如何在python中编写螺旋函数?

时间:2014-04-06 19:02:45

标签: python math trigonometry curve

我试图在python中编写一个带有两个参数(x,y)的函数,并以螺旋方向返回一个角度。

假设螺旋的中心位于(x0,y0)位置。然后给定(0,0),它返回45。鉴于其他一些点(0,90)是y轴上从顶部开始的第二个交点,角度约为170。对于任何不接触红线的点,它应该返回您期望方向的角度。螺旋只是表示角度方向的一般事物。

有谁知道如何编写这样的函数?

由于

enter image description here enter image description here

5 个答案:

答案 0 :(得分:2)

那是Archimedean spiral curve。如页面在极坐标中所述,曲线的公式是r =aθ,通常标量a 1 ,即r =θ。极地到笛卡儿的转换是

x = r cos θ, y = r sin θ

因此

x = θ cos θ, y = θ sin θ

从0到6π的变化θ将给出曲线。当您改变参数θ并获得x和y值时,您得到的将是相对于原点(0,0)。对于您的情况,您需要翻译,即将点移动x和y偏移以相应地定位它。如果你想要更大版本的相同曲线你需要缩放(在平移之前),即将x和y值乘以常数标量。

答案 1 :(得分:1)

(我认为螺旋图像比有用的更令人困惑......)

对于点(x,y),您希望以度数取回角度θ,其中(1,0)为0度,(0,1)为90度。

所以我们想找到theta。使用三角学,我们知道x是相邻边,y是相反边,tan(theta) == y/x

tan()每180度重复一次 - tan(y/x) == tan(-y/-x),这有点令人困惑。幸运的是,Python有一个内置函数atan2,可以补偿它。它以弧度为单位返回θ,我们将其转换为度数,如下所示:

from math import atan2, degrees

x, y = (2, 2)
theta = degrees(atan2(y, x))   # => theta == 45.0
然而

atan2返回-2 * pi&lt; theta <= 2 * pi(-179.9 ......至+ 180度);你想要它(0 .. 359.9 ...)度:

theta = (degrees(atan2(y, x)) + 360.0) % 360.0

答案 2 :(得分:1)

你想要一个矢量场,其中一个轨迹是阿基米德螺旋线。

如果采用螺旋式公式

  

x =θcosθ,y =θsinθ

从legends2k的答案中计算出它的切线,你得到

  

vx =cosθ - θsinθ,vy =sinθ+θcosθ

以最直接的方式消除x和y的θ给出了一般矢量场

  

vx = x / r-y,vy = y / r + x,其中r = sqrt(x ^ 2 + y ^ 2)。

然后获得矢量场的角度为atan2(vy,vx)。

答案 3 :(得分:0)

如果有人可以验证这一点,我会很感激。

此解决方案允许您使半径以不同的速率生长,然后角度

半径:

r(t) = r_scalar * t
d(r(t))/dt = r_scaler

度:

a(t) = a0 + a_scalar * t
d(a(t))/dt = a_scaler

位置:

x(t),y(t) = x0 + r(t)*cos(a(t)), y0 + r(t)*sin(a(t))

现在我们可以计算任何t的方向:

d(x(t))/dt = r(t)*(-sin(a(t))*d(a(t))/dt) + d(r(t))/dt*cos(a(t))
d(y(t))/dt = r(t)*(cos(a(t))*d(a(t))/dt) + d(r(t))/dt*cos(a(t))

简化了:

d(x(t))/dt = r(t)*(-sin(a(t))*a_scaler) + r_scaler*cos(a(t))
d(y(t))/dt = r(t)*(cos(a(t))*a_scaler) + r_scaler*sin(a(t))

得到a,b的a值,使得它最接近x(t),y(t)。你可以先估计距离x0,y0到x1,y1是否满足r(t)。

t0 = sqrt((x0 - x2)^2 + (y0 - y1)^2)/r_scalar

看到螺旋中最近的点将处于相同的程度,最小程度地调整t以使角度得到满足。即

t1 = t0-t2 where atan((y0 - y1)/(x0 - x2)) = (a0 + a_scalar * t0) % 2*pi - (a0 + a_scalar * t2)

从而

t2 = (((a0 + a_scalar * t0) % 2*pi) - atan((y0 - y1)/(x0 - x2)) + a0)/a_scalar

然后最近的方向角是atan((d(x(t0-t2))/dt / d(y(t0-t2))/dt))

答案 4 :(得分:0)

import numpy as np
import matplotlib.pyplot as plt
import math

def fermat_spiral(dot):
    data=[]    
    d=dot*0.1
    for i in range(dot): 
        t = i / d * np.pi
        x = (1 +  t) * math.cos(t)
        y = (1 +  t) * math.sin(t)
        data.append([x,y])
    narr = np.array(data)
    f_s = np.concatenate((narr,-narr))
    return f_s

f_spiral = fermat_spiral(20000)
plt.scatter(f_spiral[len(f_spiral)//2:,0],f_spiral[len(f_spiral)//2:,1])
plt.scatter(f_spiral[:len(f_spiral)//2,0],f_spiral[:len(f_spiral)//2,1])
plt.show()