added IsIn for sphere

This commit is contained in:
Federico Ponchio 2010-04-22 19:05:24 +00:00
parent cb73c0bb80
commit 8331ee9981
1 changed files with 30 additions and 16 deletions

View File

@ -89,6 +89,7 @@ protected:
bool IsEmpty() const { return _radius < 0; } bool IsEmpty() const { return _radius < 0; }
///return true if @param p - Center() <= Radius() ///return true if @param p - Center() <= Radius()
bool IsIn(const Point3<T> &p) const; bool IsIn(const Point3<T> &p) const;
bool IsIn(const Sphere3<T> &p) const;
void Add(const Point3<T> &p); void Add(const Point3<T> &p);
void Add(const Sphere3 &sphere); void Add(const Sphere3 &sphere);
@ -128,16 +129,23 @@ template <class T> void Sphere3<T>::Add(const Sphere3<T> &sphere) {
} }
Point3<T> dist = sphere.Center() - _center; Point3<T> dist = sphere.Center() - _center;
float distance = dist.Norm(); float distance = dist.Norm();
float fartest = distance + sphere.Radius(); float fartest = sphere.Radius() + distance;
if(fartest <= _radius) if(fartest <= _radius)
return; return;
if(distance == 0)
_radius = sphere.Radius(); float nearest = sphere.Radius() - distance;
else { if(nearest >= _radius) {
_center += dist * ((fartest - _radius) / (dist.Norm() * 2)); *this = sphere;
_radius = (_radius + fartest)/2; return;
} }
if(distance < 0.001*(_radius + sphere.Radius())) {
_radius += distance;
return;
}
_center += dist * ((fartest - _radius) / (distance * 2));
_radius = (_radius + fartest)/2;
} }
template <class T> void Sphere3<T>::Add(const Point3<T> &p) { template <class T> void Sphere3<T>::Add(const Point3<T> &p) {
@ -158,6 +166,13 @@ template <class T> bool Sphere3<T>::IsIn(const Point3<T> &p) const {
return dist.SquaredNorm() <= _radius*_radius; return dist.SquaredNorm() <= _radius*_radius;
} }
template <class T> bool Sphere3<T>::IsIn(const Sphere3<T> &p) const {
if(IsEmpty()) return false;
Point3<T> dist = p.Center() - _center;
float distance = dist.Norm();
return distance + p.Radius() < _radius;
}
template <class T> void Sphere3<T>::Intersect(const Sphere3<T> &s) { template <class T> void Sphere3<T>::Intersect(const Sphere3<T> &s) {
float dist = Distance(_center, s.Center()); float dist = Distance(_center, s.Center());
float r = 0.5 * (_radius + s.Radius() - dist); float r = 0.5 * (_radius + s.Radius() - dist);
@ -191,7 +206,6 @@ template <class T> void Sphere3<T>::Intersect(const Sphere3<T> &s) {
Radius() *= 1.0001; Radius() *= 1.0001;
Point3<T> center; Point3<T> center;
T radius;
//Test with 6 directions //Test with 6 directions
Point3f pert[6]; Point3f pert[6];
@ -207,13 +221,13 @@ template <class T> void Sphere3<T>::Intersect(const Sphere3<T> &s) {
pert[4] = Point3f(0, 0, step); pert[4] = Point3f(0, 0, step);
pert[5] = -pert[4]; pert[5] = -pert[4];
unsigned int best = 6; int best = 6;
T best_radius = Radius()/threshold; T best_radius = Radius()/threshold;
for(unsigned int k = 0; k < 6; k++) { for(int k = 0; k < 6; k++) {
center = Center() + pert[k]; center = Center() + pert[k];
radius = 0; radius = 0;
for(unsigned int i = 0; i < n; i++) { for(int i = 0; i < n; i++) {
float r = Distance(center, points[i]); float r = Distance(center, points[i]);
if(r > radius) if(r > radius)
radius = r; radius = r;