clip Polyline With Polygon - Java java.lang

Java examples for java.lang:Math Geometry Line

Description

clip Polyline With Polygon

Demo Code


import java.awt.geom.*;
import java.util.*;

public class Main{
    public static Vector clipPolylineWithPolygon(double[][] polyline,
            double[][] polygon) {

        // make sure the polygon is closed
        if (polygon[0][0] != polygon[polygon.length - 1][0]
                || polygon[0][1] != polygon[polygon.length - 1][1]) {
            throw new IllegalArgumentException("polygon not closed");
        }/*from ww  w  .  j a va  2s  .  c  o  m*/

        // the polyline with additional intersection points
        Vector points = new Vector();

        // add start point of polyline
        points.add(polyline[0]);

        // get all intersection points
        for (int i = 1; i < polyline.length; ++i) {
            double[][] intersections = GeometryUtils
                    .intersectLineSegmentWithPolygon(polyline[i - 1][0],
                            polyline[i - 1][1], polyline[i][0],
                            polyline[i][1], polygon);

            // add intersection points
            if (intersections != null) {
                for (int j = 0; j < intersections.length; ++j) {
                    points.add(intersections[j]);
                }
            }

            // add end point of line segment
            points.add(polyline[i]);
        }

        // return the lines in this vector
        Vector lines = new Vector();

        // store each line in a new vector
        Vector line = new Vector();

        // counter for all points
        int ptID = 0;

        // remember whether the last point was added to the line
        boolean addedLastPoint = false;

        // loop over all lines
        while (ptID < points.size() - 1) {

            // compute the middle point for each line segment
            final double[] pt1 = (double[]) points.get(ptID);
            final double[] pt2 = (double[]) points.get(ptID + 1);
            final double x = (pt1[0] + pt2[0]) / 2.d;
            final double y = (pt1[1] + pt2[1]) / 2.d;

            // test if the middle point is inside the polygon
            // the middle point is never on the border of the polygon, so no
            // special treatement for this case is needed.
            final boolean in = GeometryUtils.pointInPolygon(new double[] {
                    x, y }, polygon);

            // the middle point is inside the polygon, so add the start point of
            // the current segment to the line
            if (in) {
                line.add(points.get(ptID));
                addedLastPoint = true;
            } // the middle point is outside the polygon. Check if the start point
              // of the current line segment has to be added anyway. This is the
              // case when this is the first line segment outside the polygon.
            else if (addedLastPoint) {
                line.add(points.get(ptID));

                // store the old line and create a new one
                if (line.size() > 1) {
                    lines.add(line);
                }
                line = new Vector();

                addedLastPoint = false;
            }
            ptID++;
        }

        // the last line segment needs special treatment
        if (addedLastPoint) {
            line.add(points.get(points.size() - 1));
        }
        if (line.size() > 1) {
            lines.add(line);
        }

        // convert the Vectors to arrays
        for (int i = 0; i < lines.size(); i++) {
            Vector l = (Vector) lines.get(i);

            // only treat lines with 2 or more points (just to be sure)
            if (l.size() < 2) {
                continue;
            }

            double[][] a = new double[l.size()][2];
            for (int j = 0; j < a.length; ++j) {
                a[j] = (double[]) l.get(j);
            }
            lines.set(i, a);
        }
        return lines;
    }
    public static double[][] intersectLineSegmentWithPolygon(double x1,
            double y1, double x2, double y2, double[][] polygon) {

        java.util.List intersectionList = new java.util.LinkedList();

        // intersect the line segment with each side of the polygon
        for (int i = 1; i < polygon.length; i++) {
            double[] intersection = GeometryUtils.intersectLineSegments(x1,
                    y1, x2, y2, polygon[i - 1][0], polygon[i - 1][1],
                    polygon[i][0], polygon[i][1]);
            if (intersection != null) {
                intersectionList.add(intersection);
            }
        }

        if (intersectionList.isEmpty()) {
            return null;
        }

        // order the intersection points by increasing distance from the start point
        java.util.Collections.sort(intersectionList, new DistComp());

        // copy the coordinates of the intersection points
        double[][] intersections = new double[intersectionList.size()][2];
        for (int i = 0; i < intersections.length; ++i) {
            final double[] inter = (double[]) intersectionList.get(i);
            intersections[i][0] = inter[0];
            intersections[i][1] = inter[1];
        }
        return intersections;
    }
    public static boolean pointInPolygon(double[] point, double[][] polygon) {
        int i, j;
        boolean c = false;
        for (i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
            if ((((polygon[i][1] <= point[1]) && (point[1] < polygon[j][1])) || ((polygon[j][1] <= point[1]) && (point[1] < polygon[i][1])))
                    && (point[0] < (polygon[j][0] - polygon[i][0])
                            * (point[1] - polygon[i][1])
                            / (polygon[j][1] - polygon[i][1])
                            + polygon[i][0])) {
                c = !c;
            }
        }
        return c;
    }
    public static boolean pointInPolygon(double x, double y,
            double[][] polygon) {
        int i, j;
        boolean c = false;
        for (i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
            if ((((polygon[i][1] <= y) && (y < polygon[j][1])) || ((polygon[j][1] <= y) && (y < polygon[i][1])))
                    && (x < (polygon[j][0] - polygon[i][0])
                            * (y - polygon[i][1])
                            / (polygon[j][1] - polygon[i][1])
                            + polygon[i][0])) {
                c = !c;
            }
        }
        return c;
    }
    public static double[] intersectLineSegments(double x1, double y1,
            double x2, double y2, double x3, double y3, double x4, double y4) {

        final double denominator = (y4 - y3) * (x2 - x1) - (x4 - x3)
                * (y2 - y1);
        if (denominator == 0.d) {
            return null; // lines are parallel
        }

        final double ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3))
                / denominator;
        if (ua <= 0.d || ua >= 1.d) {
            return null; // no intersection
        }

        final double ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3))
                / denominator;
        if (ub <= 0.d || ub >= 1.d) {
            return null; // no intersection
        }

        return new double[] { x1 + ua * (x2 - x1), y1 + ua * (y2 - y1), ua };
    }
}

Related Tutorials