找到闭合的2d均匀立方B样条的面积

Hug*_*ell 14 python math numpy spline

我有一个2d点列表,它是闭合均匀立方B样条的控制顶点(Dx).我假设一条简单的曲线(非自相交,所有控制点都不同).

我试图找到曲线所包围的区域:

在此输入图像描述

如果我计算结点(Px),我可以将曲线视为多边形; 那么我"只是"需要在实际曲线和连接结点的直线之间找到每个分段的剩余三角形区域.

据我所知,Bspline的形状(因此区域)在旋转和平移下是不变的 - 所以对于每个段,我可以找到一个平移,将t = 0结放在原点,旋转放置t = 1结在+ x轴上:

在此输入图像描述

我可以通过插入点和重新分组来找到曲线的等式:

P(t) = (
    (t**3)*(-Dm1 + 3*D0 - 3*D1 + D2)
    + (t**2)*(3*Dm1 - 6*D0 + 3*D1)
    + t*(-3*Dm1 + 3*D1)
    + (Dm1 + 4*D0 + D1)
) / 6.
Run Code Online (Sandbox Code Playgroud)

但我正在试图将它整合在一起 - 我可以做到

 1
/
| Py(t) dt
/
t=0
Run Code Online (Sandbox Code Playgroud)

但这不会给我区域.我我需要的是

 Px(t=1)
/
| Py(t) (dPx(t) / dt) dt
/
x = Px(t=0)
Run Code Online (Sandbox Code Playgroud)

但在我走得更远之前,我真的很想知道:

  1. 这是正确的面积计算吗?理想情况下,分析解决方案将成为我的一天!

  2. 一旦找到这个区域,如何判断是否需要从基础多边形中添加或减去它(第一个图中的红色区域与绿色区域相比)?

  3. 是否有任何Python模块可以为我做这个计算?Numpy有一些评估立方Bsplines的方法,但没有一种方法可以用来处理区域.

  4. 有更简单的方法吗?我正在考虑可能在一堆点上评估P(t) - 类似于t = numpy.arange(0.0, 1.0, 0.05)- 并将整个事物视为多边形.知道需要多少细分来保证给定的准确度(我想要错误<1%)?

Mar*_*rot 3

  1. 选取任意点作为枢轴p 0(例如原点 (0,0))
  2. 沿着曲线选取一些点p 1 = (x,y)
  3. 对该点处的曲线进行微分,得到速度v = < vx,vy >
  4. 由三点组成一个三角形,并计算面积。最简单的方法是向量p 0 p 1v之间的叉积,然后除以二。
  5. 将该面积在t上积分,从 0 到 1。

您得到的结果是整条曲线的一段面积。有些人会是消极的,因为他们面向相反的方向。如果将所有线段的面积相加,即可得到整条曲线的面积。

结果是:

面积i = (31 x i -1 y i + 28 x i -1 y i +1 + x i -1 y i +2 - 31 x i y i -1 + 183 x i y i +1 + 28 x i y i +2 - 28 x i +1 y i -1 - 183 x i +1 y i + 31 x i +1 y i +2 - x i +2 y i -1 - 28 x i +2 y i - 31 x i + 2 y i + 1 ) / 720

如果将其转化为矩阵形式,则得到:

面积i = < x i -1   x i   x i +1   x i +2 > · P · < y i -1   y i   y i +1   y i +2 > T

其中P

[    0   31   28    1]
[  -31    0  183   28] / 720
[  -28 -183    0   31]
[   -1  -28  -31    0]
Run Code Online (Sandbox Code Playgroud)

如果控制点为[(0,0) (1,0) (1,1) (0,1)],则所得区域变为:

[(0,0), (1,0), (1,1), (0,1)] -> 242/720
[(1,0), (1,1), (0,1), (0,0)] -> 242/720
[(1,1), (0,1), (0,0), (1,0)] ->   2/720
[(0,1), (0,0), (1,0), (1,1)] ->   2/720
Run Code Online (Sandbox Code Playgroud)

总和为 488/720 = 61/90。