Java examples for java.lang:Math Geometry Line
draw lines on regions
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; } }