00001 // Magic Software, Inc. 00002 // http://www.magic-software.com 00003 // Copyright (c) 2000, All Rights Reserved 00004 // 00005 // Source code from Magic Software is supplied under the terms of a license 00006 // agreement and may not be copied or disclosed except in accordance with the 00007 // terms of that agreement. The various license agreements may be found at 00008 // the Magic Software web site. This file is subject to the license 00009 // 00010 // FREE SOURCE CODE 00011 // http://www.magic-software.com/License.html/free.pdf 00012 00013 #include "MgcContBox.h" 00014 #include "MgcGaussPointsFit.h" 00015 //#include "MgcQuaternion.h" 00016 00017 //---------------------------------------------------------------------------- 00018 /*void MgcContAlignedBox (int iQuantity, const MgcVector2* akPoint, 00019 MgcVector2& rkMin, MgcVector2& rkMax) 00020 { 00021 rkMin = akPoint[0]; 00022 rkMax = rkMin; 00023 00024 for (int i = 1; i < iQuantity; i++) 00025 { 00026 if ( akPoint[i].x < rkMin.x ) 00027 rkMin.x = akPoint[i].x; 00028 else if ( akPoint[i].x > rkMax.x ) 00029 rkMax.x = akPoint[i].x; 00030 00031 if ( akPoint[i].y < rkMin.y ) 00032 rkMin.y = akPoint[i].y; 00033 else if ( akPoint[i].y > rkMax.y ) 00034 rkMax.y = akPoint[i].y; 00035 } 00036 }*/ 00037 //---------------------------------------------------------------------------- 00038 void MgcContAlignedBox (int iQuantity, const MgcVector3* akPoint, 00039 MgcVector3& rkMin, MgcVector3& rkMax) 00040 { 00041 rkMin = akPoint[0]; 00042 rkMax = rkMin; 00043 00044 for (int i = 1; i < iQuantity; i++) 00045 { 00046 if ( akPoint[i].x < rkMin.x ) 00047 rkMin.x = akPoint[i].x; 00048 else if ( akPoint[i].x > rkMax.x ) 00049 rkMax.x = akPoint[i].x; 00050 00051 if ( akPoint[i].y < rkMin.y ) 00052 rkMin.y = akPoint[i].y; 00053 else if ( akPoint[i].y > rkMax.y ) 00054 rkMax.y = akPoint[i].y; 00055 00056 if ( akPoint[i].z < rkMin.z ) 00057 rkMin.z = akPoint[i].z; 00058 else if ( akPoint[i].z > rkMax.z ) 00059 rkMax.z = akPoint[i].z; 00060 } 00061 } 00062 //---------------------------------------------------------------------------- 00063 /*MgcBox2 MgcContOrientedBox (int iQuantity, const MgcVector2* akPoint) 00064 { 00065 MgcBox2 kBox; 00066 00067 MgcGaussPointsFit(iQuantity,akPoint,kBox.Center(),kBox.Axes(), 00068 kBox.Extents()); 00069 00070 // Let C be the box center and let U0 and U1 be the box axes. Each input 00071 // point is of the form X = C + y0*U0 + y1*U1. The following code 00072 // computes min(y0), max(y0), min(y1), and max(y1). The box center is 00073 // then adjusted to be 00074 // C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 00075 00076 MgcVector2 kDiff = akPoint[0] - kBox.Center(); 00077 MgcReal fY0Min = kDiff.Dot(kBox.Axis(0)), fY0Max = fY0Min; 00078 MgcReal fY1Min = kDiff.Dot(kBox.Axis(1)), fY1Max = fY1Min; 00079 00080 for (int i = 1; i < iQuantity; i++) 00081 { 00082 kDiff = akPoint[i] - kBox.Center(); 00083 00084 MgcReal fY0 = kDiff.Dot(kBox.Axis(0)); 00085 if ( fY0 < fY0Min ) 00086 fY0Min = fY0; 00087 else if ( fY0 > fY0Max ) 00088 fY0Max = fY0; 00089 00090 MgcReal fY1 = kDiff.Dot(kBox.Axis(1)); 00091 if ( fY1 < fY1Min ) 00092 fY1Min = fY1; 00093 else if ( fY1 > fY1Max ) 00094 fY1Max = fY1; 00095 } 00096 00097 kBox.Center() += (0.5*(fY0Min+fY0Max))*kBox.Axis(0) + 00098 (0.5*(fY1Min+fY1Max))*kBox.Axis(1); 00099 00100 kBox.Extent(0) = 0.5*(fY0Max - fY0Min); 00101 kBox.Extent(1) = 0.5*(fY1Max - fY1Min); 00102 00103 return kBox; 00104 }*/ 00105 //---------------------------------------------------------------------------- 00106 MgcBox3 MgcContOrientedBox (int iQuantity, const MgcVector3* akPoint) 00107 { 00108 MgcBox3 kBox; 00109 00110 MgcGaussPointsFit(iQuantity,akPoint,kBox.Center(),kBox.Axes(), 00111 kBox.Extents()); 00112 00113 // Let C be the box center and let U0, U1, and U2 be the box axes. Each 00114 // input point is of the form X = C + y0*U0 + y1*U1 + y2*U2. The 00115 // following code computes min(y0), max(y0), min(y1), max(y1), min(y2), 00116 // and max(y2). The box center is then adjusted to be 00117 // C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 + 00118 // 0.5*(min(y2)+max(y2))*U2 00119 00120 MgcVector3 kDiff = akPoint[0] - kBox.Center(); 00121 MgcReal fY0Min = kDiff.Dot(kBox.Axis(0)), fY0Max = fY0Min; 00122 MgcReal fY1Min = kDiff.Dot(kBox.Axis(1)), fY1Max = fY1Min; 00123 MgcReal fY2Min = kDiff.Dot(kBox.Axis(2)), fY2Max = fY2Min; 00124 00125 for (int i = 1; i < iQuantity; i++) 00126 { 00127 kDiff = akPoint[i] - kBox.Center(); 00128 00129 MgcReal fY0 = kDiff.Dot(kBox.Axis(0)); 00130 if ( fY0 < fY0Min ) 00131 fY0Min = fY0; 00132 else if ( fY0 > fY0Max ) 00133 fY0Max = fY0; 00134 00135 MgcReal fY1 = kDiff.Dot(kBox.Axis(1)); 00136 if ( fY1 < fY1Min ) 00137 fY1Min = fY1; 00138 else if ( fY1 > fY1Max ) 00139 fY1Max = fY1; 00140 00141 MgcReal fY2 = kDiff.Dot(kBox.Axis(2)); 00142 if ( fY2 < fY2Min ) 00143 fY2Min = fY2; 00144 else if ( fY2 > fY2Max ) 00145 fY2Max = fY2; 00146 } 00147 00148 kBox.Center() += (0.5*(fY0Min+fY0Max))*kBox.Axis(0) + 00149 (0.5*(fY1Min+fY1Max))*kBox.Axis(1) + 00150 (0.5*(fY2Min+fY2Max))*kBox.Axis(2); 00151 00152 kBox.Extent(0) = 0.5*(fY0Max - fY0Min); 00153 kBox.Extent(1) = 0.5*(fY1Max - fY1Min); 00154 kBox.Extent(2) = 0.5*(fY2Max - fY2Min); 00155 00156 return kBox; 00157 } 00158 //---------------------------------------------------------------------------- 00159 /*bool MgcContOrientedBox (int iQuantity, const MgcVector2* akPoint, 00160 const bool* abValid, MgcBox2& rkBox) 00161 { 00162 if ( !MgcGaussPointsFit(iQuantity,akPoint,abValid,rkBox.Center(), 00163 rkBox.Axes(),rkBox.Extents()) ) 00164 { 00165 return false; 00166 } 00167 00168 // Let C be the box center and let U0 and U1 be the box axes. Each input 00169 // point is of the form X = C + y0*U0 + y1*U1. The following code 00170 // computes min(y0), max(y0), min(y1), and max(y1). The box center is 00171 // then adjusted to be 00172 // C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 00173 00174 // get first valid vertex 00175 MgcVector2 kDiff; 00176 MgcReal fY0Min, fY0Max, fY1Min, fY1Max; 00177 int i; 00178 for (i = 0; i < iQuantity; i++) 00179 { 00180 if ( abValid[i] ) 00181 { 00182 kDiff = akPoint[i] - rkBox.Center(); 00183 fY0Min = kDiff.Dot(rkBox.Axis(0)); 00184 fY0Max = fY0Min; 00185 fY1Min = kDiff.Dot(rkBox.Axis(1)); 00186 fY1Max = fY1Min; 00187 break; 00188 } 00189 } 00190 00191 for (i++; i < iQuantity; i++) 00192 { 00193 if ( abValid[i] ) 00194 { 00195 kDiff = akPoint[i] - rkBox.Center(); 00196 00197 MgcReal fY0 = kDiff.Dot(rkBox.Axis(0)); 00198 if ( fY0 < fY0Min ) 00199 fY0Min = fY0; 00200 else if ( fY0 > fY0Max ) 00201 fY0Max = fY0; 00202 00203 MgcReal fY1 = kDiff.Dot(rkBox.Axis(1)); 00204 if ( fY1 < fY1Min ) 00205 fY1Min = fY1; 00206 else if ( fY1 > fY1Max ) 00207 fY1Max = fY1; 00208 } 00209 } 00210 00211 rkBox.Center() += (0.5*(fY0Min+fY0Max))*rkBox.Axis(0) 00212 + (0.5*(fY1Min+fY1Max))*rkBox.Axis(1); 00213 00214 rkBox.Extent(0) = 0.5*(fY0Max - fY0Min); 00215 rkBox.Extent(1) = 0.5*(fY1Max - fY1Min); 00216 00217 return true; 00218 }*/ 00219 //---------------------------------------------------------------------------- 00220 /*bool MgcContOrientedBox (int iQuantity, const MgcVector3* akPoint, 00221 const bool* abValid, MgcBox3& rkBox) 00222 { 00223 if ( !MgcGaussPointsFit(iQuantity,akPoint,abValid,rkBox.Center(), 00224 rkBox.Axes(),rkBox.Extents()) ) 00225 { 00226 return false; 00227 } 00228 00229 // Let C be the box center and let U0, U1, and U2 be the box axes. Each 00230 // input point is of the form X = C + y0*U0 + y1*U1 + y2*U2. The 00231 // following code computes min(y0), max(y0), min(y1), max(y1), min(y2), 00232 // and max(y2). The box center is then adjusted to be 00233 // C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 + 00234 // 0.5*(min(y2)+max(y2))*U2 00235 00236 // get first valid vertex 00237 MgcVector3 kDiff; 00238 MgcReal fY0Min, fY0Max, fY1Min, fY1Max, fY2Min, fY2Max; 00239 int i; 00240 for (i = 0; i < iQuantity; i++) 00241 { 00242 if ( abValid[i] ) 00243 { 00244 kDiff = akPoint[i] - rkBox.Center(); 00245 fY0Min = kDiff.Dot(rkBox.Axis(0)); 00246 fY0Max = fY0Min; 00247 fY1Min = kDiff.Dot(rkBox.Axis(1)); 00248 fY1Max = fY1Min; 00249 fY2Min = kDiff.Dot(rkBox.Axis(2)); 00250 fY2Max = fY2Min; 00251 break; 00252 } 00253 } 00254 00255 for (i++; i < iQuantity; i++) 00256 { 00257 if ( abValid[i] ) 00258 { 00259 kDiff = akPoint[i] - rkBox.Center(); 00260 00261 MgcReal fY0 = kDiff.Dot(rkBox.Axis(0)); 00262 if ( fY0 < fY0Min ) 00263 fY0Min = fY0; 00264 else if ( fY0 > fY0Max ) 00265 fY0Max = fY0; 00266 00267 MgcReal fY1 = kDiff.Dot(rkBox.Axis(1)); 00268 if ( fY1 < fY1Min ) 00269 fY1Min = fY1; 00270 else if ( fY1 > fY1Max ) 00271 fY1Max = fY1; 00272 00273 MgcReal fY2 = kDiff.Dot(rkBox.Axis(2)); 00274 if ( fY2 < fY2Min ) 00275 fY2Min = fY2; 00276 else if ( fY2 > fY2Max ) 00277 fY2Max = fY2; 00278 } 00279 } 00280 00281 rkBox.Center() += (0.5*(fY0Min+fY0Max))*rkBox.Axis(0) 00282 + (0.5*(fY1Min+fY1Max))*rkBox.Axis(1) + 00283 (0.5*(fY2Min+fY2Max))*rkBox.Axis(2); 00284 00285 rkBox.Extent(0) = 0.5*(fY0Max - fY0Min); 00286 rkBox.Extent(1) = 0.5*(fY1Max - fY1Min); 00287 rkBox.Extent(2) = 0.5*(fY2Max - fY2Min); 00288 00289 return true; 00290 } 00291 //---------------------------------------------------------------------------- 00292 MgcBox3 MgcMergeBoxes (const MgcBox3& rkBox0, const MgcBox3& rkBox1) 00293 { 00294 MgcBox3 kBox; 00295 kBox.Center() = 0.5*(rkBox0.Center() + rkBox1.Center()); 00296 00297 MgcQuaternion kQ0, kQ1; 00298 kQ0.FromAxes(rkBox0.Axes()); 00299 kQ1.FromAxes(rkBox1.Axes()); 00300 if ( kQ0.Dot(kQ1) < 0.0 ) 00301 kQ1 = -kQ1; 00302 00303 MgcQuaternion kQ = kQ0 + kQ1; 00304 MgcReal fInvLength = 1.0/MgcMath::Sqrt(kQ.Norm()); 00305 kQ = fInvLength*kQ; 00306 kQ.ToAxes(kBox.Axes()); 00307 00308 int i, j; 00309 MgcVector3 akVertex[8], kDiff; 00310 MgcReal fADot; 00311 00312 kBox.Extent(0) = 0.0; 00313 kBox.Extent(1) = 0.0; 00314 kBox.Extent(2) = 0.0; 00315 00316 rkBox0.ComputeVertices(akVertex); 00317 for (i = 0; i < 8; i++) 00318 { 00319 kDiff = akVertex[i] - kBox.Center(); 00320 for (j = 0; j < 3; j++) 00321 { 00322 fADot = MgcMath::Abs(kDiff.Dot(rkBox0.Axis(j))); 00323 if ( fADot > kBox.Extent(j) ) 00324 kBox.Extent(j) = fADot; 00325 } 00326 } 00327 00328 rkBox1.ComputeVertices(akVertex); 00329 for (i = 0; i < 8; i++) 00330 { 00331 kDiff = akVertex[i] - kBox.Center(); 00332 for (j = 0; j < 3; j++) 00333 { 00334 fADot = MgcMath::Abs(kDiff.Dot(rkBox1.Axis(j))); 00335 if ( fADot > kBox.Extent(j) ) 00336 kBox.Extent(j) = fADot; 00337 } 00338 } 00339 00340 return kBox; 00341 }*/ 00342 //----------------------------------------------------------------------------