我想画一个摆线针,该摆线针与其他摆线针一样,但我不知道该怎么做。这是我的代码。
import numpy as np
import matplotlib.pyplot as plt
import math
from matplotlib import animation
#r = float(input('write r\n'))
#R = float(input('write R\n'))
r = 1
R = 1
x = []
y = []
x2 = []
y2 = []
x3 = []
y3 = []
length=[0]
fig, ax = plt.subplots()
ln, = plt.plot([], [], 'r', animated=True)
f = np.linspace(0, 10*r*math.pi, 1000)
def init():
ax.set_xlim(-r, 12*r*math.pi)
ax.set_ylim(-4*r, 4*r)
return ln,
def update2(frame):
#parametric equations of cycloid
x0 = r * (frame - math.sin(frame))
y0 = r * (1 - math.cos(frame))
x.append(x0)
y.append(y0)
#derivative of cycloid
dx = r * (1 - math.cos(frame))
dy = r * math.sin(frame)
#center of circle
a = dy * dy + dx * dx
b = (-2 * x0 * dy) - (2 * frame * dy * dy) + (2 * y0 * dx) - (2 * frame * dx * dx)
c = (x0 * x0) + (2 * frame * x0 * dy) + (frame * frame * dy * dy) + (y0 * y0) - (2 * frame * y0 * dx) + (frame * frame * dx * dx) -1
t1 = (-b - math.sqrt(b * b - 4 * a * c)) / (2 * a)
#t2 = (-b + math.sqrt(b * b - 4 * a * c)) / (2 * a)
center1x=(x0-dy*(t1-x0))*R
center1y=(y0+dx*(t1-x0))*R
#center2x=(x0-dy*(t2-x0))*R
#center2y=(y0+dx*(t2-x0))*R
#length of cycloid
length.append(math.sqrt(x0*x0 + y0*y0))
dl=sum(length)
param = dl / R
W1x = center1x + R * math.cos(-param)
W1y = center1y + R * math.sin(-param)
#W2x = center2x + R * math.cos(-param)
#W2y = center2y + R * math.sin(-param)
x2.append(W1x)
y2.append(W1y)
#x3.append(W2x)
#y3.append(W2y)
ln.set_data([x, x2], [y, y2])
return ln,
ani = animation.FuncAnimation(fig, update2, frames=f,init_func=init, blit=True, interval = 0.1, repeat = False)
plt.show()
在我的函数
update2
中,我创建了第一个摆线的参数方程,然后尝试获取应该在第一个摆线上的第二个摆线的点的坐标。我的想法是基于典型的摆线沿直线移动,而在其他曲线上移动的摆线必须在该曲线的切线上移动,因此创建该摆线的圆心始终位于曲线的法线上。从法线的参数方程式中,我试图获得产生摆线的圆心,但我认为这不是好方法。
我的目标是得到这样的东西:
最佳答案
这是一种方法。微积分为我们提供了公式,以找到摆线上任意点的方向角和沿摆线的弧长。解析几何告诉我们如何使用该信息来找到所需的点。
顺便说一句,将一个图形沿着另一个图形滚动而成的图形称为roulette。我的代码相当简单,可以进行优化,但是现在可以正常工作,可以用于其他问题,并且可以分解以使数学和算法更易于理解。要理解我的代码,请使用此图。摆线是蓝色曲线,黑圈是摆线上的滚动圆,点A是“锚点”(边缘点与摆线接触的点-我想使代码通用),点F是是移动的边缘点。两个红色弧的长度相同,这就是我们沿着摆线滚动圆的意思。
这是我的代码。询问是否需要有关各种公式的来源的帮助,但是方向角和弧长使用微积分。
"""Numpy-compatible routines for a standard cycloid (one caused by a
circle of radius r above the y-axis rolling along the positive x-axis
starting from the origin).
"""
import numpy as np
def x(t, r):
"""Return the x-coordinate of a point on the cycloid with parameter t."""
return r * (t - np.sin(t))
def y(t, r):
"""Return the y-coordinate of a point on the cycloid with parameter t."""
return r * (1.0 - np.cos(t))
def dir_angle_norm_in(t, r):
"""Return the direction angle of the vector normal to the cycloid at
the point with parameter t that points into the cycloid."""
return -t / 2.0
def dir_angle_norm_out(t, r):
"""Return the direction angle of the vector normal to the cycloid at
the point with parameter t that points out of the cycloid."""
return np.pi - t / 2.0
def arclen(t, r):
"""Return the arc length of the cycloid between the origin and the
point on the cycloid with parameter t."""
return 4.0 * r * (1.0 - np.cos(t / 2.0))
# Roulette problem
def xy_roulette(t, r, T, R):
"""Return the x-y coordinates of a rim point on a circle of radius
R rolling on a cycloid of radius r starting at the anchor point
with parameter T currently at the point with parameter t. (Such a
rolling curve on another curve is called a roulette.)
"""
# Find the coordinates of the contact point P between circle and cycloid
px, py = x(t, r), y(t, r)
# Find the direction angle of PC from the contact point to circle's center
a1 = dir_angle_norm_out(t, r)
# Find the coordinates of the center C of the circle
cx, cy = px + R * np.cos(a1), py + R * np.sin(a1)
# Find cycloid's arc distance AP between anchor and current contact points
d = arclen(t, r) - arclen(T, r) # equals arc PF
# Find the angle φ the circle turned while rolling from the anchor pt
phi = d / R
# Find the direction angle of CF from circle's center to rim point
a2 = dir_angle_norm_in(t, r) - phi # subtract: circle rolls clockwise
# Find the coordinates of the final point F
fx, fy = cx + R * np.cos(a2), cy + R * np.sin(a2)
# Return those coordinates
return fx, fy
import matplotlib.pyplot as plt
r = 1
R = 0.75
T = np.pi / 3
t_array = np.linspace(0, 2*np.pi, 201)
cycloid_x = x(t_array, r)
cycloid_y = y(t_array, r)
roulette_x, roulette_y = xy_roulette(t_array, r, T, R)
fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.axhline(y=0, color='k')
ax.axvline(x=0, color='k')
ax.plot(cycloid_x, cycloid_y)
ax.plot(roulette_x, roulette_y)
plt.show()
这是生成的图形。您可以随意选择。请注意,这仅使圆沿摆线的一个弧形滚动。如果您弄清风口浪尖会发生什么,可以扩展此范围。
或者,如果您想要一个较小的圆和一条在尖端处结束的曲线(此处为
r = 1
,T = 0
n = 6
(小拱门的数量)和R = 4 * r / np.pi / n
),