Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>So, since I was unable to find anything like this on the web, I written my own algorithm.</p> <p>It may be insanely ineffective, but it works fast enough for me.</p> <p>Here it goes:</p> <pre><code>/** * Takes a polygon, defined by a list of lines, and splits it into several * paths on points of intersection. If non-self-intersected path is passed in, * the same path is returned. * @param path * @return */ public static List&lt;List&lt;Line2D&gt;&gt; splitPath(List&lt;Line2D&gt; lines) { List&lt;List&lt;Line2D&gt;&gt; splitted = new ArrayList&lt;List&lt;Line2D&gt;&gt;(); // find intersections. loop1: for (Line2D l1 : lines) { for (Line2D l2 : lines) { if (l1 == l2) continue; Point2D intr; if ((intr = linesIntersect(l1, l2)) != null) { // creating two splitted subpaths int i1 = lines.indexOf(l1); int i2 = lines.indexOf(l2); List&lt;Line2D&gt; subpath1 = new ArrayList&lt;Line2D&gt;(); subpath1.addAll(lines.subList(0, i1)); subpath1.add(new Line2D.Double(l1.getP1(), intr)); subpath1.add(new Line2D.Double(intr, l2.getP2())); subpath1.addAll(lines.subList(i2 + 1, lines.size())); splitted.addAll(splitPath(subpath1)); List&lt;Line2D&gt; subpath2 = new ArrayList&lt;Line2D&gt;(); subpath2.add(new Line2D.Double(intr, l1.getP2())); subpath2.addAll(lines.subList(i1 + 1, i2)); subpath2.add(new Line2D.Double(l2.getP1(), intr)); splitted.addAll(splitPath(subpath2)); break loop1; } } } if (splitted.size() &gt; 0) { return splitted; } else { return Collections.singletonList(lines); } } /** * Returns point of intersection of this line segments. * @param l1 * @param l2 * @return */ public static Point2D linesIntersect(Line2D l1, Line2D l2) { if (l1.getP1().equals(l2.getP2()) || l1.getP2().equals(l2.getP1())) return null; Point2D inter = lineIntersection(l1, l2); if (inter == null) return null; double infS = HEADER.infS; double x = inter.getX(); if (((l1.getX1() &gt; l1.getX2()) ? (x + infS &gt; l1.getX2() &amp;&amp; x - infS &lt; l1.getX1()) : (x - infS &lt; l1.getX2() &amp;&amp; x + infS &gt; l1.getX1())) &amp;&amp; ((l2.getX1() &gt; l2.getX2()) ? (x + infS &gt; l2.getX2() &amp;&amp; x - infS &lt; l2.getX1()) : (x - infS &lt; l2.getX2() &amp;&amp; x + infS &gt; l2.getX1()))) { return inter; } else { return null; } } /** * Returns point of lines intersection, or null if they are parallel. * @param l1 * @param l2 * @return */ public static Point2D lineIntersection(Line2D l1, Line2D l2) { double a1 = l1.getY2() - l1.getY1(); double b1 = l1.getX1() - l1.getX2(); double c1 = a1*l1.getX1() + b1*l1.getY1(); double a2 = l2.getY2() - l2.getY1(); double b2 = l2.getX1() - l2.getX2(); double c2 = a2*l2.getX1() + b2*l2.getY1(); double det = a1*b2 - a2*b1; if (det != 0) { double x = (b2*c1 - b1*c2)/det; double y = (a1*c2 - a2*c1)/det; return new Point2D.Double(x, y); } else { // lines are parallel return null; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload