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()
|
exit()
|
||||||
|
|
||||||
|
|
||||||
pins = PygletCornerPin(window)
|
pins = PygletCornerPin(window, source_points=[[100,100], [700,100], [100,500], [300,300]])
|
||||||
# event handlers for dragging:
|
# event handlers for dragging:
|
||||||
window.push_handlers(pins)
|
window.push_handlers(pins)
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ incidently so won't really hurt performance.
|
||||||
import pyglet
|
import pyglet
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
import logging
|
import logging
|
||||||
|
import copy
|
||||||
|
|
||||||
def adj(m): # Compute the adjugate of m
|
def adj(m): # Compute the adjugate of m
|
||||||
return [
|
return [
|
||||||
|
@ -63,8 +64,17 @@ def general2DProjection(
|
||||||
d = basisToPoints(x1d, y1d, x2d, y2d, x3d, y3d, x4d, y4d)
|
d = basisToPoints(x1d, y1d, x2d, y2d, x3d, y3d, x4d, y4d)
|
||||||
return multmm(d, adj(s))
|
return multmm(d, adj(s))
|
||||||
|
|
||||||
def transform2d(w, h, x1, y1, x2, y2, x3, y3, x4, y4):
|
def transform2d_wh(w, h, x1d, y1d, x2d, y2d, x3d, y3d, x4d, y4d):
|
||||||
t = general2DProjection(0, 0, x1, y1, w, 0, x2, y2, 0, h, x3, y3, w, h, x4, y4)
|
"""
|
||||||
|
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):
|
for i in range(9):
|
||||||
t[i] = t[i] / t[8]
|
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
|
# Below are all pyglet specific functions
|
||||||
|
|
||||||
class PygletCornerPin(pyglet.event.EventDispatcher):
|
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
|
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)
|
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)`.
|
Do not forget to register event handlers by running `window.register_handlers(pins)`.
|
||||||
"""
|
"""
|
||||||
self.window = window
|
self.window = window
|
||||||
self.corners = corners if corners else [
|
self.source_points = source_points if source_points else [
|
||||||
[0, 0],
|
[0, 0],
|
||||||
[self.window.width, 0],
|
[self.window.width, 0],
|
||||||
[0, self.window.height],
|
[0, self.window.height],
|
||||||
[self.window.width, 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.batch = pyglet.graphics.Batch()
|
||||||
self.dragging: Optional[int] = None
|
self.dragging: Optional[int] = None
|
||||||
self.handles = [
|
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
|
self.current_corner = None
|
||||||
|
|
||||||
def update_handles(self):
|
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].x = c[0]
|
||||||
self.handles[i].y = c[1]
|
self.handles[i].y = c[1]
|
||||||
|
|
||||||
|
@ -109,14 +121,12 @@ class PygletCornerPin(pyglet.event.EventDispatcher):
|
||||||
"""
|
"""
|
||||||
self.batch.draw()
|
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
|
Calculate the transform matrix
|
||||||
"""
|
"""
|
||||||
t = transform2d(
|
t = transform2d(
|
||||||
self.window.width,
|
x1s, y1s, x2s, y2s, x3s, y3s, x4s, y4s, x1d, y1d, x2d, y2d, x3d, y3d, x4d, y4d)
|
||||||
self.window.height,
|
|
||||||
x1, y1, x2, y2, x3, y3, x4, y4 )
|
|
||||||
return pyglet.math.Mat4(t)
|
return pyglet.math.Mat4(t)
|
||||||
|
|
||||||
# event handlers
|
# event handlers
|
||||||
|
@ -126,8 +136,8 @@ class PygletCornerPin(pyglet.event.EventDispatcher):
|
||||||
currentcorner = None
|
currentcorner = None
|
||||||
dist = r * r
|
dist = r * r
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
dx = x - self.corners[i][0]
|
dx = x - self.pin_positions[i][0]
|
||||||
dy = y - self.corners[i][1]
|
dy = y - self.pin_positions[i][1]
|
||||||
if dist > dx**2 + dy ** 2:
|
if dist > dx**2 + dy ** 2:
|
||||||
dist = dx**2 + dy ** 2
|
dist = dx**2 + dy ** 2
|
||||||
currentcorner = i
|
currentcorner = i
|
||||||
|
@ -139,15 +149,15 @@ class PygletCornerPin(pyglet.event.EventDispatcher):
|
||||||
if self.dragging is None:
|
if self.dragging is None:
|
||||||
return pyglet.event.EVENT_UNHANDLED
|
return pyglet.event.EVENT_UNHANDLED
|
||||||
self.dragging = None
|
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
|
return pyglet.event.EVENT_HANDLED
|
||||||
|
|
||||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||||
if self.dragging is None:
|
if self.dragging is None:
|
||||||
return pyglet.event.EVENT_UNHANDLED
|
return pyglet.event.EVENT_UNHANDLED
|
||||||
|
|
||||||
self.corners[self.dragging][0] = x
|
self.pin_positions[self.dragging][0] = x
|
||||||
self.corners[self.dragging][1] = y
|
self.pin_positions[self.dragging][1] = y
|
||||||
self.update_view()
|
self.update_view()
|
||||||
|
|
||||||
def on_key_release(self, symbol: int, modifiers: int):
|
def on_key_release(self, symbol: int, modifiers: int):
|
||||||
|
@ -186,15 +196,15 @@ class PygletCornerPin(pyglet.event.EventDispatcher):
|
||||||
base *= 2
|
base *= 2
|
||||||
|
|
||||||
if symbol == pyglet.window.key.RIGHT:
|
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:
|
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:
|
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:
|
if symbol == pyglet.window.key.DOWN:
|
||||||
self.corners[self.current_corner][1] -= base
|
self.pin_positions[self.current_corner][1] -= base
|
||||||
|
|
||||||
self.update_view()
|
self.update_view()
|
||||||
|
|
||||||
def update_view(self):
|
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