Go to the documentation of this file.00001 #ifndef __VCGTEST_IMPLICITSPHERE
00002 #define __VCGTEST_IMPLICITSPHERE
00003
00004 class ImplicitSphere
00005 {
00006 public:
00007 ImplicitSphere()
00008 {
00009 _center.SetZero();
00010 _radius = _sqr_radius = 0.0;
00011 };
00012
00013 ImplicitSphere(vcg::Point3f ¢er, float radius)
00014 {
00015 _center = center;
00016 _radius = radius;
00017 _sqr_radius = radius*radius;
00018 };
00019
00020 ImplicitSphere(const ImplicitSphere &sphere)
00021 {
00022 _center = sphere._center;
00023 _radius = sphere._radius;
00024 _sqr_radius = sphere._sqr_radius;
00025 };
00026
00027 ImplicitSphere& operator=(const ImplicitSphere &sphere)
00028 {
00029 if (this != &sphere)
00030 {
00031 _center = sphere._center;
00032 _radius = sphere._radius;
00033 _sqr_radius = sphere._sqr_radius;
00034 }
00035 return *this;
00036 };
00037
00038 ~ImplicitSphere()
00039 {};
00040
00041 bool operator!=(const ImplicitSphere &sphere)
00042 {
00043 return (sphere._center!=_center && sphere._radius!=_radius);
00044 };
00045
00046
00047 float V(int x, int y, int z) const
00048 {
00049 vcg::Point3f point((float) x, (float) y, (float) z);
00050 return (_center-point).Norm() - _radius;
00051 };
00052
00053 bool DirectedDistance(const vcg::Point3i &p1, const vcg::Point3i &p2, vcg::Point3f &v, vcg::Point3f &n, float &dist)
00054 {
00055 vcg::Point3f orig, dir;
00056 orig.X() = (float) p1.X();
00057 orig.Y() = (float) p1.Y();
00058 orig.Z() = (float) p1.Z();
00059 dir.X() = (float) p2.X()-p1.X();
00060 dir.Y() = (float) p2.Y()-p1.Y();
00061 dir.Z() = (float) p2.Z()-p1.Z();
00062
00063 double a = dir.SquaredNorm();
00064 double b = 2.0*(dir*(orig - _center));
00065 double c = (orig - _center).SquaredNorm() - _radius*_radius;
00066 double d = b*b - 4.0*a*c;
00067
00068 if (d >= 0)
00069 {
00070 d = sqrt(d);
00071
00072 double t1 = (-b-d) / (2.0*a);
00073 double t2 = (-b+d) / (2.0*a);
00074 double t = 1.00001;
00075 if (t1 >= 0.0 && t1 < t) t = t1;
00076 if (t2 >= 0.0 && t2 < t) t = t2;
00077
00078 if (t != 1.00001)
00079 {
00080 v = (vcg::Point3f) (orig + dir*((float)t));
00081 n = (vcg::Point3f) ((v - _center) / _radius);
00082 dist = (float) ((dir*n) < 0.0) ? dir.Norm()*t : -dir.Norm()*t;
00083 return true;
00084 }
00085 }
00086 return false;
00087 };
00088
00089 private:
00090 vcg::Point3f _center;
00091 float _radius;
00092 float _sqr_radius;
00093 };
00094
00095 #endif // __VCGTEST_IMPLICITSPHERE