python - 复数是如何在网上找到的乌拉姆螺旋描绘中绘制为方向向量的?
问题描述
有问题的代码可以在这里找到:
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
def make_spiral(R):
"""Generates the spiral up to radius R.
Returns a list of complex numbers (x, y coordinates)."""
spiral = [(0+0j)]
for r in range(R+1):
corner = r - 1j * r
side_len = 2 * r
current_pos = corner
for side, direction in zip(range(4), [1j, -1, -1j, 1]):
for step in range(side_len):
current_pos += direction
spiral.append(current_pos)
return spiral
fig, axes = plt.subplots(figsize=(15, 5), ncols=3)
for ax, r in zip(axes.ravel(), [2, 3, 4]):
spiral = make_spiral(r)
ax.plot(np.real(spiral), np.imag(spiral), '-o')
我倾向于认为这1j
意味着y
按照复数的通常笛卡尔表示方式沿轴上升,这会使每个右下角的“角”点沿着每个螺旋转折的右侧上升。-1
可能会从右向左滑动螺旋......等等,直到完成螺旋的一圈。
但我不明白从 开始r - 1j * r
会如何产生第一个螺旋 when r = 1
。或者zip(range(4), [1j, -1, -1j, 1])
应该产生的 ,[(0, 1j), (1, -1), (2, (-0-1j)), (3, 1)]
如何编码需要向上、向左、向下和向右多少步。
我尝试查找for side, direction in zip...
以尝试理解 Python 如何处理这些命令,但我只能将链接的文档作为我搜索的唯一返回。我看到下一行for step
对于理解这一点至关重要。
解决方案
当然,如果您了解 Python,这个问题就很愚蠢,但是对于像我这样说破 Python 的人来说,这里是伪代码/带注释的代码:
def make_spiral(R):
"""Generates the spiral up to a max number of steps in the last coil of R.
Returns a list of complex numbers (x, y coordinates)."""
spiral = [(0+0j)] # Starts at the (0,0) center.
for r in range(R+1):
# Because Py starts counting at 0 the first iteration below (range(side_len)))
# will be lost (side_len = 2*r = 0). So we need to extend to range(R+1)
corner = r - 1j * r
# This corner line repositions the starting point in each coil one diagonal step
#... farther away at the top iteration. This corner, however, is not included
#... in the output at this point. See (*)
side_len = 2 * r
# In the actual spiral we go +1 R, +i up, -2 L, -2i down, +3 R, +3i up, -4 L,...
# odd, odd, even, even, etc...
# But starting at the diagonal corner (one below ad to the right)
#... the # of steps by side will be even and equal, doubling each coil. (**)
current_pos = corner # Starts at the corner...
for side, direction in zip(range(4), [1j, -1, -1j, 1]):
# "side" is a counter or dummy running for the sides of the coil:
# 0 = R vert; 1 = UP horiz; 2 = L vert: 3 = DOWN horiz
# This is not actually used in the calculations.
# "direction" encodes the motion along C in each step.
# list(zip(range(4), [1j, -1, -1j, 1])):
# [(0, 1j), (1, -1), (2, (-0-1j)), (3, 1)]
for step in range(side_len):
# In, for example, side_len =2, the range is 0 and 1'
# but 0 is not the number 0, but just one iteration. So...
current_pos += direction
spiral.append(current_pos)
# ...each direction will be added twice (once for 0, and once for 1):
# 1j added twice will bring the corner first to (1,0), then to (1,1).
# -1 twice will bring the position first to (0,1), then to (-1,1).
# -1j twice will bring the position first to (0,-1), then to (-1,-1).
# 1 twice will bring the position first to (0,-1), then to (1,-1).
# Notice that (1,-1) is the corner. This time we save it in the output.
return spiral
(*)
例如,make_spiral R =2 的输出是:
[0j, (1+0j), (1+1j), 1j, (-1+1j), (-1+0j), (-1-1j), -1j, (1-1j), (2-1j), (2+0j), (2+1j), (2+2j), (1+2j), 2j, (-1+2j), (-2+2j), (-2+1j), (-2+0j), (-2-1j), (-2-2j), (-1-2j), -2j, (1-2j), (2-2j)]
现在很容易转换为 R(没有尝试优化时间):
spiral <- function(R){
spiral <- 0 + 0i
for (r in 1:R){
corner = r - 1i * r
side_len = 2 * r
current_pos = corner
for (dir in c(1i, -1, -1i, 1)){
for (step in seq(side_len)){
current_pos <- current_pos + dir
spiral <- c(spiral, current_pos)
}
}
}
spiral
}
get_primes <- function(n_min, n_max){
options(scipen=999)
result = vector()
for (x in seq(max(n_min,2), n_max)){
has_factor <- F
for (p in seq(2, ceiling(sqrt(x)))){
if(x %% p == 0) has_factor <- T
if(has_factor == T) break
}
if(has_factor==F) result <- c(result,x)
}
result
}
n = 120
sp = spiral(n)
int = 1: length(sp)
prime = get_primes(1,length(sp))
dat = data.frame(int,sp)
ulnam = dat[dat$int %in% prime,]
par(mar=c(.1,.1,.1,.1))
plot(ulnam$sp, asp=1, pch=19, cex=.01,
axes=F, xlab="", ylab="NULL", col="slateblue4")
推荐阅读
- javascript - 与javascript中的map()混淆
- vue.js - @Vue/test-utils shallowMount 为 vuetify 组件输出“[Vue warn]: Unknown custom element”
- zsh - ZSH - 变膨胀困境
- c# - 如何四舍五入到一半值
- php - 我如何找到特定数量的单词的出现
- javascript - 主干,触发和没有监听器的事件是否有副作用
- python - Python 中的 JSON 到 Protobuf
- excel - 当特定列的单元格中的前 4 个字符发生变化时,如何在行之间绘制边框?
- windows - 阻止 Windows 10 控制 html5 视频播放
- java - 根据用于源和目标的路径处理文件/目录时出现 java.lang.NullPointerException 错误