00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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
00197 ON_3dPoint ON_Cone::ClosestPointTo(
00198 ON_3dPoint point
00199 ) const
00200 {
00201
00202
00203 ON_3dVector v = (point-plane.origin);
00204 double x = v*plane.xaxis;
00205 double y = v*plane.yaxis;
00206
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
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,
00251 const ON_3dVector& axis,
00252 const ON_3dPoint& point
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
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413