package org.geogebra.common.util.clipper;
import org.geogebra.common.util.clipper.Point.DoublePoint;
class OutPt {
public static OutRec getLowerMostRec(OutRec outRec1, OutRec outRec2) {
// work out which polygon fragment has the correct hole state ...
if (outRec1.bottomPt == null) {
outRec1.bottomPt = outRec1.pts.getBottomPt();
}
if (outRec2.bottomPt == null) {
outRec2.bottomPt = outRec2.pts.getBottomPt();
}
final OutPt bPt1 = outRec1.bottomPt;
final OutPt bPt2 = outRec2.bottomPt;
if (bPt1.getPt().getY() > bPt2.getPt().getY()) {
return outRec1;
} else if (bPt1.getPt().getY() < bPt2.getPt().getY()) {
return outRec2;
} else if (bPt1.getPt().getX() < bPt2.getPt().getX()) {
return outRec1;
} else if (bPt1.getPt().getX() > bPt2.getPt().getX()) {
return outRec2;
} else if (bPt1.next == bPt1) {
return outRec2;
} else if (bPt2.next == bPt2) {
return outRec1;
} else if (isFirstBottomPt(bPt1, bPt2)) {
return outRec1;
} else {
return outRec2;
}
}
private static boolean isFirstBottomPt(OutPt btmPt1, OutPt btmPt2) {
OutPt p = btmPt1.prev;
while (p.getPt().equals(btmPt1.getPt()) && !p.equals(btmPt1)) {
p = p.prev;
}
final double dx1p = Math
.abs(DoublePoint.getDeltaX(btmPt1.getPt(), p.getPt()));
p = btmPt1.next;
while (p.getPt().equals(btmPt1.getPt()) && !p.equals(btmPt1)) {
p = p.next;
}
final double dx1n = Math
.abs(DoublePoint.getDeltaX(btmPt1.getPt(), p.getPt()));
p = btmPt2.prev;
while (p.getPt().equals(btmPt2.getPt()) && !p.equals(btmPt2)) {
p = p.prev;
}
final double dx2p = Math
.abs(DoublePoint.getDeltaX(btmPt2.getPt(), p.getPt()));
p = btmPt2.next;
while (p.getPt().equals(btmPt2.getPt()) && p.equals(btmPt2)) {
p = p.next;
}
final double dx2n = Math
.abs(DoublePoint.getDeltaX(btmPt2.getPt(), p.getPt()));
return dx1p >= dx2p && dx1p >= dx2n || dx1n >= dx2p && dx1n >= dx2n;
}
int idx;
// private LongPoint pt;
DoublePoint pt;
OutPt next;
OutPt prev;
public OutPt duplicate(boolean InsertAfter) {
final OutPt result = new OutPt();
// result.setPt( new LongPoint( getPt() ) );
result.setPt(new DoublePoint(getPt()));
result.idx = idx;
if (InsertAfter) {
result.next = next;
result.prev = this;
next.prev = result;
next = result;
} else {
result.prev = prev;
result.next = this;
prev.next = result;
prev = result;
}
return result;
}
OutPt getBottomPt() {
OutPt dups = null;
OutPt p = next;
OutPt pp = this;
while (p != pp) {
if (p.getPt().getY() > pp.getPt().getY()) {
pp = p;
dups = null;
} else if (p.getPt().getY() == pp.getPt().getY()
&& p.getPt().getX() <= pp.getPt().getX()) {
if (p.getPt().getX() < pp.getPt().getX()) {
dups = null;
pp = p;
} else {
if (p.next != pp && p.prev != pp) {
dups = p;
}
}
}
p = p.next;
}
if (dups != null) {
// there appears to be at least 2 vertices at bottomPt so ...
while (dups != p) {
if (!isFirstBottomPt(p, dups)) {
pp = dups;
}
dups = dups.next;
while (!dups.getPt().equals(pp.getPt())) {
dups = dups.next;
}
}
}
return pp;
}
public int getPointCount() {
int result = 0;
OutPt p = this;
do {
result++;
p = p.next;
} while (p != this && p != null);
return result;
}
/**
* modified to be compatible with double
*/
public DoublePoint getPt() {
return pt;
}
public void setPt(DoublePoint pt) {
this.pt = pt;
}
public void reversePolyPtLinks() {
OutPt pp1;
OutPt pp2;
pp1 = this;
do {
pp2 = pp1.next;
pp1.next = pp1.prev;
pp1.prev = pp2;
pp1 = pp2;
} while (pp1 != this);
}
}