所以我在玩一些贝塞尔曲线的动画——只是学习如何使用 ipycanvas (0,10,2) 的一部分——我制作的动画真的让我头疼。我期望看到的是 4 个贝塞尔控制点之间的一组直线,它们在画布周围“弹跳”,贝塞尔曲线也随之移动。
我确实得到了移动的贝塞尔曲线——但控制点保持静止。更奇怪的是,他们在最后的位置上是静止的,曲线来迎接他们。
现在有时 Python 的结构和引用会变得有点棘手,所以如果你没有真正考虑清楚,有时会得到令人困惑的结果——这完全可能是正在发生的事情——但我不知所措。
因此,为了确保我不感到困惑,我在开始时打印了控制点(pts),然后将它们显示到画布上。这证实了我的猜想。通过量子隧道或其他一些神奇的时间旅行,这条线canvas.stroke_lines(pts)
到达未来并抓住未来pts
存在的阵列并将控制点保持在其最终状态。
其他所有使用都pts
使用当前时间状态。
所以我需要知道的是 A) 物理定律是安全的,我只是太笨了,无法理解我自己的代码。B)我应该报告 ipycanvas 中有一些奇怪的错误。C)如何通过这种时间旅行代码获利——比如,我们可以用它来以某种方式分解大量数字吗?
from ipycanvas import Canvas, hold_canvas
import numpy as np
def rgb_to_hex(rgb):
if len(rgb) == 3:
return '#%02x%02x%02x' % rgb
elif len(rgb) == 4:
return '#%02x%02x%02x%02x' % rgb
def Bezier4(t, pts):
p = t**np.arange(0, 4,1)
M=np.matrix([[0,0,0,1],[0,0,3,-3],[0,3,-6,3],[1,-3,3,-1]])
return np.asarray((p*M*pts))
canvas = Canvas(width=800, height=800)
display(canvas) # display the canvas in the output cell..
pts = np.random.randint(50, 750, size=[4, 2]) #choose random starting point
print(pts) #print so we can compare with ending state
d = np.random.uniform(-4,4,size=[4,2]) #some random velocity vectors
c = rgb_to_hex(tuple(np.random.randint(75, 255,size=3))) #some random color
canvas.font = '16px serif' #font for displaying the changing pts array
with hold_canvas(canvas):
for ani in range(300):
#logic to bounce the points about...
for n in range(0,len(pts)):
pts[n]=pts[n] + d[n]
if pts[n][0] >= 800 or pts[n][0] <= 0 :
d[n][0] = - d[n][0]
if pts[n][1] >= 800 or pts[n][1] <= 0 :
d[n][1] = - d[n][1]
#calculate the points needed to display a bezier curve
B = [(Bezier4(i, pts)).ravel() for i in np.linspace(0,1,15)]
#begin display output....
canvas.clear()
#first draw bezier curve...
canvas.stroke_style = c
canvas.stroke_lines(B)
#Now draw control points
canvas.stroke_style = rgb_to_hex((255,255,128, 50))
canvas.stroke_lines(pts)
#print the control points to the canvas so we can see them move
canvas.stroke_style = rgb_to_hex((255,255,128, 150))
canvas.stroke_text(str(pts), 10, 32)
canvas.sleep(20)
说真的,我试图思考可能发生的事情,但我却一头雾水。由于 ipycanvas 正在与浏览器/javascript 对话,因此可能首先呈现帧的所有数据,并且用于保存pts
数据的数组stroke_lines
最终得到最终值......而 B 数组在每个循环中重新创建...... . 这是一个猜测。