沿着曲线在设定距离处找到带有切线的曲线的算法

问题描述 投票:0回答:1

我正在寻找编写(或理想地找到一种)用于计算给定近似曲线的算法:

  • 起点和终点
  • 沿曲线的给定距离处的切线
  • 固定的曲线总长

所以类似起点(x_0,y_0)终点(x_n,y_n)以及距离和角度列表[(a_0,0),(a_1,d_1)...(a_n,d_n)],其中a_i是[x_0,y_0)和d_n之间的距离d_i(沿曲线)与曲线的切线是沿曲线从[x_0,y_0]到(x_n,y_n)的总距离。

由于输入将来自真实世界的数据,因此不会有精确的解决方案,但某种迭代近似法将是合适的。

我的主要问题是,我不知道这样的曲线类是否具有名称,以便我可以搜索它,理想情况下,已经有一种算法可以使用。我发现的大多数东西都假定知道控制点的位置。

有关该问题的更多信息:它实际上是三维的,但z方向的范围比x和y小得多,因此为简单起见,我认为可以忽略不计。但是为了完整起见,z值在起点,终点和每个已知的切点处都是已知的。

整个曲线也随时间平滑变化(但沿着切线测量的曲线的总长度和距离保持不变),因此可以将先前时间步长处的曲线用作迭代解的起点。

我主要在python中工作,所以如果有一个numpy / scipy的实现是理想的。

python algorithm geometry curve
1个回答
0
投票

我可以尝试建议一种方法,但是您需要了解一些细节以了解如何做。

您正在寻找曲线C(s) = [C_1(s), C_2(s)],使得s是其弧长参数,即length( C(s) ) = s。您希望弧长参数s通过点0, d_1, d_2, ..., d_n,并且在每个点处,曲线的切线与水平x轴之间的角度为a_0, a_1, a_2, ..., a_n

在每个间隔[d_(i-1), d_i]中选择两个点b_i, c_i,以便选择d_(i-1) < u_i < v_i < d_i。另外,拾取并倾斜b_i

设置连续曲线

T(s, u_i, v_i, b_i) = [ T_1(s, u_i, v_i, b_i), T_2(s, u_i, v_i, b_i) ]
                    when s in [d_(i-1), d_i]

通过应用以下公式:

T_1(s) = cos( a_(i-1) + (b_i - a_(i-1)) * (s - d_(i-1))/(u_i - d_(i-1)) )
T_2(s) = sin( a_(i-1) + (b_i - a_(i-1)) * (s - d_(i-1))/(u_i - d_(i-1)) )
       when s in [d_(i-1), u_i]

T_1(s) = cos( b_i )
T_2(s) = sin( b_i )
       when s in [u_i, v_i]

T_1(s) = cos( b_i + (a_i - b_i) * (s - v_i)/(d_i - v_i)) )
T_2(s) = sin( b_i + (a_i - b_i) * (s - v_i)/(d_i - v_i)) )
       when s in [v_i, d_i]  

将所有这些曲线放在一起,得到整体曲线

T(s, u, v, b) = [ T_2(s, u, v, b),  T_2(s, u, v, b) ]  for s in [d_0, d_n]
              where u = [u_1, u_2,..., u_n], 
                    v = [v_1, v_2,..., v_n],
                    b = [b_1, b_2,..., b_n] 

按照定义,对于每个s观察其

norm( T(s, u, v, b) ) = sqrt( T_1(s, u, v, b)^2 + T_2(s, u, v, b)^2 ) = 1
    (because T is defined simply as cos and sin of the same argument)

此等式在积分曲线时完全成立

D(s, u, v, b) = integral_from(0)_to(s)  T(t, u, v, b) dt

弧长参数化,即对于所有length( D(s, u, v, b) ) = ss。曲线D(s, u, v, b)是连续可微的,因为T(s)是连续的。

注意,您可以定义地图

[u, v, b] --> D(d_n, u, v, b)

并且您有足够的参数u = [u_1,...,u_n], v = [v_1,...,v_n]b = [b_1,...,b_n]尝试调整它们,以便

D(d_n, u, v, b) = x_n - x_0

其中x_0x_n是曲线的起点和终点。例如,观察到在每个子间隔[u_i,v_i]中,积分曲线为

D(s) = D(u_i) + s*[cos(b_i), sin(b_i)]

所以它是一条直线。并且间隔D(s)中的[d_(i-1), d_i]的弯曲(实际上是圆形)部分集中在[d_(i-1), u_i] union [v_i, d_i]中。因此,u_i越接近d_(i-1)v_i越接近d_iD(s)越直越会寻找s的大部分。这使您可以变形和操纵曲线D(s),使其可以到达点x_n - x_0

结果,一条满足您条件的曲线是

C(s) = x_0 + D(s, u, v, b)
© www.soinside.com 2019 - 2024. All rights reserved.