Place pins arbitrarily (not just image corners)
This commit is contained in:
parent
12349dfd55
commit
348a96b12c
2 changed files with 31 additions and 21 deletions
|
@ -29,7 +29,7 @@ def on_key_press(symbol, modifiers):
|
|||
exit()
|
||||
|
||||
|
||||
pins = PygletCornerPin(window)
|
||||
pins = PygletCornerPin(window, source_points=[[100,100], [700,100], [100,500], [300,300]])
|
||||
# event handlers for dragging:
|
||||
window.push_handlers(pins)
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ incidently so won't really hurt performance.
|
|||
import pyglet
|
||||
from typing import Optional
|
||||
import logging
|
||||
import copy
|
||||
|
||||
def adj(m): # Compute the adjugate of m
|
||||
return [
|
||||
|
@ -63,8 +64,17 @@ def general2DProjection(
|
|||
d = basisToPoints(x1d, y1d, x2d, y2d, x3d, y3d, x4d, y4d)
|
||||
return multmm(d, adj(s))
|
||||
|
||||
def transform2d(w, h, x1, y1, x2, y2, x3, y3, x4, y4):
|
||||
t = general2DProjection(0, 0, x1, y1, w, 0, x2, y2, 0, h, x3, y3, w, h, x4, y4)
|
||||
def transform2d_wh(w, h, x1d, y1d, x2d, y2d, x3d, y3d, x4d, y4d):
|
||||
"""
|
||||
Transform the image corners based on width and height of the image
|
||||
"""
|
||||
return transform2d(0, 0, x1d, y1d, w, 0, x2d, y2d, 0, h, x3d, y3d, w, h, x4d, y4d)
|
||||
|
||||
def transform2d(x1s, y1s, x2s, y2s, x3s, y3s, x4s, y4s, x1d, y1d, x2d, y2d, x3d, y3d, x4d, y4d):
|
||||
"""
|
||||
Transform the image based on 4 arbitrarily placed pins
|
||||
"""
|
||||
t = general2DProjection(x1s, y1s, x1d, y1d, x2s, y2s, x2d, y2d, x3s, y3s, x3d, y3d, x4s, y4s, x4d, y4d)
|
||||
for i in range(9):
|
||||
t[i] = t[i] / t[8]
|
||||
|
||||
|
@ -77,7 +87,7 @@ def transform2d(w, h, x1, y1, x2, y2, x3, y3, x4, y4):
|
|||
# Below are all pyglet specific functions
|
||||
|
||||
class PygletCornerPin(pyglet.event.EventDispatcher):
|
||||
def __init__(self, window: pyglet.window.Window, corners: Optional[list[list[float]]] = None) -> None:
|
||||
def __init__(self, window: pyglet.window.Window, corners: Optional[list[list[float]]] = None, source_points: Optional[list[list[float]]] = None) -> None:
|
||||
"""
|
||||
Creates CornerPin utility for a given Pyglet window. If not given, corners default to the
|
||||
bottom left, bottom right, top left, top right corners of the window (i.e. no transform)
|
||||
|
@ -85,21 +95,23 @@ class PygletCornerPin(pyglet.event.EventDispatcher):
|
|||
Do not forget to register event handlers by running `window.register_handlers(pins)`.
|
||||
"""
|
||||
self.window = window
|
||||
self.corners = corners if corners else [
|
||||
self.source_points = source_points if source_points else [
|
||||
[0, 0],
|
||||
[self.window.width, 0],
|
||||
[0, self.window.height],
|
||||
[self.window.width, self.window.height],
|
||||
]
|
||||
self.pin_positions = corners if corners else copy.deepcopy(self.source_points)
|
||||
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
self.dragging: Optional[int] = None
|
||||
self.handles = [
|
||||
pyglet.shapes.Arc(c[0],c[1],20, thickness=2, color=(0,0,255,255), batch=self.batch) for c in self.corners
|
||||
pyglet.shapes.Arc(c[0],c[1],20, thickness=2, color=(0,0,255,255), batch=self.batch) for c in self.pin_positions
|
||||
]
|
||||
self.current_corner = None
|
||||
|
||||
def update_handles(self):
|
||||
for i, c in enumerate(self.corners):
|
||||
for i, c in enumerate(self.pin_positions):
|
||||
self.handles[i].x = c[0]
|
||||
self.handles[i].y = c[1]
|
||||
|
||||
|
@ -109,14 +121,12 @@ class PygletCornerPin(pyglet.event.EventDispatcher):
|
|||
"""
|
||||
self.batch.draw()
|
||||
|
||||
def transform2d_matrix(self, x1, y1, x2, y2, x3, y3, x4, y4):
|
||||
def transform2d_matrix(self,x1s, y1s, x2s, y2s, x3s, y3s, x4s, y4s, x1d, y1d, x2d, y2d, x3d, y3d, x4d, y4d):
|
||||
"""
|
||||
Calculate the transform matrix
|
||||
"""
|
||||
t = transform2d(
|
||||
self.window.width,
|
||||
self.window.height,
|
||||
x1, y1, x2, y2, x3, y3, x4, y4 )
|
||||
x1s, y1s, x2s, y2s, x3s, y3s, x4s, y4s, x1d, y1d, x2d, y2d, x3d, y3d, x4d, y4d)
|
||||
return pyglet.math.Mat4(t)
|
||||
|
||||
# event handlers
|
||||
|
@ -126,8 +136,8 @@ class PygletCornerPin(pyglet.event.EventDispatcher):
|
|||
currentcorner = None
|
||||
dist = r * r
|
||||
for i in range(4):
|
||||
dx = x - self.corners[i][0]
|
||||
dy = y - self.corners[i][1]
|
||||
dx = x - self.pin_positions[i][0]
|
||||
dy = y - self.pin_positions[i][1]
|
||||
if dist > dx**2 + dy ** 2:
|
||||
dist = dx**2 + dy ** 2
|
||||
currentcorner = i
|
||||
|
@ -139,15 +149,15 @@ class PygletCornerPin(pyglet.event.EventDispatcher):
|
|||
if self.dragging is None:
|
||||
return pyglet.event.EVENT_UNHANDLED
|
||||
self.dragging = None
|
||||
logging.debug(f"Corner pins set to {self.corners}")
|
||||
logging.debug(f"Corner pins set to {self.pin_positions}")
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
if self.dragging is None:
|
||||
return pyglet.event.EVENT_UNHANDLED
|
||||
|
||||
self.corners[self.dragging][0] = x
|
||||
self.corners[self.dragging][1] = y
|
||||
self.pin_positions[self.dragging][0] = x
|
||||
self.pin_positions[self.dragging][1] = y
|
||||
self.update_view()
|
||||
|
||||
def on_key_release(self, symbol: int, modifiers: int):
|
||||
|
@ -186,15 +196,15 @@ class PygletCornerPin(pyglet.event.EventDispatcher):
|
|||
base *= 2
|
||||
|
||||
if symbol == pyglet.window.key.RIGHT:
|
||||
self.corners[self.current_corner][0] += base
|
||||
self.pin_positions[self.current_corner][0] += base
|
||||
if symbol == pyglet.window.key.LEFT:
|
||||
self.corners[self.current_corner][0] -= base
|
||||
self.pin_positions[self.current_corner][0] -= base
|
||||
if symbol == pyglet.window.key.UP:
|
||||
self.corners[self.current_corner][1] += base
|
||||
self.pin_positions[self.current_corner][1] += base
|
||||
if symbol == pyglet.window.key.DOWN:
|
||||
self.corners[self.current_corner][1] -= base
|
||||
self.pin_positions[self.current_corner][1] -= base
|
||||
|
||||
self.update_view()
|
||||
|
||||
def update_view(self):
|
||||
self.window.view = self.transform2d_matrix(*[x for c in self.corners for x in c])
|
||||
self.window.view = self.transform2d_matrix(*[x for c in self.source_points for x in c], *[x for c in self.pin_positions for x in c])
|
||||
|
|
Loading…
Reference in a new issue