在某些角度,这将显示错误一侧的交叉点(当它应该是正面时返回,或者当它应该是正确时返回)。
有什么问题?
inline bool GetIntersection(f32 fDst1, f32 fDst2,
vector3df P1, vector3df P2, vector3df &Hit) {
if ( (fDst1 * fDst2) >= 0.0f)
return 0;
if ( fDst1 == fDst2)
return 0;
Hit = P1 + (P2-P1) * ( -fDst1/(fDst2-fDst1) );
return 1;
}
inline bool InBox(vector3df Hit, vector3df B1, vector3df B2, const int AXis) {
if ( AXis==1 && Hit.Z > B1.Z &&
Hit.Z < B2.Z && Hit.Y > B1.Y && Hit.Y < B2.Y)
return 1;
if ( AXis==2 && Hit.Z > B1.Z &&
Hit.Z < B2.Z && Hit.X > B1.X && Hit.X < B2.X)
return 1;
if ( AXis==3 && Hit.X > B1.X && Hit.X < B2.X &&
Hit.Y > B1.Y && Hit.Y < B2.Y)
return 1;
return 0;
}
// returns true if line (L1, L2) intersects with the boX (B1, B2)
// returns intersection point in Hit
bool CheckLineBox( vector3df B1, vector3df B2,
vector3df L1, vector3df L2, vector3df &Hit) {
if (L2.X < B1.X && L1.X < B1.X) return false;
if (L2.X > B2.X && L1.X > B2.X) return false;
if (L2.Y < B1.Y && L1.Y < B1.Y) return false;
if (L2.Y > B2.Y && L1.Y > B2.Y) return false;
if (L2.Z < B1.Z && L1.Z < B1.Z) return false;
if (L2.Z > B2.Z && L1.Z > B2.Z) return false;
if (L1.X > B1.X && L1.X < B2.X &&
L1.Y > B1.Y && L1.Y < B2.Y &&
L1.Z > B1.Z && L1.Z < B2.Z) {
Hit = L1;
return true;
}
if ((GetIntersection( L1.X-B1.X, L2.X-B1.X, L1, L2, Hit) &&
InBox(Hit, B1, B2, 1)) ||
(GetIntersection( L1.Y-B1.Y, L2.Y-B1.Y, L1, L2, Hit) &&
InBox(Hit, B1, B2, 2)) ||
(GetIntersection( L1.Z-B1.Z, L2.Z-B1.Z, L1, L2, Hit) &&
InBox(Hit, B1, B2, 3)) ||
(GetIntersection( L1.X-B2.X, L2.X-B2.X, L1, L2, Hit) &&
InBox(Hit, B1, B2, 1)) ||
(GetIntersection( L1.Y-B2.Y, L2.Y-B2.Y, L1, L2, Hit) &&
InBox(Hit, B1, B2, 2)) ||
(GetIntersection( L1.Z-B2.Z, L2.Z-B2.Z, L1, L2, Hit) &&
InBox(Hit, B1, B2, 3)))
return true;
return false;
}
答案 0 :(得分:2)
这与浮点精度问题有关。如果你想要一个稳定的算法,你不能使用==来比较浮点数。以下是禁止的:
if ( fDst1 == fDst2)
return 0;
你需要做的是用下面的feq()替换所有这些==比较:
static const double cEpsilon = 1e-5;
bool feq(double lhs, double rhs)
{
return (fabs(lhs - rhs) < cEpsilon);
}
使用此功能(如果不喜欢功能开销,也可以将其创建为#define),可以添加cEpsilon(此精度也可以更改,具体取决于您和您的问题定义为关闭)其他运营商的功能。以下是&lt;操作者:
bool lessThan(double lhs, double rhs)
{
return (lhs < rhs && !feq(lhs, rhs));
}
浏览您的代码并替换==和&lt;用这些方法。你真的不需要&gt;运算符,因为您可以转换参数并使用&lt;代替。
干杯