给定一个由n
矩阵n
组成的M
,在行i
和列j
处,我想循环遍历所有相邻值。
这样做的目的是测试依赖于M的某些函数f
,以查找(i, j)
返回f
的True
的半径。因此,f
看起来像这样:
def f(x, y):
"""do stuff with x and y, and return a bool"""
会这样称呼:
R = numpy.zeros(M.shape, dtype=numpy.int)
# for (i, j) in M
for (radius, (cx, cy)) in circle_around(i, j):
if not f(M[i][j], M[cx][cy]):
R[cx][cy] = radius - 1
break
其中
circle_around
是以圆形螺旋形式返回索引(迭代器)的函数。因此,对于M
中的每个点,此代码将计算并存储f
返回True
的那个点的半径。如果有一种更有效的计算
R
的方法,我也愿意接受。更新:
感谢所有提交答案的人。我编写了一个简短的函数来绘制
circle_around
迭代器的输出,以显示它们的作用。如果您更新答案或发布新答案,则可以使用此代码来验证您的解决方案。from matplotlib import pyplot as plt
def plot(g, name):
plt.axis([-10, 10, -10, 10])
ax = plt.gca()
ax.yaxis.grid(color='gray')
ax.xaxis.grid(color='gray')
X, Y = [], []
for i in xrange(100):
(r, (x, y)) = g.next()
X.append(x)
Y.append(y)
print "%d: radius %d" % (i, r)
plt.plot(X, Y, 'r-', linewidth=2.0)
plt.title(name)
plt.savefig(name + ".png")
结果如下:
plot(circle_around(0, 0), "F.J")
:plot(circle_around(0, 0, 10), "WolframH")
:我已经将镁的建议编码如下:
def circle_around_magnesium(x, y):
import math
theta = 0
dtheta = math.pi / 32.0
a, b = (0, 1) # are there better params to use here?
spiral = lambda theta : a + b*theta
lastX, lastY = (x, y)
while True:
r = spiral(theta)
X = r * math.cos(theta)
Y = r * math.sin(theta)
if round(X) != lastX or round(Y) != lastY:
lastX, lastY = round(X), round(Y)
yield (r, (lastX, lastY))
theta += dtheta
plot(circle_around(0, 0, 10), "magnesium")
:如您所见,没有一个满足我要寻找的接口(interface)的结果产生了一个覆盖所有0、0周围索引的圆形螺旋。FJ是最接近的,尽管WolframH命中了正确的点,但不是以螺旋顺序。
最佳答案
既然提到了点的顺序无关紧要,所以我只是按它们在给定半径处出现的角度(arctan2
)对其进行了排序。更改N
可获得更多积分。
from numpy import *
N = 8
# Find the unique distances
X,Y = meshgrid(arange(N),arange(N))
G = sqrt(X**2+Y**2)
U = unique(G)
# Identify these coordinates
blocks = [[pair for pair in zip(*where(G==idx))] for idx in U if idx<N/2]
# Permute along the different orthogonal directions
directions = array([[1,1],[-1,1],[1,-1],[-1,-1]])
all_R = []
for b in blocks:
R = set()
for item in b:
for x in item*directions:
R.add(tuple(x))
R = array(list(R))
# Sort by angle
T = array([arctan2(*x) for x in R])
R = R[argsort(T)]
all_R.append(R)
# Display the output
from pylab import *
colors = ['r','k','b','y','g']*10
for c,R in zip(colors,all_R):
X,Y = map(list,zip(*R))
# Connect last point
X = X + [X[0],]
Y = Y + [Y[0],]
scatter(X,Y,c=c,s=150)
plot(X,Y,color=c)
axis('equal')
show()
给出
N=8
:更多点
N=16
(对不起,色盲):显然,这接近一个圆并按半径递增的顺序击中每个网格点。
关于python - 在扩展的圆形螺旋中迭代2d数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8979214/