我试图在python中编写一个带有两个参数(x,y)
的函数,并以螺旋方向返回一个角度。
假设螺旋的中心位于(x0,y0)
位置。然后给定(0,0)
,它返回45
。鉴于其他一些点(0,90)
是y轴上从顶部开始的第二个交点,角度约为170
。对于任何不接触红线的点,它应该返回您期望方向的角度。螺旋只是表示角度方向的一般事物。
有谁知道如何编写这样的函数?
由于
答案 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()