在 Matplotlib 中用 90 度角的线绘制序列

Plotting a sequence with lines at 90 degree angles in Matplotlib

我想绘制 Recamán 的序列 (more info on the sequence here),先绘制一条长度等于第一个元素的线,然后垂直绘制一条线,并从第一条线的末尾开始,长度等于第二个元素,等等。

我的代码如下:

import matplotlib.pyplot as plt
import numpy as np
import math

def pal(point, angle, length): #this plots a line starting at (point), with
    # unpack the first point    #certain angle and length
    x, y = point

    # find the end point
    endy = y + length * math.sin(math.radians(angle)) #calculates change in y and adds to starting value
    endx = x + length * math.cos(math.radians(angle)) #calculates change in x and adds to starting value

    # plots the line with the starting coordinate and the calculated end coordinate
    ax.plot([x, endx], [y,endy])

# end of plot function code

#this is where the elements of the recaman sequence get calculated and added to an array
recaman = []
crn = 0
elements = 100

for i in range(1, elements):
    recaman.append(crn)
    if (crn - i in recaman) or (crn - i < 0):
        crn = crn + i
    else:
        crn = crn - i
#end of recaman calculation

x = 0
y = 0
angle = 0
length = 0

fig, ax = plt.subplots() #creating figure
for i in range(1, elements):
    length = recaman[i-1]   #obtain length of next line
    pal((x, y), angle, length)  #((starting coordinate),
                                # angle of line relative to x-axis, length of line)
    if angle == 270: #resets angle to 0 to complete one full rotation
        angle = 0
    else:
        angle = angle + 90 #adds 90 to angle to draw perpendicular line

    y = y + length * math.sin(math.radians(angle)) #moves the new starting point to the old end point
    x = x + length * math.cos(math.radians(angle))
plt.show()

预期结果如下所示:

实际结果是,好吧,不是这样的:

我已经多次深入研究我的代码,试图找出我做错了什么,但对我来说一切都很好。需要比我眼光更敏锐的人的帮助。

只需要重新排序一些语句。在更新角度之前拉出 x 和 y 更新方程。

    y = y + length * math.sin(math.radians(angle))  # moves the new starting point to the old end point
    x = x + length * math.cos(math.radians(angle))

    if angle == 270:  # resets angle to 0 to complete one full rotation
        angle = 0
    else:
        angle = angle + 90  # adds 90 to angle to draw perpendicular line

稍微不同的方法是将方向硬编码到循环器中,循环器返回北-西-南-东-北等方向。允许我们直接将绘图保留在计算序列的循环中。为了好玩和娱乐,我让它也可以交互显示剧情,这样我们就可以看到序列的发展。

import matplotlib.pyplot as plt
from itertools import cycle

#this iterator cycles through the four directions
NWSE = cycle([[0, 1], [-1, 0], [0, -1], [1, 0]])

fig, ax = plt.subplots()

plt.ion()
plt.show()

recaman = []
crn = 0
elements = 100
#xy keeps track of the coordinates to plot as [[x1, x2], [y1, y2]]
xy= [[0, 0], [0, 0]]

for i in range(1, elements):
    recaman.append(crn)
    if (crn - i in recaman) or (crn - i < 0):
        crn = crn + i
    else:
        crn = crn - i
    
    #plotting
    xy = [[coordxy[1], coordxy[1] + direction * crn] for coordxy, direction in zip(xy, next(NWSE))]
    plt.plot(*xy)
    #here you can speed it up with smaller values
    plt.pause(0.2)

input("press key")
plt.close()

不出所料,输出是相同的: