//---------------------------------------------------------------------------- bool Mgc::ContOrientedBox (int iQuantity, const Vector2* akPoint, const bool* abValid, Box2& rkBox) { if ( !GaussPointsFit(iQuantity,akPoint,abValid,rkBox.Center(), rkBox.Axes(),rkBox.Extents()) ) { return false; } // Let C be the box center and let U0 and U1 be the box axes. Each input // point is of the form X = C + y0*U0 + y1*U1. The following code // computes min(y0), max(y0), min(y1), and max(y1). The box center is // then adjusted to be // C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 // get first valid vertex Vector2 kDiff; Real fY0Min, fY0Max, fY1Min, fY1Max; int i; for (i = 0; i < iQuantity; i++) { if ( abValid[i] ) { kDiff = akPoint[i] - rkBox.Center(); fY0Min = kDiff.Dot(rkBox.Axis(0)); fY0Max = fY0Min; fY1Min = kDiff.Dot(rkBox.Axis(1)); fY1Max = fY1Min; break; } } for (i++; i < iQuantity; i++) { if ( abValid[i] ) { kDiff = akPoint[i] - rkBox.Center(); Real fY0 = kDiff.Dot(rkBox.Axis(0)); if ( fY0 < fY0Min ) fY0Min = fY0; else if ( fY0 > fY0Max ) fY0Max = fY0; Real fY1 = kDiff.Dot(rkBox.Axis(1)); if ( fY1 < fY1Min ) fY1Min = fY1; else if ( fY1 > fY1Max ) fY1Max = fY1; } } rkBox.Center() += (0.5f*(fY0Min+fY0Max))*rkBox.Axis(0) + (0.5f*(fY1Min+fY1Max))*rkBox.Axis(1); rkBox.Extent(0) = 0.5f*(fY0Max - fY0Min); rkBox.Extent(1) = 0.5f*(fY1Max - fY1Min); return true; }
bool Wml::TestIntersection (const Box2<Real>& rkBox0, const Box2<Real>& rkBox1) { // convenience variables const Vector2<Real>* akA = rkBox0.Axes(); const Vector2<Real>* akB = rkBox1.Axes(); const Real* afEA = rkBox0.Extents(); const Real* afEB = rkBox1.Extents(); // compute difference of box centers, D = C1-C0 Vector2<Real> kD = rkBox1.Center() - rkBox0.Center(); Real aafAbsAdB[2][2], fAbsAdD, fRSum; // axis C0+t*A0 aafAbsAdB[0][0] = Math<Real>::FAbs(akA[0].Dot(akB[0])); aafAbsAdB[0][1] = Math<Real>::FAbs(akA[0].Dot(akB[1])); fAbsAdD = Math<Real>::FAbs(akA[0].Dot(kD)); fRSum = afEA[0] + afEB[0]*aafAbsAdB[0][0] + afEB[1]*aafAbsAdB[0][1]; if ( fAbsAdD > fRSum ) return false; // axis C0+t*A1 aafAbsAdB[1][0] = Math<Real>::FAbs(akA[1].Dot(akB[0])); aafAbsAdB[1][1] = Math<Real>::FAbs(akA[1].Dot(akB[1])); fAbsAdD = Math<Real>::FAbs(akA[1].Dot(kD)); fRSum = afEA[1] + afEB[0]*aafAbsAdB[1][0] + afEB[1]*aafAbsAdB[1][1]; if ( fAbsAdD > fRSum ) return false; // axis C0+t*B0 fAbsAdD = Math<Real>::FAbs(akB[0].Dot(kD)); fRSum = afEB[0] + afEA[0]*aafAbsAdB[0][0] + afEA[1]*aafAbsAdB[1][0]; if ( fAbsAdD > fRSum ) return false; // axis C0+t*B1 fAbsAdD = Math<Real>::FAbs(akB[1].Dot(kD)); fRSum = afEB[1] + afEA[0]*aafAbsAdB[0][1] + afEA[1]*aafAbsAdB[1][1]; if ( fAbsAdD > fRSum ) return false; return true; }
//---------------------------------------------------------------------------- Box2 Mgc::ContOrientedBox (int iQuantity, const Vector2* akPoint) { Box2 kBox; GaussPointsFit(iQuantity,akPoint,kBox.Center(),kBox.Axes(), kBox.Extents()); // Let C be the box center and let U0 and U1 be the box axes. Each input // point is of the form X = C + y0*U0 + y1*U1. The following code // computes min(y0), max(y0), min(y1), and max(y1). The box center is // then adjusted to be // C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 Vector2 kDiff = akPoint[0] - kBox.Center(); Real fY0Min = kDiff.Dot(kBox.Axis(0)), fY0Max = fY0Min; Real fY1Min = kDiff.Dot(kBox.Axis(1)), fY1Max = fY1Min; for (int i = 1; i < iQuantity; i++) { kDiff = akPoint[i] - kBox.Center(); Real fY0 = kDiff.Dot(kBox.Axis(0)); if ( fY0 < fY0Min ) fY0Min = fY0; else if ( fY0 > fY0Max ) fY0Max = fY0; Real fY1 = kDiff.Dot(kBox.Axis(1)); if ( fY1 < fY1Min ) fY1Min = fY1; else if ( fY1 > fY1Max ) fY1Max = fY1; } kBox.Center() += (0.5f*(fY0Min+fY0Max))*kBox.Axis(0) + (0.5f*(fY1Min+fY1Max))*kBox.Axis(1); kBox.Extent(0) = 0.5f*(fY0Max - fY0Min); kBox.Extent(1) = 0.5f*(fY1Max - fY1Min); return kBox; }