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 #if !defined(ON_BOUNDING_BOX_INC_) 00018 #define ON_BOUNDING_BOX_INC_ 00019 00021 // 00022 // ON_BoundingBox - axis aligned bounding box 00023 // 00024 00025 class ON_CLASS ON_BoundingBox 00026 { 00027 public: 00028 static const ON_BoundingBox EmptyBoundingBox; // ((1.0,0,0,0,0),(-1.0,0.0,0.0)) 00029 00030 ON_BoundingBox(); // creates EmptyBox 00031 00032 ON_BoundingBox( 00033 const ON_3dPoint&, // min corner of axis aligned bounding box 00034 const ON_3dPoint& // max corner of axis aligned bounding box 00035 ); 00036 ~ON_BoundingBox(); 00037 00038 00039 // temporary - use ON_ClippingRegion - this function will be removed soon. 00040 int IsVisible( 00041 const ON_Xform& bbox2c 00042 ) const; 00043 00044 void Destroy(); // invalidates bounding box 00045 00046 // operator[] returns min if index <= 0 and max if indes >= 1 00047 ON_3dPoint& operator[](int); 00048 const ON_3dPoint& operator[](int) const; 00049 00050 ON_3dPoint Min() const; 00051 ON_3dPoint Max() const; 00052 ON_3dVector Diagonal() const; // max corner - min corner 00053 ON_3dPoint Center() const; 00054 ON_3dPoint Corner( // 8 corners of box 00055 int, // x_index 0 = Min().x, 1 = Max().x 00056 int, // y_index 0 = Min().y, 1 = Max().y 00057 int // z_index 0 = Min().z, 1 = Max().z 00058 ) const; 00059 bool GetCorners( 00060 ON_3dPointArray& box_corners // returns list of 8 corner points 00061 ) const; 00062 bool GetCorners( 00063 ON_3dPoint box_corners[8] // returns list of 8 corner points 00064 ) const; 00065 00066 bool IsValid() const; // empty boxes are not valid 00067 00068 void Dump(class ON_TextLog&) const; 00069 00070 /* 00071 Description: 00072 Test a bounding box to see if it is degenerate (flat) 00073 in one or more directions. 00074 Parameters: 00075 tolerance - [in] Distances <= tolerance will be considered 00076 to be zero. If tolerance is negative (default), then 00077 a scale invarient tolerance is used. 00078 Returns: 00079 @untitled table 00080 0 box is not degenerate 00081 1 box is a rectangle (degenerate in one direction) 00082 2 box is a line (degenerate in two directions) 00083 3 box is a point (degenerate in three directions) 00084 4 box is not valid 00085 */ 00086 int IsDegenerate( 00087 double tolerance = ON_UNSET_VALUE 00088 ) const; 00089 00090 00092 // ON_BoundingBox::Transform() updates the bounding box 00093 // to be the smallest axis aligned bounding box that contains 00094 // the transform of the eight corner points of the input 00095 // bounding box. 00096 bool Transform( const ON_Xform& ); 00097 00098 double Tolerance() const; // rough guess at a tolerance to use for comparing 00099 // objects in this bounding box 00100 00101 00102 // All of these Set() functions set or expand a box to enclose the points in the arguments 00103 // If bGrowBox is true, the existing box is expanded, otherwise it is only set to the current point list 00104 bool Set( 00105 int dim, 00106 int is_rat, 00107 int count, 00108 int stride, 00109 const double* point_array, 00110 int bGrowBox = false 00111 ); 00112 00113 bool Set( 00114 const ON_3dPoint& point, 00115 int bGrowBox = false 00116 ); 00117 00118 bool Set( 00119 const ON_SimpleArray<ON_4dPoint>& point_array, 00120 int bGrowBox = false 00121 ); 00122 00123 bool Set( 00124 const ON_SimpleArray<ON_3dPoint>& point_array, 00125 int bGrowBox = false 00126 ); 00127 00128 bool Set( 00129 const ON_SimpleArray<ON_2dPoint>& point_array, 00130 int bGrowBox = false 00131 ); 00132 00133 bool IsPointIn( 00134 const ON_3dPoint& test_point, // point to test 00135 int bStrictlyIn = false 00136 // true to test for strict ( min < point < max ) 00137 // false to test for (min <= point <= max) 00138 // 00139 ) const; 00140 00142 // Point on or in the box that is closest to test_point. 00143 // If test_point is in or on the box, the test_point is returned. 00144 ON_3dPoint ClosestPoint( 00145 const ON_3dPoint& test_point 00146 ) const; 00147 00148 00149 /* 00150 Description: 00151 Quickly find a lower bound on the distance 00152 between the point and this bounding box. 00153 Parameters: 00154 P - [in] 00155 Returns: 00156 A distance that is less than or equal to the shortest 00157 distance from the line to this bounding box. 00158 Put another way, if Q is any point in this bounding box, 00159 then P.DistanceTo(Q) >= MinimumDistanceTo(bbox). 00160 */ 00161 double MinimumDistanceTo( const ON_3dPoint& P ) const; 00162 00163 /* 00164 Description: 00165 Quickly find an upper bound on the distance 00166 between the point and this bounding box. 00167 Parameters: 00168 P - [in] 00169 Returns: 00170 A distance that is greater than or equal to the 00171 longest distance from the point P to this bounding box. 00172 Put another way, if Q is any point in this bounding box, 00173 then P.DistanceTo(Q) <= MaximumDistanceTo(bbox). 00174 */ 00175 double MaximumDistanceTo( const ON_3dPoint& P ) const; 00176 00177 00178 /* 00179 Description: 00180 Quickly find a lower bound on the distance 00181 between this and the other bounding box. 00182 Parameters: 00183 other - [in] 00184 Returns: 00185 A distance that is less than or equal to the shortest 00186 distance between the bounding boxes. 00187 Put another way, if Q is any point in this bounding box 00188 and P is any point in the other bounding box, 00189 then P.DistanceTo(Q) >= MinimumDistanceTo(bbox). 00190 */ 00191 double MinimumDistanceTo( const ON_BoundingBox& other ) const; 00192 00193 /* 00194 Description: 00195 Quickly find an upper bound on the distance 00196 between this and the other bounding box. 00197 Parameters: 00198 other - [in] 00199 Returns: 00200 A distance that is greater than or equal to the longest 00201 distance between the bounding boxes. 00202 Put another way, if Q is any point in this bounding box 00203 and P is any point in the other bounding box, 00204 then P.DistanceTo(Q) <= MaximumDistanceTo(bbox). 00205 */ 00206 double MaximumDistanceTo( const ON_BoundingBox& other ) const; 00207 00208 /* 00209 Description: 00210 Quickly find a lower bound on the distance 00211 between the line segment and this bounding box. 00212 Parameters: 00213 line - [in] 00214 Returns: 00215 A distance that is less than or equal to the shortest 00216 distance from the line to this bounding box. 00217 Put another way, if Q is any point on line 00218 and P is any point in this bounding box, then 00219 P.DistanceTo(Q) >= MinimumDistanceTo(bbox). 00220 */ 00221 double MinimumDistanceTo( const ON_Line& line ) const; 00222 00223 /* 00224 Description: 00225 Quickly find a tight lower bound on the distance 00226 between the plane and this bounding box. 00227 Parameters: 00228 plane - [in] 00229 Returns: 00230 The minimum distance between a point on the plane 00231 and a point on the bounding box. 00232 See Also: 00233 ON_PlaneEquation::MimimumValueAt 00234 ON_PlaneEquation::MaximumValueAt 00235 */ 00236 double MinimumDistanceTo( const ON_Plane& plane ) const; 00237 double MinimumDistanceTo( const ON_PlaneEquation& plane_equation ) const; 00238 00239 /* 00240 Description: 00241 Quickly find an upper bound on the distance 00242 between the line segment and this bounding box. 00243 Parameters: 00244 line - [in] 00245 Returns: 00246 A distance that is greater than or equal to the 00247 longest distance from the line to this bounding box. 00248 Put another way, if Q is any point on the line 00249 and P is any point in this bounding box, then 00250 P.DistanceTo(Q) <= MaximumDistanceTo(bbox). 00251 */ 00252 double MaximumDistanceTo( const ON_Line& line ) const; 00253 00254 /* 00255 Description: 00256 Quickly find a tight upper bound on the distance 00257 between the plane and this bounding box. 00258 Parameters: 00259 plane - [in] 00260 Returns: 00261 A distance that is equal to the longest distance from 00262 the plane to this bounding box. Put another way, 00263 if Q is any point on the plane and P is any point 00264 in this bounding box, then 00265 P.DistanceTo(Q) <= MaximumDistanceTo(bbox) and there 00266 is at least one point on the bounding box where the 00267 distance is equal to the returned value. 00268 See Also: 00269 ON_PlaneEquation::MaximumValueAt 00270 */ 00271 double MaximumDistanceTo( const ON_Plane& plane ) const; 00272 double MaximumDistanceTo( const ON_PlaneEquation& plane_equation ) const; 00273 00274 00275 /* 00276 Description: 00277 Quickly determine if the shortest distance from 00278 the point P to the bounding box is greater than d. 00279 Parameters: 00280 d - [in] distance (> 0.0) 00281 P - [in] 00282 Returns: 00283 True if if the shortest distance from the point P 00284 to the bounding box is greater than d. 00285 */ 00286 bool IsFartherThan( double d, const ON_3dPoint& P ) const; 00287 00288 /* 00289 Description: 00290 Quickly determine if the shortest distance from the line 00291 to the bounding box is greater than d. 00292 Parameters: 00293 d - [in] distance (> 0.0) 00294 line - [in] 00295 Returns: 00296 True if the shortest distance from the line 00297 to the bounding box is greater than d. It is not the 00298 case that false means that the shortest distance 00299 is less than or equal to d. 00300 */ 00301 bool IsFartherThan( double d, const ON_Line& line ) const; 00302 00303 /* 00304 Description: 00305 Quickly determine if the shortest distance from the plane 00306 to the bounding box is greater than d. 00307 Parameters: 00308 d - [in] distance (> 0.0) 00309 plane - [in] 00310 Returns: 00311 True if the shortest distance from the plane 00312 to the bounding box is greater than d, and false 00313 if the shortest distance is less than or equal to d. 00314 */ 00315 bool IsFartherThan( double d, const ON_Plane& plane ) const; 00316 00317 /* 00318 Description: 00319 Quickly determine if the shortest distance from the plane 00320 to the bounding box is greater than d. 00321 Parameters: 00322 d - [in] distance (> 0.0) 00323 plane_equation - [in] (the first three coefficients 00324 are assumed to be a unit vector. 00325 If not, adjust your d accordingly.) 00326 Returns: 00327 True if the shortest distance from the plane 00328 to the bounding box is greater than d, and false 00329 if the shortest distance is less than or equal to d. 00330 */ 00331 bool IsFartherThan( double d, const ON_PlaneEquation& plane_equation ) const; 00332 00333 /* 00334 Description: 00335 Quickly determine if the shortest distance this bounding 00336 box to another bounding box is greater than d. 00337 Parameters: 00338 d - [in] distance (> 0.0) 00339 other - [in] other bounding box 00340 Returns: 00341 True if if the shortest distance from this bounding 00342 box to the other bounding box is greater than d. 00343 */ 00344 bool IsFartherThan( double d, const ON_BoundingBox& other ) const; 00345 00346 00347 // Description: 00348 // Get point in a bounding box that is closest to a line 00349 // segment. 00350 // Parameters: 00351 // line - [in] line segment 00352 // box_point - [out] point in box that is closest to line 00353 // segment point at t0. 00354 // t0 - [out] parameter of point on line that is closest to 00355 // the box. 00356 // t1 - [out] parameter of point on line that is closest to 00357 // the box. 00358 // Returns: 00359 // 3 success - line segments intersects box in a segment 00360 // from line(t0) to line(t1) (t0 < t1) 00361 // 2 success - line segments intersects box in a single point 00362 // at line(t0) (t0==t1) 00363 // 1 success - line segment does not intersect box. Closest 00364 // point on the line is at line(t0) (t0==t1) 00365 // 0 failure - box is invalid. 00366 // Remarks: 00367 // The box is treated as a solid box. If the intersection 00368 // of the line segment, then 3 is returned. 00369 int GetClosestPoint( 00370 const ON_Line&, // line 00371 ON_3dPoint&, // box_point 00372 double*, // t0 00373 double* // t1 00374 ) const; 00375 00377 // Get points on bounding boxes that are closest to each other. 00378 // If the boxes intersect, then the point at the centroid of the 00379 // intersection is returned for both points. 00380 bool GetClosestPoint( 00381 const ON_BoundingBox&, // "other" bounding box 00382 ON_3dPoint&, // point on "this" box that is closest to "other" box 00383 ON_3dPoint& // point on "other" box that is closest to "this" box 00384 ) const; 00385 00387 // Point on the box that is farthest from the test_point. 00388 ON_3dPoint FarPoint( 00389 const ON_3dPoint& // test_point 00390 ) const; 00391 00393 // Get points on bounding boxes that are farthest from each other. 00394 bool GetFarPoint( 00395 const ON_BoundingBox&, // "other" bounding box 00396 ON_3dPoint&, // point on "this" box that is farthest from "other" box 00397 ON_3dPoint& // point on "other" box that is farthest from "this" box 00398 ) const; 00399 00400 /* 00401 Description: 00402 Intersect this with other_bbox and save intersection in this. 00403 Parameters: 00404 other_bbox - [in] 00405 Returns: 00406 True if this-intesect-other_bbox is a non-empty valid bounding box 00407 and this is set. False if the intersection is empty, in which case 00408 "this" is set to an invalid bounding box. 00409 Remarks: 00410 If "this" or other_bbox is invalid, they are treated as 00411 the empty set, and false is returned. 00412 */ 00413 bool Intersection( 00414 const ON_BoundingBox& other_bbox 00415 ); 00416 00417 /* 00418 Description: 00419 Set "this" to the intersection of bbox_A and bbox_B. 00420 Parameters: 00421 bbox_A - [in] 00422 bbox_B - [in] 00423 Returns: 00424 True if the "this" is a non-empty valid bounding box. 00425 False if the intersection is empty, in which case 00426 "this" is set to an invalid bounding box. 00427 Remarks: 00428 If bbox_A or bbox_B is invalid, they are treated as 00429 the empty set, and false is returned. 00430 */ 00431 bool Intersection( // this = intersection of two args 00432 const ON_BoundingBox& bbox_A, 00433 const ON_BoundingBox& bbox_B 00434 ); 00435 00436 bool Intersection( //Returns true when intersect is non-empty. 00437 const ON_Line&, //Infinite Line segment to intersect with 00438 double* =NULL , // t0 parameter of first intersection point 00439 double* =NULL // t1 parameter of last intersection point (t0<=t1) 00440 ) const; 00441 00442 /* 00443 Description: 00444 Test a box to see if it is contained in this box. 00445 Parameters: 00446 other - [in] box to test 00447 bProperSubSet - [in] if true, then the test is for a proper inclusion. 00448 Returns: 00449 If bProperSubSet is false, then the result is true when 00450 this->m_min[i] <= other.m_min[i] and other.m_max[i] <= this->m_max[i]. 00451 for i=0,1 and 2. 00452 If bProperSubSet is true, then the result is true when 00453 the above condition is true and at least one of the inequalities is strict. 00454 */ 00455 bool Includes( 00456 const ON_BoundingBox& other, 00457 bool bProperSubSet = false 00458 ) const; 00459 00460 double Volume() const; 00461 00462 double Area() const; 00463 00464 // Union() returns true if union is not empty. 00465 // Invalid boxes are treated as the empty set. 00466 bool Union( // this = this union arg 00467 const ON_BoundingBox& 00468 ); 00469 00470 bool Union( // this = union of two args 00471 const ON_BoundingBox&, 00472 const ON_BoundingBox& 00473 ); 00474 00475 /* 00476 Description: 00477 Test to see if "this" and other_bbox are disjoint (do not intersect). 00478 Parameters: 00479 other_bbox - [in] 00480 Returns: 00481 True if "this" and other_bbox are disjoint. 00482 Remarks: 00483 If "this" or other_bbox is invalid, then true is returned. 00484 */ 00485 bool IsDisjoint( 00486 const ON_BoundingBox& other_bbox 00487 ) const; 00488 00489 bool SwapCoordinates( int, int ); 00490 00491 ON_3dPoint m_min; 00492 ON_3dPoint m_max; 00493 }; 00494 00495 #if defined(ON_DLL_TEMPLATE) 00496 00497 // This stuff is here because of a limitation in the way Microsoft 00498 // handles templates and DLLs. See Microsoft's knowledge base 00499 // article ID Q168958 for details. 00500 #pragma warning( push ) 00501 #pragma warning( disable : 4231 ) 00502 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_BoundingBox>; 00503 #pragma warning( pop ) 00504 00505 #endif 00506 00507 /* 00508 Description: 00509 Get a tight bounding box that contains the points. 00510 Parameters: 00511 dim - [in] (>=1) 00512 is_rat - [in] true if points are rational 00513 count - [in] number of points 00514 stride - [in] stride between points 00515 point_list - [in] 00516 bbox - [in/out] 00517 bGrowBox - [in] (default = false) 00518 If the input bbox is valid and bGrowBox is true, 00519 then the output bbox is the union of the input 00520 bbox and the bounding box of the point list. 00521 xform - [in] (default = NULL) 00522 If not null, the bounding box of the transformed 00523 points is calculated. The points are not modified. 00524 Returns: 00525 True if the output bbox is valid. 00526 */ 00527 ON_DECL 00528 bool ON_GetPointListBoundingBox( 00529 int dim, 00530 int is_rat, 00531 int count, 00532 int stride, 00533 const double* point_list, 00534 ON_BoundingBox& bbox, 00535 int bGrowBox = false, 00536 const ON_Xform* xform = 0 00537 ); 00538 00539 ON_DECL 00540 bool ON_GetPointListBoundingBox( 00541 int dim, 00542 int is_rat, 00543 int count, 00544 int stride, 00545 const float* point_list, 00546 ON_BoundingBox& bbox, 00547 int bGrowBox = false, 00548 const ON_Xform* xform = 0 00549 ); 00550 00551 ON_DECL 00552 bool ON_GetPointListBoundingBox( 00553 int dim, 00554 int is_rat, 00555 int count, 00556 int stride, 00557 const double* point_list, 00558 double* boxmin, // min[dim] 00559 double* boxmax, // max[dim] 00560 int bGrowBox 00561 ); 00562 00563 ON_DECL 00564 ON_BoundingBox ON_PointListBoundingBox( 00565 int dim, 00566 int is_rat, 00567 int count, 00568 int stride, 00569 const double* point_list 00570 ); 00571 00572 ON_DECL 00573 bool ON_GetPointListBoundingBox( 00574 int dim, 00575 int is_rat, 00576 int count, 00577 int stride, 00578 const float* point_list, 00579 float* boxmin, // min[dim] 00580 float* boxmax, // max[dim] 00581 int bGrowBox 00582 ); 00583 00584 ON_DECL 00585 ON_BoundingBox ON_PointListBoundingBox( // low level workhorse function 00586 int dim, 00587 int is_rat, 00588 int count, 00589 int stride, 00590 const float* point_list 00591 ); 00592 00593 ON_DECL 00594 bool ON_GetPointGridBoundingBox( 00595 int dim, 00596 int is_rat, 00597 int point_count0, int point_count1, 00598 int point_stride0, int point_stride1, 00599 const double* point_grid, 00600 double* boxmin, // min[dim] 00601 double* boxmax, // max[dim] 00602 int bGrowBox 00603 ); 00604 00605 ON_DECL 00606 ON_BoundingBox ON_PointGridBoundingBox( 00607 int dim, 00608 int is_rat, 00609 int point_count0, int point_count1, 00610 int point_stride0, int point_stride1, 00611 const double* point_grid 00612 ); 00613 00614 ON_DECL 00615 double ON_BoundingBoxTolerance( 00616 int dim, 00617 const double* bboxmin, 00618 const double* bboxmax 00619 ); 00620 00621 /* 00622 Description: 00623 Determine if an object is too large or too far 00624 from the origin for single precision coordinates 00625 to be useful. 00626 Parameters: 00627 bbox - [in] 00628 Bounding box of an object with single precision 00629 coordinates. An ON_Mesh is an example of an 00630 object with single precision coordinates. 00631 xform - [out] 00632 If this function returns false and xform is not 00633 null, then the identity transform is returned. 00634 If this function returns true and xform is not 00635 null, then the transform moves the region 00636 contained in bbox to a location where single 00637 precision coordinates will have enough 00638 information for the object to be useful. 00639 Returns: 00640 true: 00641 The region contained in bbox is too large 00642 or too far from the origin for single 00643 precision coordinates to be useful. 00644 false: 00645 A single precision object contained in bbox 00646 will be satisfactory for common calculations. 00647 */ 00648 ON_DECL 00649 bool ON_BeyondSinglePrecision( const ON_BoundingBox& bbox, ON_Xform* xform ); 00650 00651 ON_DECL 00652 bool ON_WorldBBoxIsInTightBBox( 00653 const ON_BoundingBox& tight_bbox, 00654 const ON_BoundingBox& world_bbox, 00655 const ON_Xform* xform 00656 ); 00657 00658 #endif