00001 #ifndef __SEG_DIST__
00002 #define __SEG_DIST__
00003
00004
00005 #define float double
00006
00007
00008
00009
00010
00011 float aux_edge(float tmp, float denum) {
00012
00013
00014 if (tmp>0.0)
00015 return 0.0;
00016 else {
00017 if (-tmp>denum)
00018 return 1.0;
00019 else
00020 return -tmp/denum;
00021 }
00022 }
00023
00024 float aux_corner(float s_in, float t_in, float Qs, float Qt,
00025 float edge0, float denum0, float edge1,
00026 float denum1, float &s, float &t) {
00027 if (Qs>0.0) { t=t_in;s=aux_edge(edge0,denum0); }
00028 else { s=s_in;
00029 if (Qt>0.0) t=aux_edge(edge1,denum1);
00030 else t = t_in;
00031 }
00032 }
00033
00034 template<class Vector>
00035 float min_seg_dist(const Vector &B0, const Vector &B0p, const Vector &B1,
00036 const Vector &B1p,float &s,float &t) {
00037 const float tol = 1e-12;
00038 Vector D = B0-B1, M0 = B0p-B0, M1 = B1p-B1;
00039 float a = M0.dot(M0), b = -M0.dot(M1), c = M1.dot(M1);
00040 float d = M0.dot(D), e = -M1.dot(D), f = D.dot(D);
00041 float det = fabsf(a*c-b*b);
00042 float invDet, tmp;
00043 s = b*e-c*d; t = b*d-a*e;
00044
00045 if (det>=tol) {
00046
00047 if (s>=0.0) {
00048 if (s<=det) {
00049 if (t>=0.0) {
00050 if (t<=det) {
00051 invDet = 1.0/det; s*= invDet; t*=invDet; }
00052 else {
00053 t=1.0; s=aux_edge(b+d,a);
00054 }
00055 }
00056 else {
00057 t=0.0; s=aux_edge(d,a);
00058 }
00059 }
00060 else {
00061 if (t>=0.0) {
00062 if (t<=det) {
00063 s = 1.0; t=aux_edge(b+e,c);
00064 }
00065 else {
00066 aux_corner(1.0,1.0,a+b+c,b+c+e,b+d,a,b+e,c,s,t);
00067 }
00068 }
00069 else {
00070 aux_corner(1.0,0.0,a+d,b+e,d,a,b+e,c,s,t);
00071 }
00072 }
00073 }
00074 else {
00075 if (t>=0.0) {
00076 if (t<=det) {
00077 s = 0.0; t=aux_edge(e,c);
00078 } else {
00079 aux_corner(0.0,1.0,-(b+d),c+e,b+d,a,e,c,s,t);
00080 }
00081 }
00082 else {
00083 aux_corner(0.0,0.0,-d,-e,d,a,e,c,s,t);
00084 }
00085 }
00086 }
00087 else {
00088
00089
00090 if (b>0) {
00091 if (d>=0) { s=0.0; t=0.0; }
00092 else {
00093 if (-d<=a) { s=-d/a; t=0.0; }
00094 else {
00095 s=1.0; tmp = a+d; if (-tmp>=b) t=1.0; else t = -tmp/b;
00096 }
00097 }
00098 }
00099 else {
00100 if (-d>=a) { s=1.0;t=0.0; }
00101 else { if (d<=0.0) { s=-d/a; t=0.0; }
00102 else { s=0.0; if (d>=-b) t=1.0; else t=-d/b;} }
00103 }
00104 }
00105 return ((B0+(B0p-B0)*s)-(B1+(B1p-B1)*t)).norm();
00106 }
00107
00108 #endif // __SEG_DIST__