draw lines on regions - Java java.lang

Java examples for java.lang:Math Geometry Line

Description

draw lines on regions

Demo Code


import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Point2D.Double;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
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  . ja v a 2 s  .  c  o  m
     * draw lines on regions
     * 
     * @param intersectLines
     * @param regions
     * @param l
     * @return
     * @throws Exception
     */
    public static List<Line2D> lineRegion(List<Line2D> intersectLines,
            Region p, Line2D l, double lineAngle, int height, int width)
            throws Exception {
        // System.out.print("line : " + lineCount + "\n");

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

        Set<Point2D> intersections = GeomUtil.getIntersections(
                p.getShape(), l, lineAngle, width, height);

        List<Point2D> intersectionArray = new ArrayList<Point2D>();
        for (Iterator<Point2D> it = intersections.iterator(); it.hasNext();) {
            Point2D rotatedPt = rotate.transform(it.next(), null);
            intersectionArray.add(rotatedPt);
        }

        // sort vertically
        for (int i = 0; i < intersectionArray.size() - 1; i++) {
            for (int j = intersectionArray.size() - 1; j > 0; j--) {
                if (intersectionArray.get(j).getY() < intersectionArray
                        .get(j - 1).getY()) {
                    Point2D temPt = intersectionArray.get(j);
                    intersectionArray.set(j, intersectionArray.get(j - 1));
                    intersectionArray.set(j - 1, temPt);
                }
            }
        }

        for (int i = 0; i < intersectionArray.size(); i++) {
            Point2D rotatedPt = rotateInverse.transform(
                    intersectionArray.get(i), null);
            intersectionArray.set(i, rotatedPt);
        }

        // System.out.println("Intersection: " +
        // intersections.size());
        Point2D start = new Point2D.Double(), end = new Point2D.Double();
        boolean draw = false, hasStart = false, hasEnd = false;
        for (Iterator<Point2D> it = intersectionArray.iterator(); it
                .hasNext();) {
            Point2D point = it.next();
            if (!hasStart) {
                start = point;
                hasStart = true;
            }

            else if (hasStart && !hasEnd) {
                end = point;
                hasEnd = true;
            }

            if (hasStart && hasEnd) {
                draw = true;
                hasStart = false;
                hasEnd = false;
            }

            // boolean addLine = false;
            if (draw) {
                intersectLines = GeomUtil.extendLine(intersectLines, start,
                        end);
                // intersectLines.add(new Line2D.Double(start,end));
                draw = false;
            }
        }

        return intersectLines;
    }
    /**
     * 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;

    }
    /**
     * Extend and merge intersecting lines
     * 
     * @param intersectLines
     * @param start
     * @param end
     * @return
     */
    public static List<Line2D> extendLine(List<Line2D> intersectLines,
            Point2D start, Point2D end) {
        boolean addLine = false;
        for (Line2D il : intersectLines) {
            if (!il.intersectsLine(new Line2D.Double(start, end))) {
                addLine = true;
            }
            if (start.getY() <= il.getY1() && end.getY() >= il.getY1()
                    && end.getY() <= il.getY2()) {
                il.setLine(start, il.getP2());
                addLine = false;
                mergeLine(intersectLines);
                break;
            }

            else if (start.getY() >= il.getY1()
                    && start.getY() <= il.getY2()
                    && end.getY() >= il.getY2()) {
                il.setLine(il.getP1(), end);
                addLine = false;
                mergeLine(intersectLines);
                break;
            }

            else if (il.getY1() >= start.getY() && il.getY2() <= end.getY()) {
                il.setLine(start, end);
                addLine = false;
                mergeLine(intersectLines);
                break;
            }

            else if (!(il.getY2() < start.getY() || il.getY1() > end.getY())) {
                addLine = false;
            }

        }

        if (intersectLines.isEmpty() || addLine) {
            intersectLines.add(new Line2D.Double(start, end));
            mergeLine(intersectLines);
            // System.out.print(addLine+"\n");
        }

        return intersectLines;
    }
    /**
     * Merge overlapping lines
     * 
     * @param intersectLines
     * @return
     */
    public static List<Line2D> mergeLine(List<Line2D> intersectLines) {
        boolean merged = false;
        for (int i = 0; i < intersectLines.size();) {
            for (int j = i + 1; j < intersectLines.size(); j++) {
                Line2D l1 = intersectLines.get(i);
                Line2D l2 = intersectLines.get(j);
                if (l1.getY1() <= l2.getY1() && l1.getY2() >= l2.getY1()
                        && l1.getY2() <= l2.getY2()) {
                    l2.setLine(l1.getP1(), l2.getP2());
                    intersectLines.remove(i);
                    // System.out.print("remove : " + i + "\n");
                    merged = true;
                    break;
                }

                else if (l1.getY1() >= l2.getY1()
                        && l1.getY1() <= l2.getY2()
                        && l1.getY2() >= l2.getY2()) {
                    l2.setLine(l2.getP1(), l1.getP2());
                    intersectLines.remove(i);
                    // System.out.print("remove : " + i + "\n");
                    merged = true;
                    break;
                }

                else if (l2.getY1() >= l1.getY1()
                        && l2.getY2() <= l1.getY2()) {
                    l2.setLine(l1);
                    // mergeLine(intersectLines);
                    intersectLines.remove(i);
                    // System.out.print("remove : " + i + "\n");
                    merged = true;
                    break;
                }

                else if (l1.getY1() >= l2.getY1()
                        && l1.getY2() <= l2.getY2()) {
                    intersectLines.remove(i);
                    merged = true;
                    break;
                }
            }
            if (merged == true) {
                i = 0;
                merged = false;
            } else
                i++;
        }

        return intersectLines;
    }
}

Related Tutorials