Implement snapping functionality for tracking points in VideoEditor

This commit enhances the VideoEditor class by adding a snapping feature that allows users to snap new tracking points to existing points from any frame within a 50px radius. The logic first checks for the removal of existing points before determining if a new point should be added or if it should snap to a nearby point. The specification has been updated to reflect this new snapping behavior, improving the precision of motion tracking.
This commit is contained in:
2025-09-17 15:05:12 +02:00
parent 8c45b30bca
commit 84a0748f0b
2 changed files with 23 additions and 2 deletions

View File

@@ -2227,6 +2227,8 @@ class VideoEditor:
rx, ry = self._map_screen_to_rotated(x, y) rx, ry = self._map_screen_to_rotated(x, y)
threshold = 50 threshold = 50
removed = False removed = False
# First check for removal of existing points on current frame
if self.current_frame in self.tracking_points: if self.current_frame in self.tracking_points:
pts_screen = [] pts_screen = []
for idx, (px, py) in enumerate(self.tracking_points[self.current_frame]): for idx, (px, py) in enumerate(self.tracking_points[self.current_frame]):
@@ -2240,9 +2242,27 @@ class VideoEditor:
# self.show_feedback_message("Tracking point removed") # self.show_feedback_message("Tracking point removed")
removed = True removed = True
break break
# If not removed, check for snapping to nearby points from other frames
if not removed: if not removed:
snapped = False
# Check all tracking points from all frames for snapping
for frame_num, points in self.tracking_points.items():
for (px, py) in points:
sxp, syp = self._map_rotated_to_screen(px, py)
if (sxp - x) ** 2 + (syp - y) ** 2 <= threshold ** 2:
# Snap to this existing point
self.tracking_points.setdefault(self.current_frame, []).append((int(px), int(py)))
snapped = True
break
if snapped:
break
# If no snapping, add new point at clicked location
if not snapped:
self.tracking_points.setdefault(self.current_frame, []).append((int(rx), int(ry))) self.tracking_points.setdefault(self.current_frame, []).append((int(rx), int(ry)))
# self.show_feedback_message("Tracking point added") # self.show_feedback_message("Tracking point added")
self.clear_transformation_cache() self.clear_transformation_cache()
self.save_state() self.save_state()

View File

@@ -58,6 +58,7 @@ Be careful to save and load settings when navigating this way
### Motion Tracking ### Motion Tracking
- **Right-click**: Add tracking point (green circle with white border) - **Right-click**: Add tracking point (green circle with white border)
- **Right-click existing point**: Remove tracking point (within 50px) - **Right-click existing point**: Remove tracking point (within 50px)
- **Right-click near existing point**: Snap to existing point from any frame (within 50px radius)
- **v**: Toggle motion tracking on/off - **v**: Toggle motion tracking on/off
- **V**: Clear all tracking points - **V**: Clear all tracking points
- **Blue cross**: Shows computed tracking position - **Blue cross**: Shows computed tracking position