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;
import org.simantics.maps.MapScalingTransform;
import org.simantics.scenegraph.utils.GeometryUtils;
+import gnu.trove.list.array.TDoubleArrayList;
+
public class DistrictNetworkNodeUtils {
public static ThreadLocal<AffineTransform> sharedTransform = new ThreadLocal<AffineTransform>() {
scale = Math.max(4096, scale); //Math.min(scale, 32768));
return scale;
}
-}
+
+ /**
+ * Finds the longest line segment from the provided <code>path</code> and sets
+ * <code>centerPoint</code> to the middle of that line and
+ * <code>direction</code> as the normalized direction vector of that line
+ * segment.
+ *
+ * <p>
+ * If the path has no points, both <code>centerPoint</code> and
+ * <code>direction</code> are set to ({@link Double#NaN}, {@link Double#NaN}).
+ * If the path has only one point then <code>centerPoint</code> is set to that
+ * single point and <code>direction</code> is set to <code>(1,0)</code>.
+ *
+ * @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