繁体   English   中英

点集之间的平滑线

[英]Smooth line between set of points

我希望将值联合起来的线条是平滑的圆线。 我尝试了 wit interp1d,但似乎并没有完全理解一维数组的要求。

from matplotlib import pyplot as plt

a = int(input("what number?\n"))

X_Values, Y_Values, fibonacci = [0] * a, [0] * a, [0] * a
X_Values[0], Y_Values [0] = 0, 0
X_Values[1], Y_Values[1] = 1, 1
fibonacci[0] = 1
fibonacci[1] = 1
counter = 2

for i in range(2,a):
   fibonacci[i] = fibonacci[i-1] + fibonacci[i-2]
   if counter == 0:
       X_Values[i] = 0
       Y_Values[i] = -fibonacci[i]
       counter += 1
   elif counter == 1:
       X_Values[i] = fibonacci[i]
       Y_Values[i] = 0
       counter += 1
   elif counter == 2:
       X_Values[i] = 0
       Y_Values[i] = fibonacci[i]
       counter += 1
   elif counter == 3:
       X_Values[i] = -fibonacci[i]
       Y_Values[i] = 0
       counter = 0


plt.axhline(y=0, color='k') 
plt.axvline(x=0, color='k')
plt.plot(X_Values, Y_Values, '*-g')
plt.title("Flow Chart of a Fibonacci series with %i elements" %a)
plt.figtext(0.5, 0.025, "The {0}th number of the Fibonacci serie is: {1}".format(a, fibonacci[-1]), ha="center", fontsize=8, bbox={"facecolor":"orange", "alpha":0.5, "pad":5})
print("The ", a, "th Fibonacci number is: ", fibonacci[a-1])
plt.show()

有没有办法缩短 if elif 循环以将坐标分配给 X 和 Y _values?

要创建平滑插值,您可能可以使用Bézier splines 您可以通过添加X[i]X[i+1]以及Y[i]Y[i+1]来计算中间点。

使用圆弧看起来会更好。 起始角度将为-90, 0, 90, 180, 270, ... 结束角度将是开始角度加上 90。宽度和高度有点棘手,因为它们的角色不断切换。 它要么是斐波那契数 i 和 i+1,要么相反。 i % 2(i+1) % 2将负责切换。

要使用更少的代码进行计算,首先请注意不需要counter ,因为它只是i mod 4 旋转方向可以存储在两个列表中, dir_xdir_y 此外,前两个值可以通过 if-test ( if i < 2 ) 设置,因此它们可以对 x 和 y position 使用相同的分配。

from matplotlib import pyplot as plt
from matplotlib.patches import Arc

a = int(input("what number?\n"))

X_Values, Y_Values, fibonacci = [0] * a, [0] * a, [0] * a

dir_x = [0, 1, 0, -1]
dir_y = [-1, 0, 1, 0]
for i in range(0, a):
    if i < 2:
        fibonacci[i] = 1
    else:
        fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2]
    X_Values[i] = dir_x[i % 4] * fibonacci[i]
    Y_Values[i] = dir_y[i % 4] * fibonacci[i]

fig, ax = plt.subplots()
for i in range(a - 1):
    ax.add_patch(Arc((0, 0), width=fibonacci[i + (i + 1) % 2] * 2, height=fibonacci[i + i % 2] * 2,
                     theta1=(i - 1) * 90, theta2=i * 90, color='crimson', lw=2))
# ax.relim() # needed to calculate the x and y limits if no lines are added to the plot
# ax.autoscale()
ax.axis('equal') # equal distances on x and on y
ax.axis('off') # hide the surrounding axes

ax.axhline(y=0, color='k')
ax.axvline(x=0, color='k')
ax.plot(X_Values, Y_Values, '*--g', lw=0.5)
ax.set_title("Flow Chart of a Fibonacci series with %i elements" % a)
ax.text(0.5, -0.05, f"The {a}th number of the Fibonacci serie is: {fibonacci[-1]}", ha="center",
        fontsize=8, bbox={"facecolor": "orange", "alpha": 0.5, "pad": 5}, transform=ax.transAxes)
print("The ", a, "th Fibonacci number is: ", fibonacci[a - 1])

plt.tight_layout()
plt.show()

示例图

PS:创建弧的代码可以使用它的angle参数进一步简化。 angle是弧线的额外旋转,它消除了交替宽度和高度的需要。

ax.add_patch(Arc((0, 0), width=fibonacci[i] * 2, height=fibonacci[i + 1] * 2,
                 angle=(i - 1) * 90, theta1=0, theta2=90, color='crimson', lw=2))

绘制二次贝塞尔曲线的代码:

from matplotlib.patches import PathPatch, Path

x, y = X_Values, Y_Values
for i in range(a - 1):
    ax.add_patch(PathPatch(
        Path([(x[i], y[i]), (x[i] + x[i + 1], y[i] + y[i + 1]), (x[i + 1], y[i + 1])],
             [Path.MOVETO, Path.CURVE3, Path.CURVE3]),
        fc="none", ec='navy', transform=ax.transData))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM