我想沿着阿基米德螺旋等距放置点,沿着螺旋的每个点之间以及螺旋的每一圈之间都有固定的间隙,如附图所示。我怎样才能实现这个目标?
例如,在图像中,三个红点表示我希望这些点等距。每个点代表一个洞。我尝试使用下面的代码来实现此目的,但是修改
theta
和 radius
参数似乎没有按预期工作:
import numpy as np
import matplotlib.pyplot as plt
def generate_membranes(Nx, Ny, radius, height, output_path):
hole = create_holes(radius, height)
patch_size = hole.shape[0]
image = np.full((Nx + 2 * patch_size, Ny + 2 * patch_size), height)
theta = np.arange(0, max([Nx,Ny]) * np.pi, 0.0001)
r = radius * theta / np.pi * 1.414
x = np.floor(Nx // 2. + r * np.cos(theta))
y = np.floor(Ny // 2. + r * np.sin(theta))
# Correction of x and y values to ensure they are valid
x = np.clip(x, patch_size, Nx + patch_size - 1).astype(np.int32)
y = np.clip(y, patch_size, Ny + patch_size - 1).astype(np.int32)
for i in range(len(x)):
if patch_size < x[i] < Nx + patch_size and patch_size < y[i] < Ny + patch_size:
patchImage = image[x[i] - radius: x[i] + radius + 1, y[i] - radius: y[i] + radius + 1]
if np.sum(patchImage) == height * patchImage.size:
image[x[i] - radius: x[i] + radius + 1, y[i] - radius: y[i] + radius + 1] = hole
return image
Nx, Ny = 300, 300
radius = 2
height = 80
output_path = ""
generate_membranes(Nx, Ny, radius, height, output_path)
我认为这段代码只适用于这些参数,但是一旦参数被修改,它就不再起作用了。
一种可能性是沿旋臂以相等距离绘制点,该距离等于旋臂之间的间距(外半径)/(圈数)。这给出了在空间中几乎但不完全等距的点,最大的偏差在中心。
如果阿基米德螺线有极坐标方程
r=a.theta
,则theta=0
和theta=t
之间的弧长为s=(a/2)[t.sqrt(1+t^2) + ln(t+sqrt(1+t^2))]
因此,找到总长度,将其分成相等的距离,并对每个距离迭代求解极角(我重新排列为下面
t^2
中的二次方程)。请注意,如果您沿着每个段的一半距离,您将在某种程度上减轻中心的情况。
import math
import numpy as np
import matplotlib.pyplot as plt
def spiral( radius, num_cycles ):
''' Returns points separated by equal distance along spiral arms '''
dr = radius / num_cycles # the target distance apart
theta_max = 2 * np.pi * num_cycles # maximum angle
a = radius / theta_max # constant in r = a.theta
s_max = ( a / 2 ) * ( theta_max * math.sqrt( 1 + theta_max ** 2 ) + math.log( theta_max + math.sqrt( 1 + theta_max ** 2 ) ) )
# total distance
N = int( s_max / dr + 0.5 ) # number of points
s = np.linspace( dr / 2, s_max - dr / 2, N ) # individual distances (centres of the arc segments)
theta = np.zeros( N ) # array to hold angles
for i in range( N ): # solve for theta, given s
t = 0
told = t + 1
while abs( t - told ) > 1.0e-10:
told, t = t, math.sqrt( ( -1 + math.sqrt( 1 + 4 * ( 2 * s[i] / a - math.log( t + math.sqrt( 1 + t ** 2 ) ) ) ** 2 ) ) / 2 )
theta[i] = t
r = a * theta # polar equation of Archimedean spiral
return r * np.cos( theta ), r * np.sin( theta ) # cartesian coordinates
radius, ncycle = 1, 20
x, y = spiral( radius, ncycle )
fig, ax = plt.subplots( figsize=(7,7) )
ax.plot( x, y, 'ko' )
plt.show()