对于个人项目,我需要确定两条三次贝塞尔曲线是否相交。我不需要知道在哪里:我只需要知道他们是否这样做。但是,我需要快速完成。
我一直在搜寻这个地方,并找到了一些资源。大多数情况下,这里的这个问题有一个有希望的答案。
因此,在我弄清楚什么是Sylvester 矩阵、什么是行列式、什么是结果以及它为什么有用之后,我想我知道了解决方案是如何工作的。然而,现实要求有所不同,而且效果并不好。
到处乱混
我用我的图形计算器绘制了两条相交的贝塞尔样条曲线(我们称之为 B 0和 B 1)。它们的坐标如下(P 0 , P 1 , P 2 , P 3):
(1, 1) (2, 4) (3, 4) (4, 3)
(3, 5) (3, 6) (0, 1) (3, 1)
结果如下,B 0是“水平”曲线,B 1是另一条曲线:
按照上述问题的最高投票答案的指示,我将 B 0减去B 1。它给我留下了两个方程(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,因为曲线相交。但是,为我的程序提供上面制作的 Sylvester 矩阵,它是 -2916。
这是我的错误还是他们的错误?找出两条三次贝塞尔曲线是否相交的正确方法是什么?