DxLibの線分間の最短距離を求める関数Segment_Segment_MinLength_Squareについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
こぐこ

DxLibの線分間の最短距離を求める関数Segment_Segment_MinLength_Squareについて

#1

投稿記事 by こぐこ » 6年前

いつもお世話になっております。

線分間の最短距離を求めようと自力で実装しようとしていたのですが
全く進まないのでDxLibの方を参考させていただこうと
Segment_Segment_MinLength_Square(DxLibレファレンス)を拝見したのですが
基本的な考え方は私も考えた「単位ベクトルと係数で線分上にあるのかどうかを求める」
だと思うのですが、その算出方法でどうも私では理解出来ない部分が多々ありました。
今回そちらの質問をさせていただきたいのですが、

コード:

VECTOR da, db, p, tp ;
VECTOR e1, e2 ;
float a, b, c, d, e, f, w, s, t = 0.0f ;
float tmpA, tmpB ;

VectorSub( &da, &SA2, &SA1 ) ;
VectorSub( &db, &SB2, &SB1 ) ;
VectorSub( &p, &SA1, &SB1 ) ;
a =  VectorInnerProduct( &da, &da ) ;
b = -VectorInnerProduct( &da, &db ) ;
c = -b ;
d = -VectorInnerProduct( &db, &db ) ;
e = -VectorInnerProduct( &da, &p ) ;
f = -VectorInnerProduct( &db, &p ) ;

コード:

	
// SA1 - SA2 または SB1 - SB2 の距離が限りなくゼロに近いかどうかのチェック
tmpA = a < 0.0f ? -a : a ;
tmpB = d < 0.0f ? -d : d ;
if( tmpA < 0.00000001f )
{
	if( tmpB < 0.00000001f )
	{
		return VSquareSize( VSub( SA1, SB1 ) ) ;
	}
	else
	{
		return Segment_Point_MinLength_Square( SB1, SB2, SA1 ) ;
	}
}
else
if( tmpB < 0.00000001f )
{
	return Segment_Point_MinLength_Square( SA1, SA2, SB1 ) ;
}
これは片方、又は両方が点になっているかの判定だと理解しました。

コード:

s = -0.1f ;
w = a * d - b * c ;
if( w <= -0.00000001f )
{
	// クラーメルの公式
	s = ( e * d - b * f ) / w ;
	t = ( a * f - e * c ) / w ;
}
ここがまず理解できません。
クラメルの公式を知らなかったので少し勉強して公式は少し理解しました。
このsとtには今後の使われ方を見ると恐らくまだ未定の係数が入ったと思うのですが、
どのようにして入ったのか理解できませんでした...

コード:

// 二つの線分が縮退していたら点と見なして点同士の距離を返す
if( VectorInnerProduct( &vSA, &vSA ) <= 0.0f && - -VectorInnerProduct( &vSB, &vSB ) <= 0.0f )
{
	VectorSub( &tp, &SA1, &SB1 ) ;
	return _SQRT( VectorInnerProduct( &tp, &tp ) ) ;
}
これは先ほどと一緒で両辺が点なのかどうかの判定だと思うのですが
何故2回目を行ったのでしょうか…

それ以下のコードは恐らく最終的な係数を算出しているとは思いますが
s,tを理解してないので取り敢えずここまででの質問とさせて頂きます。

長文、拙文失礼しました。
何か不足な点があったらすいません。
よろしくお願いします。

“C言語何でも質問掲示板” へ戻る