// find distance x0 is from triangle x1-x2-x3 float point_triangle_distance( const Vec3f &x0, const Vec3f &x1, const Vec3f &x2, const Vec3f &x3, float * baryCentricCoordinates) { // first find barycentric coordinates of closest point on infinite plane Vec3f x13(x1-x3), x23(x2-x3), x03(x0-x3); float m13=mag2(x13), m23=mag2(x23), d=dot(x13,x23); float invdet=1.f/max(m13*m23-d*d,1e-30f); float a=dot(x13,x03), b=dot(x23,x03); // the barycentric coordinates themselves float w23=invdet*(m23*a-d*b); float w31=invdet*(m13*b-d*a); float w12=1-w23-w31; if(baryCentricCoordinates!=0){ baryCentricCoordinates[0] = w23; baryCentricCoordinates[1] = w31; baryCentricCoordinates[2] = w12; } if(w23>=0 && w31>=0 && w12>=0){ // if we're inside the triangle return dist(x0, w23*x1+w31*x2+w12*x3); }else{ // we have to clamp to one of the edges if(w23>0) // this rules out edge 2-3 for us return min(point_segment_distance(x0,x1,x2), point_segment_distance(x0,x1,x3)); else if(w31>0) // this rules out edge 1-3 return min(point_segment_distance(x0,x1,x2), point_segment_distance(x0,x2,x3)); else // w12 must be >0, ruling out edge 1-2 return min(point_segment_distance(x0,x1,x3), point_segment_distance(x0,x2,x3)); } }
// find distance x0 is from triangle x1-x2-x3 static FLOAT64 point_triangle_distance(const vec3d &x0, const vec3d &x1, const vec3d &x2, const vec3d &x3, vec3d &out ) { // first find barycentric coordinates of closest point on infinite plane vec3d x13(x1-x3), x23(x2-x3), x03(x0-x3); FLOAT64 m13=x13.len2(), m23=x23.len2(), d=x13*x23; FLOAT64 invdet=1.0/fmax(m13*m23-d*d,1e-30); FLOAT64 a=x13*x03, b=x23*x03; // the barycentric coordinates themselves FLOAT64 w23=invdet*(m23*a-d*b); FLOAT64 w31=invdet*(m13*b-d*a); FLOAT64 w12=1-w23-w31; if(w23>=0 && w31>=0 && w12>=0){ // if we're inside the triangle out = w23*x1+w31*x2+w12*x3; return (x0-out).len(); }else{ // we have to clamp to one of the edges if(w23>0) // this rules out edge 2-3 for us return fmin(point_segment_distance(x0,x1,x2,out), point_segment_distance(x0,x1,x3,out)); else if(w31>0) // this rules out edge 1-3 return fmin(point_segment_distance(x0,x1,x2,out), point_segment_distance(x0,x2,x3,out)); else // w12 must be >0, ruling out edge 1-2 return fmin(point_segment_distance(x0,x1,x3,out), point_segment_distance(x0,x2,x3,out)); } }
int main(void) { // 3.4.5 Class member access // p 2 // if the id-expression in a class member access is an // unqualified-id, and the type of the object expression is of class // type C (or pointer to class type C), the unqualified-id is looked // up in the scope of class C. If the type of the object-expression // is of pointer to scalar type, the unqualified-id is looked up in // the context of the complete postfix-expression. // p 3 // if the unqualitified id is ~type-name, and the type of the object // expression is of a class type C (or pointer to class type C), the // type-name is looked up in the context of the entire // postfix-expression and in the scope of class C. The type-name // shall refer to a class-name. If type-name is found in both // contexts, the name shall refer to the same class type. If the // type of the object expression is of scalar type, the type-name is // looked up in the complete postfix-expression. typedef X localtype; // // 1 non-templatized, pointer, unqualified // X x01 ; X *px = &x01; px->~X(); X x02 (66); px = &x02; px->~localtype(); X x03 (68); px = &x03; px->~classtype(); //-g++ //p3: unqual-id lookup in object and postfix-expr X x04 (70); px = &x04; px->~globaltype(); // p 1 // . . . the id-expression is first looked up in the class of the // object-expression. If the identifier is not found, itis then // looked up in the context of the entier postfix-expression and // shall name a class or function template. If the lookup in the // class of the object-expression finds a template, the name is also // looked up in teh context of the entier postfix-expression and // 1 if the name is not found, use the name from the object-expr // 2 if the name found in postfix-expr != class template, use object-expr // 3 if name found is class template, name must match object-expr or error // p 4 // if the id-expr in a class member acess is a qualified-id, the // id-expression is looked up in both the context of the entire // postfix-expr and in the scope of the class of the object-expr. If // the name is found in both contexts, the id-expr shall refer to // the same entity. // // 2 non-templatized, pointer, qualified // X x05 ; px = &x05; px->X::~X(); X x06 (66); px = &x06; px->X::~localtype(); X x07 (68); px = &x07; px->X::~classtype(); // -edg X x08 (70); px = &x08; px->X::~globaltype(); X x09 (66); px = &x09; px->localtype::~localtype(); X x10 (68); px = &x10; px->classtype::~classtype(); X x11 (70); px = &x11; px->globaltype::~globaltype(); X x12 (66); px = &x12; px->classtype::~localtype(); X x13 (68); px = &x13; px->globaltype::~localtype(); X x14 (70); px = &x14; px->localtype::~globaltype(); X x15 (70); px = &x15; px->classtype::~globaltype(); X x16 (70); px = &x16; px->localtype::~classtype(); //-edg X x17 (70); px = &x17; px->globaltype::~classtype(); //-edg #if 0 // // non-templatized, non-pointer // X xo5 ; xo5.~X(); //unqualified localtype xo6 (66); xo6.~localtype(); X xo7 (68); xo7.~classtype(); X xo8 (70); xo8.~globaltype(); // // templatized, pointer // X_tem<int> xto1 ; X_tem<int> *pxt = &xto1; pxt->~X_tem(); //unqualified typedef X_tem<int> localtype_tem; localtype_tem xto2 (66); pxt = &xto2; pxt->~localtype_tem(); //paragraph 2: unqualitifed id looked up in scope of post-fix expr if object X_tem<int> xto3 (68); pxt = &xto3; pxt->~classtype_tem(); X_tem<int> xto4 (70); pxt = &xto4; pxt->~globaltype_tem(); // // templatized, non-pointer // X_tem<int> xto5 ; xto5.~X_tem(); //unqualified localtype_tem xto6 (66); xto6.~localtype_tem(); X_tem<int> xto7 (68); xto7.~classtype_tem(); X_tem<int> xto8 (70); xto8.~globaltype_tem(); #endif return 0; }