【问题标题】:Find the point on a curve a given distance along the curve from another point在曲线上找到沿曲线到另一点给定距离的点
【发布时间】:2019-12-16 14:32:50
【问题描述】:

我试图在曲线上找到一个点“p2”,它距离点“p1”有“d”。

  • 曲线是二次公式ax^2 + bx + c = y
  • 点 p1 在曲线上,假设是 (p1x, p1y)
  • 点 p2 在曲线上,但我们只知道它与 p1 的“沿曲线”距离,即“d”。曲线上的距离可以通过积分'(1+(2*a*x+b)^2)^(1/2) dx'来计算。在这里,从 p1x 到 p2x 的积分'(1+(2*a*x+b)^2)^(1/2) dx' 期望具有给定的数字 k。 p2x 未知。

我一直在使用循环来寻找点。

from scipy import integrate

def integral(a, b, c, p1x, distance_between_p1_and_p2):
        x = lambda x:(1+(2*a*x+b)**2)**(1/2)
        best_i=0
        p2x=0
        for points_on_curve in range(int(p1x*1000),int((p1x+0.15)*1000),1):
                i,j  = integrate.quad(x,p1x,points_on_curve/1000)
                if abs(i-distance_between_p1_and_p2)<abs(best_i-distance_between_p1_and_p2):
                        best_i=i
                        p2x=points_on_curve/1000
        return p1x+p2x

这里的问题是需要很长时间,因为它从p1x开始并稍微增加值,计算从p1到潜在p2的长度,看看它是否比上一个更接近目标distance_between_p1_and_p2。

会有更好的编程方式吗?

【问题讨论】:

  • 对不起,我忘了放图书馆。我只知道集成在 scipy 中,所以我使用了它。当范围未知时,我不确定 scipy 能否找到它。
  • 如果我能做 sqrt(1 + (2*a*x + b)^2) dx 的无限积分,我也许能做到,但我解决不了。跨度>
  • 请参阅this Wikipedia article 中的“寻找曲线的弧长”,并求解您的曲线类别的解析形式
  • 嗨 Linuxios,这个公式让我有 sqrt(1 + (2*a*x + b)^2) dx.. 我被困在这里试图进行无限集成。
  • 一个想法是,拥有被积函数,对端点空间进行一种二分搜索,在每个端点进行数值积分并检查弧长与所需值的接近程度。虽然我觉得积分可能是可以解决的......也许在 Math.SE 上问一下?

标签: python scipy sympy curve numerical-integration


【解决方案1】:

我一直在努力,我找到了两个解决方案。

首先,我使用了 sympy.geometry.curve

from sympy.geometry.curve import Curve
x = sp. Symbol('x')
a = sp. Symbol('a')
b = sp. Symbol('b')
c = sp. Symbol('c')
start = sp. Symbol('start')
end = sp. Symbol('end')
print('length')
print(Curve((a*x**2+b*x+c, x), (x, start, end)).length)

我把它作为输出。

(end + b/(2*a))*sqrt(4*a**2*(end + b/(2*a))**2 + 1)/2 - (start + b/(2*a))*sqrt(4*a**2*(start + b/(2*a))**2 + 1)/2 + asinh(2*a*(end + b/(2*a)))/(4*a) - asinh(2*a*(start + b/(2*a)))/(4*a)

在这里,我可以使用方程式。

from sympy import solve, sqrt, asinh, nsolve
end = sp.S('end')
a = -1
b = 0
c = 4
w3 = 1
length = 2

eq = sp.Eq((end + b/(2*a))*sqrt(4*a**2*(end + b/(2*a))**2 + 1)/2 - (w3 + b/(2*a))*sqrt(4*a**2*(w3 + b/(2*a))**2 + 1)/2 + asinh(2*a*(end + b/(2*a)))/(4*a) - asinh(2*a*(w3 + b/(2*a)))/(4*a),length)

我找到了两种解方程的方法。

  1. 使用 nsolve。即使我有两个答案,这也只能给出一个答案。例如,如果有两个答案(a+sqrt(b)、a-sqrt(b)),我猜这只会给出一个更接近预期值_to_start_search_answer 的答案。

    打印(sp.nsolve(eq, expected_value_to_start_search_answer))

  2. 使用求解。这给出了所有可能的答案,但它比第一个选项慢。

    sol = 求解(eq,end) 打印(溶胶)

【讨论】:

    【解决方案2】:

    您的目标点x, y 位于抛物线以及围绕 p1 的圆上,换句话说,都满足方程

    a x^2 + b x + c = y
    (x - p1x)^2 + (y - p1y)^2 = r^2
    

    您可以通过将第一个方程中的 lhs 插入第二个方程来简单地消除 y,然后求解得到的二次方程为 x

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-06
      • 1970-01-01
      • 1970-01-01
      • 2013-12-31
      • 2021-04-02
      相关资源
      最近更新 更多