|
请教一个问题,实时碰撞检测算法技术一书中,用面积求两线段交点,求告之参数 t 的推导过程
// Test if segments ab and cd overlap. If they do, compute and return
// intersection t value along ab and intersection position p
int Test2DSegmentSegment(Point a, Point b, Point c, Point d, float &t, Point &p)
{
// Sign of areas correspond to which side of ab points c and d are
float a1 = Signed2DTriArea(a, b, d); // Compute winding of abd (+ or -)
float a2 = Signed2DTriArea(a, b, c); // To intersect, must have sign opposite of a1
// If c and d are on different sides of ab, areas have different signs
if (a1 * a2 < 0.0f)
{
// Compute signs for a and b with respect to segment cd
float a3 = Signed2DTriArea(c, d, a); // Compute winding of cda (+ or -)
// Since area is constant a1 - a2 = a3 - a4, or a4 = a3 + a2 - a1
// float a4 = Signed2DTriArea(c, d, b); // Must have opposite sign of a3
float a4 = a3 + a2 - a1;
// Points a and b on different sides of cd if areas have different signs
if (a3 * a4 < 0.0f)
{
// Segments intersect. Find intersection point along L(t) = a + t * (b - a).
// Given height h1 of a over cd and height h2 of b over cd,
// t = h1 / (h1 - h2) = (b*h1/2) / (b*h1/2 - b*h2/2) = a3 / (a3 - a4),
// where b (the base of the triangles cda and cdb, i.e., the length
// of cd) cancels out.
t = a3 / (a3 - a4);// 此公式是怎么推导出来的?
p = a + t * (b - a);
return 1;
}
}
// Segments not intersecting (or collinear)
return 0;
}
|
|