Get intersecting part of a line and an area - Java java.lang

Java examples for java.lang:Math Geometry Line

Description

Get intersecting part of a line and an area

Demo Code


//package com.java2s;

import java.awt.geom.AffineTransform;
import java.awt.geom.Area;

import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;

import java.util.HashSet;

import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class Main {
    private static double MAX_DIST = 1E-2;

    /**/*from   w  w w . j  a v  a 2s.c om*/
     * Get intersecting part of a line and an area
     * 
     * @param path
     * @param line
     * @return a set of point as intersections
     * @throws Exception
     */
    public static Set<Point2D> getIntersections(Path2D path, Line2D line,
            double lineAngle, int width, int height) throws Exception {
        // List to hold found intersections

        Set<Point2D> intersections = new HashSet<Point2D>();

        AffineTransform rotate = new AffineTransform();
        rotate.rotate(lineAngle, width / 2, height / 2);
        AffineTransform rotateInverse = new AffineTransform();
        rotateInverse.rotate(-lineAngle, width / 2, height / 2);

        Point2D rtPt1 = rotate.transform(line.getP1(), null);
        Point2D rtPt2 = rotate.transform(line.getP2(), null);
        Point2D boldPt1 = rotateInverse.transform(
                new Point2D.Double(rtPt1.getX() - 1, rtPt1.getY()), null);
        Point2D boldPt2 = rotateInverse.transform(
                new Point2D.Double(rtPt2.getX() - 1, rtPt2.getY()), null);
        Point2D boldPt3 = rotateInverse.transform(
                new Point2D.Double(rtPt2.getX() + 1, rtPt2.getY()), null);
        Point2D boldPt4 = rotateInverse.transform(
                new Point2D.Double(rtPt1.getX() + 1, rtPt1.getY()), null);

        Path2D boldLine = new Path2D.Double();

        boldLine.moveTo(boldPt1.getX(), boldPt1.getY());
        boldLine.lineTo(boldPt2.getX(), boldPt2.getY());
        boldLine.lineTo(boldPt3.getX(), boldPt3.getY());
        boldLine.lineTo(boldPt4.getX(), boldPt4.getY());
        boldLine.closePath();

        Line2D auxLine = new Line2D.Double(boldPt1, boldPt2);

        Area pathArea = new Area(path);
        Area lineArea = new Area(boldLine);

        if (lineArea.isEmpty()) {
            System.out.println("line is empty");
        }

        pathArea.intersect(lineArea);

        if (pathArea.isEmpty()) {
            return intersections;
        }

        PathIterator lineIt = pathArea.getPathIterator(null);

        // Double array with length 6 needed by iterator
        double[] coords = new double[6];

        int type;
        List<Point2D> intersectionsTemp = new LinkedList<Point2D>();
        while (!lineIt.isDone()) {
            double dist;
            type = lineIt.currentSegment(coords);
            switch (type) {
            case PathIterator.SEG_LINETO: {
                Point2D intersectPt = new Point2D.Double(coords[0],
                        coords[1]);
                // System.out.println("type: LINETO "+ intersectPt.toString());
                dist = auxLine.ptLineDistSq(intersectPt);
                // System.out.println(" dist: " + dist);
                // System.out.println("\n not ADD POINT "+
                // intersectPt.toString() + " dist: " + dist + "\n");
                if (dist <= MAX_DIST) {

                    boolean inList = false;
                    for (Point2D pt : intersections) {
                        if ((pt.getX() - coords[0])
                                * (pt.getX() - coords[0])
                                + (pt.getY() - coords[1])
                                * (pt.getY() - coords[1]) <= MAX_DIST) {
                            inList = true;
                        }
                    }
                    if (!inList) {
                        intersectionsTemp.add(new Point2D.Double(coords[0],
                                coords[1]));
                        // System.out.println("\nADD POINT "+
                        // intersectPt.toString() + " dist: " + dist + "\n");
                    }
                }
                break;
            }

            case PathIterator.SEG_MOVETO: {
                if (intersectionsTemp.size() == 2) {
                    intersections.addAll(intersectionsTemp);
                } else if (intersectionsTemp.size() > 2) {
                    for (int m = 0; m < intersectionsTemp.size() - 1; m++) {
                        for (int n = intersectionsTemp.size() - 1; n > 0; n--) {
                            if (intersectionsTemp.get(n).getY() < intersectionsTemp
                                    .get(n - 1).getY()) {
                                Point2D temPt = intersectionsTemp.get(n);
                                intersectionsTemp.set(n,
                                        intersectionsTemp.get(n - 1));
                                intersectionsTemp.set(n - 1, temPt);
                            }
                        }
                    }
                    intersections.add(intersectionsTemp.get(0));
                    intersections.add(intersectionsTemp
                            .get(intersectionsTemp.size() - 1));

                }

                intersectionsTemp.clear();

                Point2D intersectPt = new Point2D.Double(coords[0],
                        coords[1]);
                // System.out.println("type: MOVETO "+ intersectPt.toString());
                dist = auxLine.ptLineDistSq(intersectPt);
                // System.out.println(" dist: " + dist);
                if (dist <= MAX_DIST) {
                    boolean inList = false;
                    for (Point2D pt : intersections) {
                        if ((pt.getX() - coords[0])
                                * (pt.getX() - coords[0])
                                + (pt.getY() - coords[1])
                                * (pt.getY() - coords[1]) <= MAX_DIST) {
                            inList = true;
                        }
                    }
                    if (!inList) {
                        intersectionsTemp.add(new Point2D.Double(coords[0],
                                coords[1]));
                        // System.out.println("\nADD POINT "+
                        // intersectPt.toString() + " dist: " + dist + "\n");

                    }
                }
                break;
            }

            case PathIterator.SEG_CUBICTO: {

                Point2D intersectPt = new Point2D.Double(coords[0],
                        coords[1]);
                // System.out.println("type: CUBICTO "+ intersectPt.toString());
                dist = auxLine.ptLineDistSq(intersectPt);
                // System.out.println(" dist: " + dist);
                if (dist <= MAX_DIST) {
                    boolean inList = false;
                    for (Point2D pt : intersections) {
                        if ((pt.getX() - coords[0])
                                * (pt.getX() - coords[0])
                                + (pt.getY() - coords[1])
                                * (pt.getY() - coords[1]) <= MAX_DIST) {
                            inList = true;
                        }
                    }
                    if (!inList) {
                        intersectionsTemp.add(new Point2D.Double(coords[0],
                                coords[1]));
                        // System.out.println("\nADD POINT "+
                        // intersectPt.toString() + " dist: " + dist + "\n");
                    }
                }
                break;
            }

            case PathIterator.SEG_CLOSE: {
                if (intersectionsTemp.size() == 2) {
                    intersections.addAll(intersectionsTemp);
                } else if (intersectionsTemp.size() > 2) {
                    for (int m = 0; m < intersectionsTemp.size() - 1; m++) {
                        for (int n = intersectionsTemp.size() - 1; n > 0; n--) {
                            if (intersectionsTemp.get(n).getY() < intersectionsTemp
                                    .get(n - 1).getY()) {
                                Point2D temPt = intersectionsTemp.get(n);
                                intersectionsTemp.set(n,
                                        intersectionsTemp.get(n - 1));
                                intersectionsTemp.set(n - 1, temPt);
                            }
                        }
                    }
                    intersections.add(intersectionsTemp.get(0));
                    intersections.add(intersectionsTemp
                            .get(intersectionsTemp.size() - 1));

                }

                intersectionsTemp.clear();

                // System.out.println("type: CLOSE "+ intersectPt.toString());
                break;
            }
            default: {
                throw new Exception(
                        "Unsupported PathIterator segment type: " + type);
            }
            }
            lineIt.next();
        }

        if (intersections.size() % 2 != 0)
            System.out.println("odd number of intersection points");

        return intersections;

    }
}

Related Tutorials