/* Find convex hull vertex to complete triangle (oriented call) */ static RBFNODE * find_chull_vert(const RBFNODE *rbf0, const RBFNODE *rbf1) { FVECT vmid, vejn, vp; RBFNODE *rbf, *rbfbest = NULL; double dprod, area2, bestarea2 = FHUGE, bestdprod = -.5; VSUB(vejn, rbf1->invec, rbf0->invec); VADD(vmid, rbf0->invec, rbf1->invec); if (normalize(vejn) == 0 || normalize(vmid) == 0) return(NULL); /* XXX exhaustive search */ /* Find triangle with minimum rotation from perpendicular */ for (rbf = dsf_list; rbf != NULL; rbf = rbf->next) { if ((rbf == rbf0) | (rbf == rbf1)) continue; tri_orient(vp, rbf0->invec, rbf1->invec, rbf->invec); if (DOT(vp, vmid) <= FTINY) continue; /* wrong orientation */ area2 = .25*DOT(vp,vp); VSUB(vp, rbf->invec, vmid); dprod = -DOT(vp, vejn); VSUM(vp, vp, vejn, dprod); /* above guarantees non-zero */ dprod = DOT(vp, vmid) / VLEN(vp); if (dprod <= bestdprod + FTINY*(1 - 2*(area2 < bestarea2))) continue; /* found better already */ if (overlaps_tri(rbf0, rbf1, rbf)) continue; /* overlaps another triangle */ rbfbest = rbf; bestdprod = dprod; /* new one to beat */ bestarea2 = area2; } return(rbfbest); }
/* Determine if vertex order is reversed (inward normal) */ int is_rev_tri(const FVECT v1, const FVECT v2, const FVECT v3) { FVECT tor; tri_orient(tor, v1, v2, v3); return(DOT(tor, v2) < 0.); }