叶子的小屋
线段 矩形 碰撞检测
2015-11-13 admin
template <class Real>
bool IntrLine2Box2<Real>::Clip (Real fDenom, Real fNumer, Real& rfT0,
Real& rfT1)
{
// Return value is 'true' if line segment intersects the current test
// plane. Otherwise 'false' is returned in which case the line segment
// is entirely clipped.
if (fDenom > (Real)0.0)
{
if (fNumer > fDenom*rfT1)
{
return false;
}
if (fNumer > fDenom*rfT0)
{
rfT0 = fNumer/fDenom;
}
return true;
}
else if (fDenom < (Real)0.0)
{
if (fNumer > fDenom*rfT0)
{
return false;
}
if (fNumer > fDenom*rfT1)
{
rfT1 = fNumer/fDenom;
}
return true;
}
else
{
return fNumer <= (Real)0.0;
}
}
//////////////////////////////////////////////////////////////////
template <class Real>
bool IntrLine2Box2<Real>::DoClipping (Real fT0, Real fT1,
const Vector2<Real>& rkOrigin, const Vector2<Real>& rkDirection,
const Box2<Real>& rkBox, bool bSolid, int& riQuantity,
Vector2<Real> akPoint[2], int& riIntrType)
{
assert(fT0 < fT1);
// convert linear component to box coordinates
Vector2<Real> kDiff = rkOrigin - rkBox.Center;
Vector2<Real> kBOrigin(
kDiff.Dot(rkBox.Axis[0]),
kDiff.Dot(rkBox.Axis[1])
);
Vector2<Real> kBDirection(
rkDirection.Dot(rkBox.Axis[0]),
rkDirection.Dot(rkBox.Axis[1])
);
Real fSaveT0 = fT0, fSaveT1 = fT1;
bool bNotAllClipped =
Clip(+kBDirection.X(),-kBOrigin.X()-rkBox.Extent[0],fT0,fT1) &&
Clip(-kBDirection.X(),+kBOrigin.X()-rkBox.Extent[0],fT0,fT1) &&
Clip(+kBDirection.Y(),-kBOrigin.Y()-rkBox.Extent[1],fT0,fT1) &&
Clip(-kBDirection.Y(),+kBOrigin.Y()-rkBox.Extent[1],fT0,fT1);
if (bNotAllClipped && (bSolid || fT0 != fSaveT0 || fT1 != fSaveT1))
{
if (fT1 > fT0)
{
riIntrType = IT_SEGMENT;
riQuantity = 2;
akPoint[0] = rkOrigin + fT0*rkDirection;
akPoint[1] = rkOrigin + fT1*rkDirection;
}
else
{
riIntrType = IT_POINT;
riQuantity = 1;
akPoint[0] = rkOrigin + fT0*rkDirection;
}
}
else
{
riIntrType = IT_EMPTY;
riQuantity = 0;
}
return riIntrType != IT_EMPTY;
}










调用DoClipping()即可获得交点坐标



代码来自开源引擎WildMagic4p9\GeometricTools\WildMagic4\LibFoundation\Intersection\Wm4IntrLine2Box2.cpp