opennurbs_cone.cpp
Go to the documentation of this file.
00001 /* $NoKeywords: $ */
00002 /*
00003 //
00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
00006 // McNeel & Associates.
00007 //
00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
00011 //                              
00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
00013 //
00015 */
00016 
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018 
00019 ON_Cone::ON_Cone() 
00020 {
00021   height = 0.0;
00022 }
00023 
00024 ON_Cone::ON_Cone(
00025     const ON_Plane& p,
00026     double h,
00027     double r
00028     )
00029 {
00030   Create(p,h,r);
00031 }
00032 
00033 ON_Cone::~ON_Cone()
00034 {}
00035 
00036 
00037 ON_BOOL32 ON_Cone::Create(
00038     const ON_Plane& p,
00039     double h,
00040     double r
00041     )
00042 {
00043   plane = p;
00044   height = h;
00045   radius = r;
00046   return IsValid();
00047 }
00048 
00049 ON_BOOL32 ON_Cone::IsValid() const
00050 {
00051   return (plane.IsValid() && height != 0.0 && radius != 0.0);
00052 }
00053 
00054 
00055 const ON_3dVector& ON_Cone::Axis() const
00056 {
00057   return plane.zaxis;
00058 }
00059 
00060 const ON_3dPoint& ON_Cone::ApexPoint() const
00061 {
00062   return plane.origin;
00063 }
00064 
00065 ON_3dPoint ON_Cone::BasePoint() const
00066 {
00067   return plane.origin + height*plane.zaxis;
00068 }
00069 
00070 double ON_Cone::AngleInRadians() const
00071 {
00072   return height == 0.0 ? (radius!=0.0?ON_PI:0.0) : atan(radius/height);
00073 }
00074 
00075 double ON_Cone::AngleInDegrees() const
00076 {
00077   return 180.0*AngleInRadians()/ON_PI;
00078 }
00079 
00080 ON_Circle ON_Cone::CircleAt( 
00081       double height_parameter
00082       ) const
00083 {
00084   ON_Circle c(plane,radius);
00085   c.Translate(height_parameter*plane.zaxis);
00086   if ( height != 0.0 )
00087     c.radius *= height_parameter/height;
00088   else if (height_parameter==0.0)
00089     c.radius = 0.0;
00090   return c;
00091 }
00092 
00093 ON_Line ON_Cone::LineAt( 
00094       double radial_parameter
00095       ) const
00096 {
00097   return ON_Line(PointAt(radial_parameter,height),ApexPoint());
00098 }
00099 
00100 
00101 ON_3dPoint ON_Cone::PointAt( double radial_parameter, double height_parameter ) const
00102 {
00103   double r;
00104   if ( height != 0.0 )
00105     r = (radius/height)*height_parameter;
00106   else
00107     r = (height_parameter == 0.0)?0.0:radius;
00108   return plane.PointAt(r*cos(radial_parameter),r*sin(radial_parameter)) + height_parameter*plane.zaxis;
00109 }
00110 
00111 ON_3dVector ON_Cone::NormalAt( double radial_parameter, double height_parameter ) const
00112 {
00113   double s = sin(radial_parameter);
00114   double c = cos(radial_parameter);
00115   if ( radius<0.) {
00116     c = -c;
00117     s = -s;
00118   }
00119   ON_3dVector ds = c*plane.yaxis - s*plane.xaxis;
00120   ON_3dVector N = ON_CrossProduct( ((radius<0.0)?-ds:ds),
00121                                    plane.PointAt(radius*c,radius*s,height) - plane.origin
00122                                    );
00123   N.Unitize();
00124   return N;
00125 }
00126 
00127 ON_BOOL32 ON_Cone::Transform( const ON_Xform& xform )
00128 {
00129   ON_Circle xc(plane,radius);
00130   ON_BOOL32 rc = xc.Transform(xform);
00131   if (rc)
00132   {
00133     ON_3dPoint xH = xform*(plane.origin + height*plane.zaxis);
00134     double xh = (xH-xc.plane.origin)*xc.plane.zaxis;
00135     plane = xc.plane;
00136     radius = xc.radius;
00137     height = xh;
00138   }
00139   return rc;
00140 }
00141 
00142 bool ON_Cone::ClosestPointTo( 
00143           ON_3dPoint point, 
00144           double* radial_parameter,
00145           double* height_parameter
00146        ) const
00147 {
00148   // untested code
00149 
00150   bool rc = false;
00151 
00152   ON_3dVector v = (point-plane.origin);
00153   double x = v*plane.xaxis;
00154   double y = v*plane.yaxis;
00155   double z = v*plane.zaxis;
00156 
00157   if ( radial_parameter )
00158   {
00159     double a = ( 0.0 == y && 0.0 == x ) ? 0.0 : atan2(y,x);
00160 
00161     if (a > 2.0*ON_PI )
00162     {
00163       a -= 2.0*ON_PI;
00164     }
00165     
00166     if (a < 0.0 )
00167     {
00168       a += 2.0*ON_PI;
00169     }
00170 
00171     *radial_parameter = a;
00172   }
00173 
00174   if (height_parameter)
00175   {
00176     point.x -= plane.origin.x;
00177     point.y -= plane.origin.y;
00178     point.z -= plane.origin.z;
00179     v.x = x;
00180     v.y = y;
00181     v.z = 0.0;
00182     v.Unitize();
00183     v.x *= radius;
00184     v.y *= radius;
00185     ON_Line line(ON_origin, v.x*plane.xaxis + v.y*plane.yaxis + height*plane.zaxis );
00186     rc = line.ClosestPointTo(point,&z);
00187     if (rc)
00188     {
00189       *height_parameter = z*height;
00190     }
00191   }
00192 
00193   return rc;
00194 }
00195 
00196 // returns point on cylinder that is closest to given point
00197 ON_3dPoint ON_Cone::ClosestPointTo( 
00198        ON_3dPoint point
00199        ) const
00200 {
00201   // untested code
00202 
00203   ON_3dVector v = (point-plane.origin);
00204   double x = v*plane.xaxis;
00205   double y = v*plane.yaxis;
00206   //double z = v*plane.zaxis;
00207 
00208   point.x -= plane.origin.x;
00209   point.y -= plane.origin.y;
00210   point.z -= plane.origin.z;
00211   v.x = x;
00212   v.y = y;
00213   v.z = 0.0;
00214   v.Unitize();
00215   v.x *= radius;
00216   v.y *= radius;
00217   ON_Line line(ON_origin, v.x*plane.xaxis + v.y*plane.yaxis + height*plane.zaxis );
00218   return line.ClosestPointTo(point);
00219 }
00220 
00221 ON_BOOL32 ON_Cone::Rotate(
00222       double sin_angle,
00223       double cos_angle,
00224       const ON_3dVector& axis_of_rotation
00225       )
00226 {
00227   return Rotate( sin_angle, cos_angle, axis_of_rotation, plane.origin );
00228 }
00229 
00230 ON_BOOL32 ON_Cone::Rotate(
00231       double angle,
00232       const ON_3dVector& axis_of_rotation
00233       )
00234 {
00235   return Rotate( sin(angle), cos(angle), axis_of_rotation, plane.origin );
00236 }
00237 
00238 // rotate plane about a point and axis
00239 ON_BOOL32 ON_Cone::Rotate(
00240       double sin_angle,
00241       double cos_angle,
00242       const ON_3dVector& axis_of_rotation,
00243       const ON_3dPoint& center_of_rotation
00244       )
00245 {
00246   return plane.Rotate( sin_angle, cos_angle, axis_of_rotation, center_of_rotation );
00247 }
00248 
00249 ON_BOOL32 ON_Cone::Rotate(
00250       double angle,              // angle in radians
00251       const ON_3dVector& axis, // axis of rotation
00252       const ON_3dPoint&  point  // center of rotation
00253       )
00254 {
00255   return Rotate( sin(angle), cos(angle), axis, point );
00256 }
00257 
00258 ON_BOOL32 ON_Cone::Translate(
00259       const ON_3dVector& delta
00260       )
00261 {
00262   return plane.Translate( delta );
00263 }
00264 
00265 int ON_Cone::GetNurbForm( ON_NurbsSurface& s ) const
00266 {
00267   int rc = 0;
00268   if ( IsValid() ) {
00269     ON_Circle c = CircleAt(height);
00270     ON_NurbsCurve n;
00271     c.GetNurbForm(n);
00272     ON_3dPoint apex = ApexPoint();
00273     ON_4dPoint cv;
00274     int i, j0, j1;
00275 
00276     s.Create(3,true,3,2,9,2);
00277     for ( i = 0; i < 10; i++ )
00278       s.m_knot[0][i] = n.m_knot[i];
00279 
00280     if ( height >= 0.0 ) {
00281       s.m_knot[1][0] = 0.0;
00282       s.m_knot[1][1] = height; 
00283       j0 = 0;
00284       j1 = 1;
00285     }
00286     else {
00287       s.m_knot[1][0] = height;
00288       s.m_knot[1][1] = 0.0;
00289       j0 = 1;
00290       j1 = 0;
00291     }
00292 
00293     for ( i = 0; i < 9; i++ ) {
00294       cv = n.CV(i);
00295       s.SetCV(i, j1, ON::homogeneous_rational, &cv.x );
00296       cv.x = apex.x*cv.w;
00297       cv.y = apex.y*cv.w;
00298       cv.z = apex.z*cv.w;
00299       s.SetCV(i, j0, cv);
00300     }
00301     rc = 2;
00302   }
00303   return rc;
00304 }
00305 
00306 ON_RevSurface* ON_Cone::RevSurfaceForm( ON_RevSurface* srf ) const
00307 {
00308   if ( srf )
00309     srf->Destroy();
00310   ON_RevSurface* pRevSurface = NULL;
00311   if ( IsValid() )
00312   {
00313     ON_Line line;
00314     ON_Interval line_domain;
00315     if ( height >= 0.0 )
00316       line_domain.Set(0.0,height);
00317     else
00318       line_domain.Set(height,0.0);
00319     line.from = PointAt(0.0,line_domain[0]);
00320     line.to = PointAt(0.0,line_domain[1]);
00321     ON_LineCurve* line_curve = new ON_LineCurve( line, line_domain[0], line_domain[1] );
00322     if ( srf )
00323       pRevSurface = srf;
00324     else
00325       pRevSurface = new ON_RevSurface();
00326     pRevSurface->m_angle.Set(0.0,2.0*ON_PI);
00327     pRevSurface->m_t = pRevSurface->m_angle;
00328     pRevSurface->m_curve = line_curve;
00329     pRevSurface->m_axis.from = plane.origin;
00330     pRevSurface->m_axis.to = plane.origin + plane.zaxis;
00331     pRevSurface->m_bTransposed = false;
00332     pRevSurface->m_bbox.m_min = plane.origin;
00333     pRevSurface->m_bbox.m_max = plane.origin;
00334     pRevSurface->m_bbox.Union(CircleAt(height).BoundingBox());
00335   }
00336   return pRevSurface;
00337 }
00338 
00339 /*
00340 // obsolete use ON_BrepCone
00341 ON_Brep* ON_Cone::BrepForm( ON_Brep* brep ) const
00342 {
00343   ON_Brep* pBrep = 0;
00344   if ( brep )
00345     brep->Destroy();
00346   ON_RevSurface* pRevSurface = RevSurfaceForm();
00347   if ( pRevSurface )
00348   {
00349     if ( brep )
00350       pBrep = brep;
00351     else
00352       pBrep = new ON_Brep();
00353     if ( !pBrep->Create(pRevSurface) ) 
00354     {
00355       if ( !brep )
00356         delete pBrep;
00357       pBrep = 0;
00358       if ( !pRevSurface )
00359       {
00360         delete pRevSurface;
00361         pRevSurface = 0;
00362       }
00363     }
00364     else 
00365     {
00366       // add cap
00367       ON_Circle circle = CircleAt(height);
00368       ON_NurbsSurface* pCapSurface = ON_NurbsSurfaceQuadrilateral( 
00369         circle.plane.PointAt(-radius,-radius),
00370         circle.plane.PointAt(+radius,-radius),
00371         circle.plane.PointAt(+radius,+radius),
00372         circle.plane.PointAt(-radius,+radius)
00373         );
00374       pCapSurface->m_knot[0][0] = -fabs(radius);
00375       pCapSurface->m_knot[0][1] =  fabs(radius);
00376       pCapSurface->m_knot[1][0] = pCapSurface->m_knot[0][0];
00377       pCapSurface->m_knot[1][1] = pCapSurface->m_knot[0][1];
00378       circle.Create( ON_xy_plane, ON_origin, radius );
00379       ON_NurbsCurve* c2 = new ON_NurbsCurve();
00380       circle.GetNurbForm(*c2);
00381       c2->ChangeDimension(2);
00382 
00383       pBrep->m_S.Append(pCapSurface);
00384       pBrep->m_C2.Append(c2);
00385       ON_BrepFace& cap = pBrep->NewFace( pBrep->m_S.Count()-1 );
00386       ON_BrepLoop& loop = pBrep->NewLoop( ON_BrepLoop::outer, cap );
00387       ON_BrepEdge& edge = pBrep->m_E[1];
00388       ON_BrepTrim& trim = pBrep->NewTrim( edge, true, loop, pBrep->m_C2.Count()-1 );
00389       trim.m_tolerance[0] = 0.0;
00390       trim.m_tolerance[1] = 0.0;
00391       trim.m_pbox.m_min.x = -radius;
00392       trim.m_pbox.m_min.y = -radius;
00393       trim.m_pbox.m_min.z = 0.0;
00394       trim.m_pbox.m_max.x = radius;
00395       trim.m_pbox.m_max.y = radius;
00396       trim.m_pbox.m_max.z = 0.0;
00397       loop.m_pbox = trim.m_pbox;
00398       pBrep->SetTrimIsoFlags(trim);
00399       for ( int eti = 0; eti < edge.m_ti.Count(); eti++ )
00400         pBrep->m_T[ edge.m_ti[eti] ].m_type = ON_BrepTrim::mated;
00401       if ( !pBrep->IsValid() )
00402       {
00403         if (brep)
00404           brep->Destroy();
00405         else
00406           delete pBrep;
00407         pBrep = 0;
00408       }
00409     }
00410   }
00411   return pBrep;
00412 }
00413 */


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:00