mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-10 16:19:54 +01:00
better decision-making about when to Fill hole
This commit is contained in:
parent
8c53b5f07e
commit
6f70496b5d
@ -41,6 +41,7 @@
|
|||||||
namespace p2t {
|
namespace p2t {
|
||||||
|
|
||||||
const double PI_3div4 = 3 * M_PI / 4;
|
const double PI_3div4 = 3 * M_PI / 4;
|
||||||
|
const double PI_div2 = 1.57079632679489661923;
|
||||||
const double EPSILON = 1e-12;
|
const double EPSILON = 1e-12;
|
||||||
|
|
||||||
enum Orientation { CW, CCW, COLLINEAR };
|
enum Orientation { CW, CCW, COLLINEAR };
|
||||||
|
@ -225,8 +225,8 @@ void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n)
|
|||||||
Node* node = n.next;
|
Node* node = n.next;
|
||||||
|
|
||||||
while (node->next) {
|
while (node->next) {
|
||||||
double angle = HoleAngle(*node);
|
// if HoleAngle exceeds 90 degrees then break.
|
||||||
if (angle > M_PI_2 || angle < -M_PI_2) break;
|
if (LargeHole_DontFill(node)) break;
|
||||||
Fill(tcx, *node);
|
Fill(tcx, *node);
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
@ -235,8 +235,8 @@ void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n)
|
|||||||
node = n.prev;
|
node = n.prev;
|
||||||
|
|
||||||
while (node->prev) {
|
while (node->prev) {
|
||||||
double angle = HoleAngle(*node);
|
// if HoleAngle exceeds 90 degrees then break.
|
||||||
if (angle > M_PI_2 || angle < -M_PI_2) break;
|
if (LargeHole_DontFill(node)) break;
|
||||||
Fill(tcx, *node);
|
Fill(tcx, *node);
|
||||||
node = node->prev;
|
node = node->prev;
|
||||||
}
|
}
|
||||||
@ -250,6 +250,61 @@ void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// True if HoleAngle exceeds 90 degrees.
|
||||||
|
bool Sweep::LargeHole_DontFill(Node* node) {
|
||||||
|
|
||||||
|
Node* nextNode = node->next;
|
||||||
|
Node* prevNode = node->prev;
|
||||||
|
if (!AngleExceeds90Degrees(node->point, nextNode->point, prevNode->point))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check additional points on front.
|
||||||
|
Node* next2Node = nextNode->next;
|
||||||
|
// "..Plus.." because only want angles on same side as point being added.
|
||||||
|
if ((next2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, next2Node->point, prevNode->point))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Node* prev2Node = prevNode->prev;
|
||||||
|
// "..Plus.." because only want angles on same side as point being added.
|
||||||
|
if ((prev2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, nextNode->point, prev2Node->point))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sweep::AngleExceeds90Degrees(Point* origin, Point* pa, Point* pb) {
|
||||||
|
double angle = Angle(*origin, *pa, *pb);
|
||||||
|
bool exceeds90Degrees = ((angle > PI_div2) || (angle < -PI_div2));
|
||||||
|
return exceeds90Degrees;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sweep::AngleExceedsPlus90DegreesOrIsNegative(Point* origin, Point* pa, Point* pb) {
|
||||||
|
double angle = Angle(*origin, *pa, *pb);
|
||||||
|
bool exceedsPlus90DegreesOrIsNegative = (angle > PI_div2) || (angle < 0);
|
||||||
|
return exceedsPlus90DegreesOrIsNegative;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Sweep::Angle(Point& origin, Point& pa, Point& pb) {
|
||||||
|
/* Complex plane
|
||||||
|
* ab = cosA +i*sinA
|
||||||
|
* ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
|
||||||
|
* atan2(y,x) computes the principal value of the argument function
|
||||||
|
* applied to the complex number x+iy
|
||||||
|
* Where x = ax*bx + ay*by
|
||||||
|
* y = ax*by - ay*bx
|
||||||
|
*/
|
||||||
|
double px = origin.x;
|
||||||
|
double py = origin.y;
|
||||||
|
double ax = pa.x- px;
|
||||||
|
double ay = pa.y - py;
|
||||||
|
double bx = pb.x - px;
|
||||||
|
double by = pb.y - py;
|
||||||
|
double x = ax * by - ay * bx;
|
||||||
|
double y = ax * bx + ay * by;
|
||||||
|
double angle = atan2(x, y);
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
|
||||||
double Sweep::BasinAngle(Node& node)
|
double Sweep::BasinAngle(Node& node)
|
||||||
{
|
{
|
||||||
double ax = node.point->x - node.next->next->point->x;
|
double ax = node.point->x - node.next->next->point->x;
|
||||||
|
@ -169,6 +169,13 @@ private:
|
|||||||
*/
|
*/
|
||||||
void FillAdvancingFront(SweepContext& tcx, Node& n);
|
void FillAdvancingFront(SweepContext& tcx, Node& n);
|
||||||
|
|
||||||
|
// Decision-making about when to Fill hole.
|
||||||
|
// Contributed by ToolmakerSteve2
|
||||||
|
bool LargeHole_DontFill(Node* node);
|
||||||
|
bool AngleExceeds90Degrees(Point* origin, Point* pa, Point* pb);
|
||||||
|
bool AngleExceedsPlus90DegreesOrIsNegative(Point* origin, Point* pa, Point* pb);
|
||||||
|
double Angle(Point& origin, Point& pa, Point& pb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param node - middle node
|
* @param node - middle node
|
||||||
|
Loading…
Reference in New Issue
Block a user