在曲线上找到与另一点沿曲线给定距离的点
Find the point on a curve a given distance along the curve from another point
我正在尝试在曲线上找到一个点 'p2',它与点 'p1' 相距 'd'。
- 曲线为二次方程 ax^2 + bx + c = y
- 点 p1 在曲线上,假设 (p1x, p1y)
- 点p2在曲线上,但我们只知道它到p1的距离'along the curve',即'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 .
有没有更好的编程方式?
我一直在努力,我找到了两个解决方案。
首先,我使用了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)
我找到了两种解方程的方法。
使用 nsolve。即使我有两个,这也只会给出一个答案。例如,如果有两个答案 (a+sqrt(b), a-sqrt(b)),我猜这只会给出一个更接近 expected_value_to_start_search_answer 的答案。
print(sp.nsolve(eq, expected_value_to_start_search_answer))
使用求解。这给出了所有可能的答案,但它比第一个选项慢。
sol = 求解(eq,end)
打印(溶胶)
你的目标点x, y
在抛物线和p1圆周上,换句话说,都满足方程
a x^2 + b x + c = y
(x - p1x)^2 + (y - p1y)^2 = r^2
您可以通过将第一个方程的 lhs 插入第二个方程来简单地消除 y
,然后求解 x
的二次方程。
我正在尝试在曲线上找到一个点 'p2',它与点 'p1' 相距 'd'。
- 曲线为二次方程 ax^2 + bx + c = y
- 点 p1 在曲线上,假设 (p1x, p1y)
- 点p2在曲线上,但我们只知道它到p1的距离'along the curve',即'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 .
有没有更好的编程方式?
我一直在努力,我找到了两个解决方案。
首先,我使用了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)
我找到了两种解方程的方法。
使用 nsolve。即使我有两个,这也只会给出一个答案。例如,如果有两个答案 (a+sqrt(b), a-sqrt(b)),我猜这只会给出一个更接近 expected_value_to_start_search_answer 的答案。
print(sp.nsolve(eq, expected_value_to_start_search_answer))
使用求解。这给出了所有可能的答案,但它比第一个选项慢。
sol = 求解(eq,end) 打印(溶胶)
你的目标点x, y
在抛物线和p1圆周上,换句话说,都满足方程
a x^2 + b x + c = y
(x - p1x)^2 + (y - p1y)^2 = r^2
您可以通过将第一个方程的 lhs 插入第二个方程来简单地消除 y
,然后求解 x
的二次方程。