diff --git a/croppa/main.py b/croppa/main.py index ebb44d5..4ad687c 100644 --- a/croppa/main.py +++ b/croppa/main.py @@ -1562,15 +1562,10 @@ class VideoEditor: crop_y <= orig_y < crop_y + crop_h) print(f"draw_tracking_points: point {i} is {'inside' if is_in_crop else 'outside'} crop area") - # Get the display coordinates - either from stored value or transform now - if tracking_point.display: - # Use stored display coordinates - display_point = tracking_point.display - print(f"draw_tracking_points: using stored display coordinates {display_point}") - else: - # Transform point from original frame coordinates to display coordinates - display_point = self.transform_point(tracking_point.original) - print(f"draw_tracking_points: transformed to display coordinates {display_point}") + # Always transform point from original frame coordinates to display coordinates + # This ensures the point is always drawn correctly regardless of current crop/rotation state + display_point = self.transform_point(tracking_point.original) + print(f"draw_tracking_points: transformed to display coordinates {display_point}") if display_point is not None: # Scale and offset the point to match the canvas @@ -2220,17 +2215,26 @@ class VideoEditor: if removed: print(f"mouse_callback: removed tracking point at {original_point}") else: - # Add a new tracking point with both original and display coordinates - # This is the key change - we store both coordinate systems + # Add a new tracking point - only store the original coordinates + # Display coordinates will be calculated fresh each time to ensure accuracy self.motion_tracker.add_tracking_point( self.current_frame, original_point[0], - original_point[1], - display_coords=(display_x, display_y) # Store the display coordinates directly + original_point[1] + # No display coordinates - we'll calculate them fresh each time ) - print(f"mouse_callback: added tracking point at {original_point} (display: {display_x}, {display_y})") + print(f"mouse_callback: added tracking point at {original_point}") - # No need for verification - we're storing both coordinate systems directly + # Verify the coordinates are correct by doing a round-trip transformation + verification_display = self.transform_point(original_point) + if verification_display: + expected_x = int(start_x + verification_display[0] * scale) + expected_y = int(start_y + verification_display[1] * scale) + print(f"mouse_callback: verification - expected canvas position: ({expected_x}, {expected_y}), actual: ({x}, {y})") + + error_x = abs(expected_x - x) + error_y = abs(expected_y - y) + print(f"mouse_callback: verification - position error: ({error_x}, {error_y}) pixels") # Save state when tracking points change self.save_state() diff --git a/croppa/tracking.py b/croppa/tracking.py index 39987b5..f119a14 100644 --- a/croppa/tracking.py +++ b/croppa/tracking.py @@ -21,20 +21,19 @@ class MotionTracker: self.base_crop_rect = None # Original crop rect when tracking started self.base_zoom_center = None # Original zoom center when tracking started - def add_tracking_point(self, frame_number: int, x: float, y: float, display_coords: Optional[Tuple[float, float]] = None): + def add_tracking_point(self, frame_number: int, x: float, y: float): """Add a tracking point at the specified frame and coordinates Args: frame_number: The frame number to add the point to x: Original x coordinate y: Original y coordinate - display_coords: Optional display coordinates after transformation """ if frame_number not in self.tracking_points: self.tracking_points[frame_number] = [] - # Store both original and display coordinates - point = TrackingPoint(original=(float(x), float(y)), display=display_coords) + # Store only the original coordinates - display coordinates will be calculated fresh each time + point = TrackingPoint(original=(float(x), float(y))) print(f"Adding tracking point: {point}") self.tracking_points[frame_number].append(point)