00001 #ifndef __VCGTEST_SPHEREDIFFERENCE 00002 #define __VCGTEST_SPHEREDIFFERENCE 00003 00004 class SphereDifference 00005 { 00006 public: 00007 SphereDifference() 00008 {} 00009 00010 SphereDifference( const SphereDifference &sphere_difference) 00011 { 00012 _union = sphere_difference._union; 00013 _sphere = sphere_difference._sphere; 00014 } 00015 00016 SphereDifference( const SphereUnion &sphere_union, const ImplicitSphere &sphere) 00017 { 00018 _union = sphere_union; 00019 _sphere = sphere; 00020 } 00021 00022 float V(int x, int y, int z) 00023 { 00024 return vcg::math::Max<float>(_union.V(x, y, z), -_sphere.V(x, y, z)); 00025 } 00026 00027 inline bool DirectedDistance(const vcg::Point3i p1, const vcg::Point3i p2, vcg::Point3f &p, vcg::Point3f &n, float &d) 00028 { 00029 vcg::Point3f v1, n1; 00030 vcg::Point3f v2, n2; 00031 float d1, d2; 00032 00033 bool ok1 = _union.DirectedDistance(p1, p2, v1, n1, d1); 00034 bool ok2 = _sphere.DirectedDistance(p1, p2, v2, n2, d2); 00035 d2 = -d2; 00036 00037 if (ok1 && ok2) 00038 { 00039 if (d1 > d2) 00040 ok2 = false; 00041 else 00042 ok1 = false; 00043 } 00044 00045 if (ok1) 00046 { 00047 p = v1; 00048 n = n1; 00049 d = d1; 00050 return true; 00051 } 00052 else if (ok2) 00053 { 00054 p = v2; 00055 n = n2; 00056 d = d2; 00057 return true; 00058 } 00059 00060 return false; 00061 } 00062 00063 private: 00064 SphereUnion _union; 00065 ImplicitSphere _sphere; 00066 00067 }; 00068 00069 #endif // __VCGTEST_SPHEREDIFFERENCE