Python 确定两个已知点之间具有给定弧长的抛物线
设(0,0)和(Xo,Yo)是笛卡尔平面上的两点。我们想要确定抛物线,Y=AX^2+BX+C,它从这两点经过,给定的弧长等于S。显然,S>sqrt(Xo^2+Yo^2)。由于曲线必须从(0,0)经过,因此它应该是C=0。因此,曲线方程简化为:Y=AX^2+BX。我如何确定{A,B}知道{Xo,Yo,S}?有两种解决方案,我想要一个>0的 我有一个解析解(复数),对于给定的一组{a,B,Xo,Yo}给出S,虽然这里的问题是相反的。。。我可以通过数值求解一个复杂的方程组。。。但也许有一个数字例程可以做到这一点 有没有有用的Python库?其他想法 非常感谢:-)注意,二次Python 确定两个已知点之间具有给定弧长的抛物线,python,geometry,curve-fitting,Python,Geometry,Curve Fitting,设(0,0)和(Xo,Yo)是笛卡尔平面上的两点。我们想要确定抛物线,Y=AX^2+BX+C,它从这两点经过,给定的弧长等于S。显然,S>sqrt(Xo^2+Yo^2)。由于曲线必须从(0,0)经过,因此它应该是C=0。因此,曲线方程简化为:Y=AX^2+BX。我如何确定{A,B}知道{Xo,Yo,S}?有两种解决方案,我想要一个>0的 我有一个解析解(复数),对于给定的一组{a,B,Xo,Yo}给出S,虽然这里的问题是相反的。。。我可以通过数值求解一个复杂的方程组。。。但也许有一个数字例程可以
a*x0^2+b*x0
的弧长(线积分)由sqrt(1+(2ax+b)^2)
从x=0
到x=x0
的积分给出。求解积分时,积分值为0.5*(I(u)-I(l))/a
,其中u=2ax0+b
<代码>l=b;和I(t)=0.5*(t*sqrt(1+t^2)+log(t+sqrt(1+t^2))
,是sqrt(1+t^2)的积分
由于y0=a*x0^2+b*x0
,b=y0/x0-a*x0
。在u
和l
中替换b
的值,u=y0/x0+a*x0
,l=y0/x0-a*x0
。在线积分(弧长)的解中替换u
和l
,我们得到弧长作为a
的函数:
s(a) = 0.5 * (I(y0/x0 + a*x0) - I(y0/x0 - a*x0)) / a
现在我们有了弧长作为a
的函数,我们只需要找到a
的值,其中s(a)=s
。这就是我最喜欢的根查找算法,the,再次发挥作用的地方
牛顿-拉斐逊求根法的工作算法如下:
对于要获得根的函数f(x)
,如果x(i)
是根的i
猜测
x(i+1) = x(i) - f(x(i)) / f'(x(i))
其中f'(x)
是f(x)
的导数。这个过程一直持续到两个连续猜测之间的差值非常小为止
在我们的例子中,f(a)=s(a)-s
和f'(a)=s'(a)
。通过简单应用链式规则和商规则
s'(a) = 0.5 * (a*x0 * (I'(u) + I'(l)) + I(l) - I(u)) / (a^2)
其中I'(t)=sqrt(1+t^2)
剩下的唯一问题是计算一个好的初始猜测。由于函数的性质,该函数是牛顿-拉斐逊法的最佳候选函数,y0/x0
的初始猜测在大约5-6次迭代中收敛到1e-10
的公差/ε
一旦找到a
的值,b
就是y0/x0-a*x0
将其转化为代码:
def find_coeff(x0, y0, s0):
def dI(t):
return sqrt(1 + t*t)
def I(t):
rt = sqrt(1 + t*t)
return 0.5 * (t * rt + log(t + rt))
def s(a):
u = y0/x0 + a*x0
l = y0/x0 - a*x0
return 0.5 * (I(u) - I(l)) / a
def ds(a):
u = y0/x0 + a*x0
l = y0/x0 - a*x0
return 0.5 * (a*x0 * (dI(u) + dI(l)) + I(l) - I(u)) / (a*a)
N = 1000
EPSILON = 1e-10
guess = y0 / x0
for i in range(N):
dguess = (s(guess) - s0) / ds(guess)
guess -= dguess
if abs(dguess) <= EPSILON:
print("Break:", abs((s(guess) - s0)))
break
print(i+1, ":", guess)
a = guess
b = y0/x0 - a*x0
print(a, b, s(a))
def find_coeff(x0,y0,s0):
def dI(t):
返回sqrt(1+t*t)
定义I(t):
rt=sqrt(1+t*t)
返回0.5*(t*rt+log(t+rt))
def s(a):
u=y0/x0+a*x0
l=y0/x0-a*x0
返回0.5*(I(u)-I(l))/a
def ds(a):
u=y0/x0+a*x0
l=y0/x0-a*x0
返回0.5*(a*x0*(dI(u)+dI(l))+I(l)-I(u))/(a*a)
N=1000
ε=1e-10
猜测=y0/x0
对于范围(N)中的i:
dguess=(s(猜测)-s0)/ds(猜测)
猜测-=dguess
如果abs(dguess)@ReblochonMasque不一定。任何通过原点的多项式都有x-0
或简单地x
作为根。因此它不能有一个独立于x
的常数项。通过S
弧长,我假设你的意思是0,0
和x0,y0
形成的弧长是S
?对我来说,这似乎更像是一个数学问题,而不是编程问题。试着先在纸上算出解析解?你读过吗?在那一节的命名法中,你知道s和p,并想计算f,作为第一步。那里的方程对我来说似乎是非常超越的,所以我不希望得到一个精确的公式。不同的numeric方法可能值得尝试。如果你有(A,B,x0,y0)->S0
,并且不容易反转,这是一个简单的2D最小化问题,你想最小化“abs(S-S0)”,所以你可以尝试一个简单的最小二乘算法……实际上它是1D,因为你有它必须通过的点的限制