沿阿基米德螺旋线的等距点,点之间和螺旋圈之间具有固定间隙

问题描述 投票:0回答:1

我想沿着阿基米德螺旋等距放置点,沿着螺旋的每个点之间以及螺旋的每一圈之间都有固定的间隙,如附图所示。我怎样才能实现这个目标?

Spiral

例如,在图像中,三个红点表示我希望这些点等距。每个点代表一个洞。我尝试使用下面的代码来实现此目的,但是修改

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)

我认为这段代码只适用于这些参数,但是一旦参数被修改,它就不再起作用了。

python numpy numpy-ndarray spiral
1个回答
0
投票

一种可能性是沿旋臂以相等距离绘制点,该距离等于旋臂之间的间距(外半径)/(圈数)。这给出了在空间中几乎但不完全等距的点,最大的偏差在中心。

如果阿基米德螺线有极坐标方程

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()

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.