個人的なプロジェクトの場合、2つの立方ベジェ曲線が交差するかどうかを確認する必要があります。私はどこにいるのかを知る必要はありません:私は彼らがそうするかどうかを知る必要があります。しかし、私はそれを速くする必要があります。
私はその場所を掃除していて、いくつかのリソースを見つけました。ほとんどの場合、有望な答えがあったこの質問がここにあります。
したがって、シルベスター行列とは何か、行列式とは何か、結果とは何か、なぜそれが役立つのかを理解した後、ソリューションがどのように機能するかを理解したと思いました。しかし、現実は違うように頼み、それはあまりうまく機能しません。
いじり
グラフ電卓を使用して、交差する2つのベジェスプライン( B0とB1と呼びます)を描画しました。それらの座標は次のとおりです(P 0、P 1、P 2、P 3):
(1, 1) (2, 4) (3, 4) (4, 3)
(3, 5) (3, 6) (0, 1) (3, 1)
結果は次のようになります。B0は「水平」曲線であり、B1はもう1つの曲線です。
前述の質問の上位投票の回答からの指示に従って、 B0をB1に減算しました。私の計算機によると、2つの方程式(X軸とY軸)が残りました。
x = 9t^3 - 9t^2 - 3t + 2
y = 9t^3 - 9t^2 - 6t + 4
シルベスター行列
そして、そこから次のシルベスター行列を作成しました。
9 -9 -3 2 0 0
0 9 -9 -3 2 0
0 0 9 -9 -3 2
9 -9 -6 4 0 0
0 9 -9 -6 4 0
0 0 9 -9 -6 4
その後、余因子展開を使用して行列式を計算するC++関数を作成しました。
template<int size>
float determinant(float* matrix)
{
float total = 0;
float sign = 1;
float temporaryMatrix[(size - 1) * (size - 1)];
for (int i = 0; i < size; i++)
{
if (matrix[i] != 0)
{
for (int j = 1; j < size; j++)
{
float* targetOffset = temporaryMatrix + (j - 1) * (size - 1);
float* sourceOffset = matrix + j * size;
int firstCopySize = i * sizeof *matrix;
int secondCopySize = (size - i - 1) * sizeof *matrix;
memcpy(targetOffset, sourceOffset, firstCopySize);
memcpy(targetOffset + i, sourceOffset + i + 1, secondCopySize);
}
float subdeterminant = determinant<size - 1>(temporaryMatrix);
total += matrix[i] * subdeterminant * sign;
}
sign *= -1;
}
return total;
}
template<>
float determinant<1>(float* matrix)
{
return matrix[0];
}
比較的小さなマトリックス(2x2、3x3、4x4)でかなりうまく機能するように見えるので、6x6マトリックスでも機能すると思います。ただし、徹底的なテストは行っていないので、壊れている可能性があります。
問題
他の質問の答えを正しく理解した場合、曲線が交差するため、行列式は0になります。ただし、上記で作成したシルベスター行列をプログラムにフィードすると、-2916になります。
それは私の側の間違いですか、それとも彼らの側の間違いですか?2つの立方ベジェ曲線が交差するかどうかを確認する正しい方法は何ですか?