Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/main/java/clipper2/Clipper.java
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ public static RectD GetBounds(PathD path) {
result.bottom = pt.y;
}
}
return result.left == Double.MAX_VALUE ? new RectD() : result;
return Math.abs(result.left - Double.MAX_VALUE) < InternalClipper.FLOATING_POINT_TOLERANCE ? new RectD() : result;
}

public static RectD GetBounds(PathsD paths) {
Expand All @@ -829,7 +829,7 @@ public static RectD GetBounds(PathsD paths) {
}
}
}
return result.left == Double.MAX_VALUE ? new RectD() : result;
return Math.abs(result.left - Double.MAX_VALUE) < InternalClipper.FLOATING_POINT_TOLERANCE ? new RectD() : result;
}

public static Path64 MakePath(int[] arr) {
Expand Down Expand Up @@ -1366,10 +1366,10 @@ public static Path64 TrimCollinear(Path64 path, boolean isOpen) {
int len = path.size();
int i = 0;
if (!isOpen) {
while (i < len - 1 && InternalClipper.CrossProduct(path.get(len - 1), path.get(i), path.get(i + 1)) == 0) {
while (i < len - 1 && InternalClipper.IsCollinear(path.get(len - 1), path.get(i), path.get(i + 1))) {
i++;
}
while (i < len - 1 && InternalClipper.CrossProduct(path.get(len - 2), path.get(len - 1), path.get(i)) == 0) {
while (i < len - 1 && InternalClipper.IsCollinear(path.get(len - 2), path.get(len - 1), path.get(i))) {
len--;
}
}
Expand All @@ -1385,7 +1385,7 @@ public static Path64 TrimCollinear(Path64 path, boolean isOpen) {
Point64 last = path.get(i);
result.add(last);
for (i++; i < len - 1; i++) {
if (InternalClipper.CrossProduct(last, path.get(i), path.get(i + 1)) == 0) {
if (InternalClipper.IsCollinear(last, path.get(i), path.get(i + 1))) {
continue;
}
last = path.get(i);
Expand All @@ -1394,10 +1394,10 @@ public static Path64 TrimCollinear(Path64 path, boolean isOpen) {

if (isOpen) {
result.add(path.get(len - 1));
} else if (InternalClipper.CrossProduct(last, path.get(len - 1), result.get(0)) != 0) {
} else if (!InternalClipper.IsCollinear(last, path.get(len - 1), result.get(0))) {
result.add(path.get(len - 1));
} else {
while (result.size() > 2 && InternalClipper.CrossProduct(result.get(result.size() - 1), result.get(result.size() - 2), result.get(0)) == 0) {
while (result.size() > 2 && InternalClipper.IsCollinear(result.get(result.size() - 1), result.get(result.size() - 2), result.get(0))) {
result.remove(result.size() - 1);
}
if (result.size() < 3) {
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/clipper2/core/InternalClipper.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public final class InternalClipper {
private static final long Invalid64 = Long.MAX_VALUE;

public static final double DEFAULT_ARC_TOLERANCE = 0.25;
private static final double FLOATING_POINT_TOLERANCE = 1E-12;
public static final double FLOATING_POINT_TOLERANCE = 1E-12;
// private static final double DEFAULT_MIN_EDGE_LENGTH = 0.1;

private static final String PRECISION_RANGE_ERROR = "Error: Precision is out of range.";
Expand Down Expand Up @@ -52,7 +52,7 @@ public static long CheckCastInt64(double val) {
return (long) Math.rint(val);
}

public static boolean GetIntersectPoint(Point64 ln1a, Point64 ln1b, Point64 ln2a, Point64 ln2b, /* out */ Point64 ip) {
public static boolean GetSegmentIntersectPt(Point64 ln1a, Point64 ln1b, Point64 ln2a, Point64 ln2b, /* out */ Point64 ip) {
double dy1 = (ln1b.y - ln1a.y);
double dx1 = (ln1b.x - ln1a.x);
double dy2 = (ln2b.y - ln2a.y);
Expand Down Expand Up @@ -86,6 +86,10 @@ public static boolean GetIntersectPoint(Point64 ln1a, Point64 ln1b, Point64 ln2a
return true;
}

public static boolean GetIntersectPoint(Point64 ln1a, Point64 ln1b, Point64 ln2a, Point64 ln2b, /* out */ Point64 ip) {
return GetSegmentIntersectPt(ln1a, ln1b, ln2a, ln2b, ip);
}

public static boolean SegsIntersect(Point64 seg1a, Point64 seg1b, Point64 seg2a, Point64 seg2b) {
return SegsIntersect(seg1a, seg1b, seg2a, seg2b, false);
}
Expand Down Expand Up @@ -295,4 +299,4 @@ private static int triSign(long x) {
return x > 0 ? 1 : (x < 0 ? -1 : 0);
}

}
}
5 changes: 4 additions & 1 deletion src/main/java/clipper2/core/Path64.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ public Path64(Point64... path) {
public String toString() {
StringBuilder s = new StringBuilder();
for (Point64 p : this) {
s.append(p.toString()).append(" ");
s.append(p.toString()).append(", ");
}
if (!s.isEmpty()) {
s.setLength(s.length() - 2);
}
return s.toString();
}
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/clipper2/core/PathD.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ public PathD(List<PointD> path) {
public String toString() {
StringBuilder s = new StringBuilder();
for (PointD p : this) {
s.append(p.toString()).append(" ");
s.append(p.toString()).append(", ");
}
if (!s.isEmpty()) {
s.setLength(s.length() - 2);
}
return s.toString();
}
Expand Down
44 changes: 21 additions & 23 deletions src/main/java/clipper2/engine/ClipperBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,7 @@ private static boolean IsValidAelOrder(Active resident, Active newcomer) {
if (resident.isLeftBound != newcomerIsLeft) {
return newcomerIsLeft;
}
if (InternalClipper.CrossProduct(PrevPrevVertex(resident).pt, resident.bot, resident.top) == 0) {
if (InternalClipper.IsCollinear(PrevPrevVertex(resident).pt, resident.bot, resident.top)) {
return true;
}
// compare turning direction of the alternate bound
Expand Down Expand Up @@ -1416,13 +1416,13 @@ private static Active FindEdgeWithMatchingLocMin(Active e) {
return result;
}

private OutPt IntersectEdges(Active ae1, Active ae2, Point64 pt) {
private void IntersectEdges(Active ae1, Active ae2, Point64 pt) {
OutPt resultOp = null;

// MANAGE OPEN PATH INTERSECTIONS SEPARATELY ...
if (hasOpenPaths && (IsOpen(ae1) || IsOpen(ae2))) {
if (IsOpen(ae1) && IsOpen(ae2)) {
return null;
return;
}
// the following line avoids duplicating quite a bit of code
if (IsOpen(ae2)) {
Expand All @@ -1436,26 +1436,26 @@ private OutPt IntersectEdges(Active ae1, Active ae2, Point64 pt) {

if (cliptype == ClipType.Union) {
if (!IsHotEdge(ae2)) {
return null;
return;
}
} else if (ae2.localMin.polytype == PathType.Subject) {
return null;
return;
}

switch (fillrule) {
case Positive :
if (ae2.windCount != 1) {
return null;
return;
}
break;
case Negative :
if (ae2.windCount != -1) {
return null;
return;
}
break;
default :
if (Math.abs(ae2.windCount) != 1) {
return null;
return;
}
break;
}
Expand Down Expand Up @@ -1483,15 +1483,15 @@ else if (pt.opEquals(ae1.localMin.vertex.pt) && !IsOpenEnd(ae1.localMin.vertex))
} else {
SetSides(ae3.outrec, ae3, ae1);
}
return ae3.outrec.pts;
return;
}

resultOp = StartOpenPath(ae1, pt);
} else {
resultOp = StartOpenPath(ae1, pt);
}

return resultOp;
return;
}

// MANAGING CLOSED PATHS FROM HERE ON
Expand Down Expand Up @@ -1554,7 +1554,7 @@ else if (pt.opEquals(ae1.localMin.vertex.pt) && !IsOpenEnd(ae1.localMin.vertex))
boolean e2WindCountIs0or1 = oldE2WindCount == 0 || oldE2WindCount == 1;

if ((!IsHotEdge(ae1) && !e1WindCountIs0or1) || (!IsHotEdge(ae2) && !e2WindCountIs0or1)) {
return null;
return;
}

// NOW PROCESS THE INTERSECTION ...
Expand Down Expand Up @@ -1612,7 +1612,7 @@ else if (IsHotEdge(ae1)) {
switch (cliptype) {
case Union :
if (e1Wc2 > 0 && e2Wc2 > 0) {
return null;
return;
}
resultOp = AddLocalMinPoly(ae1, ae2, pt);
break;
Expand All @@ -1631,15 +1631,13 @@ else if (IsHotEdge(ae1)) {

default : // ClipType.Intersection:
if (e1Wc2 <= 0 || e2Wc2 <= 0) {
return null;
return;
}
resultOp = AddLocalMinPoly(ae1, ae2, pt);
break;
}
}
}

return resultOp;
}

private void DeleteFromAEL(Active ae) {
Expand Down Expand Up @@ -1727,7 +1725,7 @@ private void DisposeIntersectNodes() {

private void AddNewIntersectNode(Active ae1, Active ae2, long topY) {
Point64 ip = new Point64();
if (!InternalClipper.GetIntersectPoint(ae1.bot, ae1.top, ae2.bot, ae2.top, ip)) {
if (!InternalClipper.GetSegmentIntersectPt(ae1.bot, ae1.top, ae2.bot, ae2.top, ip)) {
ip = new Point64(ae1.curX, topY);
}

Expand Down Expand Up @@ -2232,7 +2230,7 @@ private void CheckJoinLeft(Active e, Point64 pt) {
private void CheckJoinLeft(Active e, Point64 pt, boolean checkCurrX) {
@Nullable
Active prev = e.prevInAEL;
if (prev == null || IsOpen(e) || IsOpen(prev) || !IsHotEdge(e) || !IsHotEdge(prev)) {
if (prev == null || !IsHotEdge(e) || !IsHotEdge(prev) || IsHorizontal(e) || IsHorizontal(prev) || IsOpen(e) || IsOpen(prev)) {
return;
}

Expand All @@ -2249,7 +2247,7 @@ private void CheckJoinLeft(Active e, Point64 pt, boolean checkCurrX) {
} else if (e.curX != prev.curX) {
return;
}
if (InternalClipper.CrossProduct(e.top, pt, prev.top) != 0) {
if (!InternalClipper.IsCollinear(e.top, pt, prev.top)) {
return;
}

Expand All @@ -2272,7 +2270,7 @@ private void CheckJoinRight(Active e, Point64 pt) {
private void CheckJoinRight(Active e, Point64 pt, boolean checkCurrX) {
@Nullable
Active next = e.nextInAEL;
if (next == null || IsOpen(e) || IsOpen(next) || !IsHotEdge(e) || !IsHotEdge(next) || IsJoined(e)) {
if (next == null || !IsHotEdge(e) || !IsHotEdge(next) || IsHorizontal(e) || IsHorizontal(next) || IsOpen(e) || IsOpen(next)) {
return;
}

Expand All @@ -2289,7 +2287,7 @@ private void CheckJoinRight(Active e, Point64 pt, boolean checkCurrX) {
} else if (e.curX != next.curX) {
return;
}
if (InternalClipper.CrossProduct(e.top, pt, next.top) != 0) {
if (!InternalClipper.IsCollinear(e.top, pt, next.top)) {
return;
}

Expand Down Expand Up @@ -2656,7 +2654,7 @@ private void CleanCollinear(OutRec outrec) {
OutPt op2 = startOp;
for (;;) {
// NB if preserveCollinear == true, then only remove 180 deg. spikes
if ((InternalClipper.CrossProduct(op2.prev.pt, op2.pt, op2.next.pt) == 0) && ((op2.pt.opEquals(op2.prev.pt)) || (op2.pt.opEquals(op2.next.pt))
if (InternalClipper.IsCollinear(op2.prev.pt, op2.pt, op2.next.pt) && ((op2.pt.opEquals(op2.prev.pt)) || (op2.pt.opEquals(op2.next.pt))
|| !getPreserveCollinear() || (InternalClipper.DotProduct(op2.prev.pt, op2.pt, op2.next.pt) < 0))) {
if (op2.equals(outrec.pts)) {
outrec.pts = op2.prev;
Expand Down Expand Up @@ -2686,7 +2684,7 @@ private void DoSplitOp(OutRec outrec, OutPt splitOp) {
// OutPt result = prevOp;

Point64 ip = new Point64(); // ip mutated by GetIntersectPoint()
InternalClipper.GetIntersectPoint(prevOp.pt, splitOp.pt, splitOp.next.pt, nextNextOp.pt, ip);
InternalClipper.GetSegmentIntersectPt(prevOp.pt, splitOp.pt, splitOp.next.pt, nextNextOp.pt, ip);

double area1 = Area(prevOp);
double absArea1 = Math.abs(area1);
Expand Down Expand Up @@ -2793,7 +2791,7 @@ public static boolean BuildPath(@Nullable OutPt op, boolean reverse, boolean isO
}
}

if (path.size() == 3 && IsVerySmallTriangle(op2)) {
if (path.size() == 3 && !isOpen && IsVerySmallTriangle(op2)) {
return false;
} else {
return true;
Expand Down
Loading