Make sliver triangle tests work on the minimum altitude, not on

area.

[git-p4: depot-paths = "//depot/solvespace/": change = 1816]
This commit is contained in:
Jonathan Westhues 2008-07-01 20:32:24 -08:00
parent b77cb053e2
commit 8a70efed05
6 changed files with 16 additions and 9 deletions

View File

@ -67,8 +67,8 @@ void SMesh::Simplify(int start) {
int i, j; int i, j;
for(i = start; i < l.n; i++) { for(i = start; i < l.n; i++) {
STriangle *tr = &(l.elem[i]); STriangle *tr = &(l.elem[i]);
if((tr->Normal()).Magnitude() < LENGTH_EPS*LENGTH_EPS) { if(tr->MinAltitude() < LENGTH_EPS) {
tr->tag = 0; tr->tag = 1;
} else { } else {
tr->tag = 0; tr->tag = 0;
} }
@ -171,7 +171,7 @@ void SMesh::Simplify(int start) {
for(i = 0; i < convc - 2; i++) { for(i = 0; i < convc - 2; i++) {
STriangle tr = STriangle::From(meta, conv[0], conv[i+1], conv[i+2]); STriangle tr = STriangle::From(meta, conv[0], conv[i+1], conv[i+2]);
if((tr.Normal()).Magnitude() > LENGTH_EPS*LENGTH_EPS) { if(tr.MinAltitude() > LENGTH_EPS) {
tout[toutc++] = tr; tout[toutc++] = tr;
} }
} }

View File

@ -5,9 +5,17 @@ Vector STriangle::Normal(void) {
return ab.Cross(bc); return ab.Cross(bc);
} }
double STriangle::MinAltitude(void) {
double altA = a.DistanceToLine(b, c.Minus(b)),
altB = b.DistanceToLine(c, a.Minus(c)),
altC = c.DistanceToLine(a, b.Minus(a));
return min(altA, min(altB, altC));
}
bool STriangle::ContainsPoint(Vector p) { bool STriangle::ContainsPoint(Vector p) {
Vector n = Normal(); Vector n = Normal();
if(n.Magnitude() < LENGTH_EPS*LENGTH_EPS) { if(MinAltitude() < LENGTH_EPS) {
// shouldn't happen; zero-area triangle // shouldn't happen; zero-area triangle
return false; return false;
} }

View File

@ -124,6 +124,7 @@ public:
static STriangle From(STriMeta meta, Vector a, Vector b, Vector c); static STriangle From(STriMeta meta, Vector a, Vector b, Vector c);
Vector Normal(void); Vector Normal(void);
void FlipNormal(void); void FlipNormal(void);
double MinAltitude(void);
int WindingNumberForPoint(Vector p); int WindingNumberForPoint(Vector p);
bool ContainsPoint(Vector p); bool ContainsPoint(Vector p);
bool ContainsPointProjd(Vector n, Vector p); bool ContainsPointProjd(Vector n, Vector p);

View File

@ -24,7 +24,7 @@ inline int WRAP(int v, int n) {
#define ZERO(v) memset((v), 0, sizeof(*(v))) #define ZERO(v) memset((v), 0, sizeof(*(v)))
#define CO(v) (v).x, (v).y, (v).z #define CO(v) (v).x, (v).y, (v).z
#define LENGTH_EPS (0.0000001) #define LENGTH_EPS (1e-7)
#define isforname(c) (isalnum(c) || (c) == '_' || (c) == '-' || (c) == '#') #define isforname(c) (isalnum(c) || (c) == '_' || (c) == '-' || (c) == '#')

View File

@ -269,10 +269,7 @@ Vector Vector::From(hParam x, hParam y, hParam z) {
} }
bool Vector::Equals(Vector v) { bool Vector::Equals(Vector v) {
if(fabs(x - v.x) > LENGTH_EPS) return false; return (this->Minus(v)).Magnitude() < LENGTH_EPS;
if(fabs(y - v.y) > LENGTH_EPS) return false;
if(fabs(z - v.z) > LENGTH_EPS) return false;
return true;
} }
Vector Vector::Plus(Vector b) { Vector Vector::Plus(Vector b) {

View File

@ -8,6 +8,7 @@ auto-generate circles and faces when lathing
copy the section geometry to other end when sweeping copy the section geometry to other end when sweeping
cylindrical faces cylindrical faces
draw explicit edges draw explicit edges
symmetric about line segment
long term long term