From c7ecea2acf6b5409aa08e66b80e6eee1bf9fe386 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Mon, 28 Oct 2024 13:53:30 +0100 Subject: [PATCH] Use an iterative version of Dougle Reumer for freeform selection. --- .../mastodon/ui/util/RamerDouglasPeucker.java | 19 +++++++++++++++++++ .../display/FreeformSelectionBehaviour.java | 5 +++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/mastodon/ui/util/RamerDouglasPeucker.java b/src/main/java/org/mastodon/ui/util/RamerDouglasPeucker.java index fa8d0b31e..01d29f295 100644 --- a/src/main/java/org/mastodon/ui/util/RamerDouglasPeucker.java +++ b/src/main/java/org/mastodon/ui/util/RamerDouglasPeucker.java @@ -14,6 +14,25 @@ public static void simplifyPath( final List< Point > points, final double epsilo simplifySection( points, 0, points.size() - 1, epsilon ); } + /** + * Determines if a point should be added to the specified polygon, based on + * the Ramer-Douglas-Peucker criterion (perpendicular distance from the last + * segment). + */ + public static boolean shouldAddPoint( final List< Point > points, final Point newPoint, final double epsilon ) + { + if ( points.size() < 2 ) + return true; + + // Get the last two points + final Point lastPoint = points.get( points.size() - 1 ); + final Point secondLastPoint = points.get( points.size() - 2 ); + + final double distance = perpendicularDistance( newPoint, secondLastPoint, lastPoint ); + + return distance > epsilon; + } + private static void simplifySection( final List< Point > points, final int start, final int end, final double epsilon ) { if ( end <= start + 1 ) diff --git a/src/main/java/org/mastodon/views/grapher/display/FreeformSelectionBehaviour.java b/src/main/java/org/mastodon/views/grapher/display/FreeformSelectionBehaviour.java index 6c502eb85..63a1b2c8b 100644 --- a/src/main/java/org/mastodon/views/grapher/display/FreeformSelectionBehaviour.java +++ b/src/main/java/org/mastodon/views/grapher/display/FreeformSelectionBehaviour.java @@ -125,8 +125,9 @@ public void drag( final int x, final int y ) { if ( isDrawing ) { - polygon.add( new Point( x, y ) ); - RamerDouglasPeucker.simplifyPath( polygon, 0.1 ); + final Point p = new Point( x, y ); + if ( RamerDouglasPeucker.shouldAddPoint( polygon, p, 0.1 ) ) + polygon.add( p ); panel.repaint(); } }