まず、概略図。
。
例示によれば、線a1は、エンドポイントとA2、B1線bは、エンドポイントとB2を表すを表す。ベクトル外積の関係を利用するために、ベクターとしての株の4つの端部は、ベクターは、太字で以下に示される。ベクトル演算をそれことを見出し
A = A2-A1、
。B = B2-B1
:線分パラメータ方程式は以下のように表される
A = A1 + TA
B = B1 + UB
前記パラメータT、uは[0,1]値
2本の線分の交点には、以下の関係を有する:
A1 = B1 + TA + UB
同時に式bの外積の両側に、精製します:
(A1 + TA)XB =(B1 + UB)XB
BXB = 0、得ることができるので
A1 XB + taxbを= B1 XB
パラメータTについて解く
T =(A1-B1)XB /(AXB)
同様に、パラメータについて解くU
U = AX(A1-B1)/(AXB)
0 <= T <= 1、及び0 <= U <= 1、2つの線分が交点を有する。
線分の交点の座標を取得するために、パラメータ方程式のセグメントを代入:
A1 + TA
することにより、上記式で中間変数を元のセグメントのエンドポイントは、エンドポイントに記載の交点が線分で表すことができると述べました。
コード1
// Returns 1 if the lines intersect, otherwise 0. In addition, if the lines
// intersect the intersection point may be stored in the floats i_x and i_y.
char get_line_intersection(float p0_x, float p0_y, float p1_x, float p1_y,
float p2_x, float p2_y, float p3_x, float p3_y, float *i_x, float *i_y)
{
float s1_x, s1_y, s2_x, s2_y;
s1_x = p1_x - p0_x; s1_y = p1_y - p0_y;
s2_x = p3_x - p2_x; s2_y = p3_y - p2_y;
float s, t;
s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / (-s2_x * s1_y + s1_x * s2_y);
t = ( s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / (-s2_x * s1_y + s1_x * s2_y);
if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
{
// Collision detected
if (i_x != NULL)
*i_x = p0_x + (t * s1_x);
if (i_y != NULL)
*i_y = p0_y + (t * s1_y);
return 1;
}
return 0; // No collision
}
コード2
精度誤差を回避するために、平行線分の場合を除く、バージョンを最適化
int get_line_intersection(float p0_x, float p0_y, float p1_x, float p1_y,
float p2_x, float p2_y, float p3_x, float p3_y, float *i_x, float *i_y)
{
float s02_x, s02_y, s10_x, s10_y, s32_x, s32_y, s_numer, t_numer, denom, t;
s10_x = p1_x - p0_x;
s10_y = p1_y - p0_y;
s32_x = p3_x - p2_x;
s32_y = p3_y - p2_y;
denom = s10_x * s32_y - s32_x * s10_y;
if (denom == 0)//平行或共线
return 0; // Collinear
bool denomPositive = denom > 0;
s02_x = p0_x - p2_x;
s02_y = p0_y - p2_y;
s_numer = s10_x * s02_y - s10_y * s02_x;
if ((s_numer < 0) == denomPositive)//参数是大于等于0且小于等于1的,分子分母必须同号且分子小于等于分母
return 0; // No collision
t_numer = s32_x * s02_y - s32_y * s02_x;
if ((t_numer < 0) == denomPositive)
return 0; // No collision
if (fabs(s_numer) > fabs(denom) || fabs(t_numer) > fabs(denom))
return 0; // No collision
// Collision detected
t = t_numer / denom;
if (i_x != NULL)
*i_x = p0_x + (t * s10_x);
if (i_y != NULL)
*i_y = p0_y + (t * s10_y);
return 1;
}
スタックオーバーフローの記事からの方法:幾何学-あなたはどのようにWHERE 2つの線分検出ください
INTERSECTを?----------------
免責事項:この記事はCSDNブロガーである「アウェイ・ファー」で元の記事、CC 4.0 BY-SAの著作権契約に従うが、再現し、元のソースのリンクと、この文を添付してください。
オリジナルリンクします。https://blog.csdn.net/wcl0617/article/details/78654944