00001
00002
00003
00004
00005
00006
00007 #include "geometry/Conic.h"
00008
00009 inline static double sqr(double x){return x*x;}
00010
00011
00012 Conic::Conic( const Point& origin, const Vector& axis,
00013 double radius, double slope )
00014
00015 : Surface(origin ,axis.unit())
00016 , m_slope(slope)
00017 , m_radius(radius)
00018
00019 {}
00020
00021
00022 double
00023 Conic::how_near( const Point& x ) const
00024
00025
00026
00027
00028 {
00029 Vector r = x - origin();
00030 double z = r*axis(),
00031 rho = sqrt( r.mag2() - sqr(z) ),
00032 c = sqrt(1+sqr(m_slope));
00033
00034 return (radius()>0? radius(z)-rho : rho+radius(z))/c ;
00035 }
00036
00037
00038
00039 Vector
00040 Conic::normal( const Point& x )const
00041
00042 {
00043 Vector r = x-origin();
00044 Vector rhohat = (r - (r*axis())*axis()).unit();
00045 double b = radius()>0? m_slope : -m_slope;
00046
00047 Vector n = sqrt(1-sqr(b))*rhohat - b* axis();
00048 return radius()>0 ? n : -n;
00049 }
00050
00051
00052 double
00053 Conic::distance(const Point& x, const Vector& vhat, int inout)const
00054
00055
00056
00057
00058
00059
00060 {
00061
00062 Vector ahat = axis(),
00063 r = x - origin();
00064 double rpar = r*ahat,
00065 vpar = vhat*ahat,
00066 alpha= m_slope,
00067 R = radius(rpar);
00068 Vector rperp = r - rpar*ahat,
00069 vperp = vhat-vpar*ahat;
00070
00071 double a = vperp.mag2()-sqr(alpha*vpar),
00072 b = vperp*rperp-alpha*vpar*R,
00073 c = rperp.mag2() - sqr(R),
00074 disc = b*b-a*c,
00075 s;
00076
00077
00078 if( disc<=0 ) return FLT_MAX;
00079 if( radius()<0 ) inout *=-1;
00080 int leaving = inout==1;
00081 if( b<0 ) {
00082
00083 s = (leaving) ? (-b+sqrt(disc))/a :
00084 c/(-b+sqrt(disc));
00085 } else {
00086
00087 s = (leaving) ? c/(-b-sqrt(disc)) : FLT_MAX;
00088 }
00089
00090 if( m_slope!=0 && (rpar + s*vpar) < -m_radius/m_slope ){
00091
00092 s = FLT_MAX;
00093 }
00094 return s ;
00095 }
00096
00097 void Conic::printOn( std::ostream& os ) const
00098
00099 {
00100 os << "Conic surface with origin: " << origin()
00101 << ",\t radius: " << radius()
00102 << ",\t axis: " << axis()
00103 << ",\t slope: "<< m_slope << "\n";
00104 }
00105
00106
00107