All Downloads are FREE. Search and download functionalities are using the official Maven repository.

test.GeometryClosestPointManager Maven / Gradle / Ivy

Go to download

Jeddict is an open source Jakarta EE application development platform that accelerates developers productivity and simplifies development tasks of creating complex entity relationship models.

There is a newer version: 6.6.0
Show newest version
/**
 * Copyright 2013-2022 Gaurav Gupta
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package test;

import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Line2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.util.ArrayList;

/**
 *
 *
 */
public class GeometryClosestPointManager {

    public static ClosestSegment getClosetsPoint(Shape s, Point2D.Double insidePoint) {

        ClosestSegment cs = new ClosestSegment();

        Area area = new Area();
        area.add(new Area(s));
        // Note: we're storing double[] and not Point2D.Double
        ArrayList areaPoints = new ArrayList();
        double[] coords = new double[6];

        for (PathIterator pi = area.getPathIterator(null); !pi.isDone(); pi.next()) {

            // Because the Area is composed of straight lines
            int type = pi.currentSegment(coords);
            // We record a double array of {segment type, x coord, y coord}
            double[] pathIteratorCoords = {type, coords[0], coords[1]};
            areaPoints.add(pathIteratorCoords);
        }

        double[] start = new double[3]; // To record where each polygon starts
        for (int i = 0; i < areaPoints.size(); i++) {
            // If we're not on the last point, return a line from this point to the next
            double[] currentElement = areaPoints.get(i);

            // We need a default value in case we've reached the end of the ArrayList
            double[] nextElement = {-1, -1, -1};
            if (i < areaPoints.size() - 1) {
                nextElement = areaPoints.get(i + 1);
            }

            // Make the lines
            if (currentElement[0] == PathIterator.SEG_MOVETO) {
                start = currentElement; // Record where the polygon started to close it later
            }

            if (nextElement[0] == PathIterator.SEG_LINETO) {
                cs.getAreaSegments().add(
                        new Line2D.Double(
                                currentElement[1], currentElement[2],
                                nextElement[1], nextElement[2]
                        )
                );
            } else if (nextElement[0] == PathIterator.SEG_CLOSE) {
                cs.getAreaSegments().add(
                        new Line2D.Double(
                                currentElement[1], currentElement[2],
                                start[1], start[2]
                        )
                );
            }
        }

        // Calculate the nearest point on the edge
        for (Line2D.Double line : cs.getAreaSegments()) {

            // From: http://stackoverflow.com/questions/6176227
            double u
                    = ((insidePoint.getX() - line.x1) * (line.x2 - line.x1) + (insidePoint.getY() - line.y1) * (line.y2 - line.y1))
                    / ((line.x2 - line.x1) * (line.x2 - line.x1) + (line.y2 - line.y1) * (line.y2 - line.y1));

            double xu = line.x1 + u * (line.x2 - line.x1);
            double yu = line.y1 + u * (line.y2 - line.y1);

            if (u < 0) {
                cs.getClosestPoint().setLocation(line.getP1());
            } else if (u > 1) {
                cs.getClosestPoint().setLocation(line.getP2());
            } else {
                cs.getClosestPoint().setLocation(xu, yu);
            }

            if (!Double.isNaN(cs.getClosestPoint().getX()) && !Double.isNaN(cs.getClosestPoint().getY())) {
                cs.getClosestPointList().add((Point2D.Double) cs.getClosestPoint().clone());

                if (cs.getBestPoint() == null) {
                    cs.setBestPoint(new Point2D.Double(-1, -1));
                    cs.getBestPoint().setLocation(cs.getClosestPoint());
                } else {
                    if (cs.getClosestPoint().distance(insidePoint) < cs.getBestPoint().distance(insidePoint)) {
                        cs.getBestPoint().setLocation(cs.getClosestPoint());
                    }
                }
            }

        }

        ////System.out.println("cscscs : " + cs);
        return cs;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy