X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.district.network.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fnetwork%2Fui%2Fnodes%2FDistrictNetworkNodeUtils.java;h=2cc0ee96ae4ffa89ad97b696c3661944f13146bc;hb=386525ce8e466427df0624a304ebb64df249d1bb;hp=c9e4a00e19b3be532b23f2d4641590e953bb9524;hpb=5b90436d8860b56af851b00eddfb2dcb7ba88dd5;p=simantics%2Fdistrict.git diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkNodeUtils.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkNodeUtils.java index c9e4a00e..2cc0ee96 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkNodeUtils.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkNodeUtils.java @@ -1,6 +1,8 @@ package org.simantics.district.network.ui.nodes; import java.awt.geom.AffineTransform; +import java.awt.geom.Path2D; +import java.awt.geom.PathIterator; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; @@ -8,8 +10,16 @@ import org.simantics.district.network.ModelledCRS; import org.simantics.maps.MapScalingTransform; import org.simantics.scenegraph.utils.GeometryUtils; +import gnu.trove.list.array.TDoubleArrayList; + public class DistrictNetworkNodeUtils { + public static ThreadLocal sharedTransform = new ThreadLocal() { + protected AffineTransform initialValue() { + return new AffineTransform(); + } + }; + public static Rectangle2D calculateDrawnGeometry(Point2D p, Rectangle2D margin, Rectangle2D result, double scaleRecip) { if (result == null) result = new Rectangle2D.Double(); @@ -39,20 +49,78 @@ public class DistrictNetworkNodeUtils { public static double calculateScaleRecip(AffineTransform tr) { int zoomLevel = MapScalingTransform.zoomLevel(tr); - double t; - if (zoomLevel > 15) { - int d = zoomLevel - 15; // stop zooming vertices when zoom level > 15 - t = 1.0 / d / (getScale(tr) * Math.sqrt(zoomLevel)); - } else { - t = 1.0 / (getScale(tr) * Math.sqrt(zoomLevel)); - } - return t; + return 1.0 / (getScale(tr) * Math.sqrt(zoomLevel)); } static double getScale(AffineTransform tr) { double scale; scale = GeometryUtils.getScale(tr); - scale = Math.max(4096, Math.min(scale, 32768)); + scale = Math.max(4096, scale); //Math.min(scale, 32768)); return scale; } -} + + /** + * Finds the longest line segment from the provided path and sets + * centerPoint to the middle of that line and + * direction as the normalized direction vector of that line + * segment. + * + *

+ * If the path has no points, both centerPoint and + * direction are set to ({@link Double#NaN}, {@link Double#NaN}). + * If the path has only one point then centerPoint is set to that + * single point and direction is set to (1,0). + * + * @param path the path to process + * @param centerPoint point for writing the output center point + * @param direction point for writing the output direction vector + * @return the amount of points in the path + */ + public static int calculateCenterPointAndDirection(Path2D path, Point2D centerPoint, Point2D direction) { + PathIterator pi = path.getPathIterator(null); + TDoubleArrayList segments = new TDoubleArrayList(20); + double[] tmp = new double[6]; + while (!pi.isDone()) { + pi.currentSegment(tmp); + segments.add(tmp[0]); + segments.add(tmp[1]); + pi.next(); + } + + // Cover corner cases + int segCount = segments.size(); + if (segCount == 0) { + centerPoint.setLocation(Double.NaN, Double.NaN); + direction.setLocation(Double.NaN, Double.NaN); + return 0; + } else if (segCount == 2) { + centerPoint.setLocation(segments.getQuick(0), segments.getQuick(1)); + direction.setLocation(1, 0); + return 1; + } + + int longest = 1; + double distance = 0.0; + for (int i = 2; i < segCount; i += 2) { + double dx = segments.getQuick(i) - segments.getQuick(i-2); + double dy = segments.getQuick(i+1) - segments.getQuick(i-1); + + double d = dx * dx + dy * dy; + if (d > distance) { + distance = d; + longest = i; + } + } + + double x0 = segments.getQuick(longest - 2); + double y0 = segments.getQuick(longest - 1); + double x1 = segments.getQuick(longest); + double y1 = segments.getQuick(longest + 1); + + distance = Math.sqrt(distance); + centerPoint.setLocation((x0 + x1) / 2, (y0 + y1) / 2); + direction.setLocation((x1 - x0) / distance, (y1 - y0) / distance); + return segCount / 2; + } + +} \ No newline at end of file