Python 如何在其他函数(其他摆线)的曲线上绘制摆线?
我想画一个摆线,那个是在其他摆线上画的,但我不知道怎么画。这是我的密码Python 如何在其他函数(其他摆线)的曲线上绘制摆线?,python,math,geometry,drawing,Python,Math,Geometry,Drawing,我想画一个摆线,那个是在其他摆线上画的,但我不知道怎么画。这是我的密码 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 = [] y
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
中,我创建了第一个摆线的参数方程,然后试图获得第二个摆线的点坐标,该坐标应位于第一个摆线上
我的想法是基于,典型的摆线是在直线上移动的,而在另一条曲线上移动的摆线必须在该曲线的切线上移动,所以创建该摆线的圆心始终位于曲线的法线上。从法线的参数方程中,我试图得到创建摆线的圆心,但我认为这不是一个好方法
我的目标是得到这样的东西:
您可以使用定义生成滚动圆中心的坐标。这个中心的参数方程非常简单(如果我没有犯错误的话): 对于大摆线:
X = R(t - sin(t))
Y = R(1 - cos(t))
X' = R(1 - cos(t))
Y' = R*sin(t)
平行曲线(小圆中心):
但圆周上点的轨迹是中心位置和围绕它的旋转与角速度的叠加,角速度取决于主摆线的长度加上主切线的旋转
从评论中的讨论中添加:
摆线弧长
L(t) = 4R*(1-cos(t/2))
to use it for small circle rotation, divide by r
切线旋转导数
fi(t) = atan(Y'/X') = atan(sin(t)/(1-cos(t)) =
atan(2*sin(t/2)*cos(t/2)/(2(sin^2(t/2))) =
atan(ctg(t/2)) = Pi/2 - t/2
所以切线方向的变化和大摆线参数成正比
最终的结果是(也许有些迹象不正确)
这里有一个方法。微积分给出了求摆线上任意点的方向角和沿摆线的弧长的公式。解析几何告诉我们如何使用这些信息来找到所需的点 顺便说一下,将一个图形沿着另一个图形滚动而成的图称为a。我的代码相当简单,可以进行优化,但它现在可以工作,可以用于其他问题,并且被分解以使数学和算法更容易理解。要理解我的代码,请使用此图。摆线是蓝色的曲线,黑色的圆是摆线上的滚动圆,点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
)
谢谢大家。不知何故,我成功地做到了这一点。这个解决方案也许很难看,但对我来说已经足够了
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=0.1
x = []
y = []
x2 = []
y2 = []
x_1=0
x_2=0
lengthX=[0]
lengthY=[0]
lengthabs=[0]
fig, ax = plt.subplots()
ln, = plt.plot([], [], 'r', animated=True)
f = np.linspace(0, 2*math.pi, 1000)
def init():
ax.set_xlim(-r, 4*r*math.pi)
ax.set_ylim(0, 4*r)
return ln,
def update2(frame):
#cycloid's equations
x0 = r * (frame - math.sin(frame))
y0 = r * (1 - math.cos(frame))
x.append(r * (frame - math.sin(frame)))
y.append(r * (1 - math.cos(frame)))
#arc's length
lengthabs.append(math.sqrt((x0-lengthX[-1])*(x0-lengthX[-1])+(y0-lengthY[-1])*(y0-lengthY[-1])))
lengthX.append(x0)
lengthY.append(y0)
dl=sum(lengthabs)
param = dl / R
#center of circle
center1x = r * (frame - math.sin(frame)) + R * math.cos((frame+2*math.pi) / 2)
center1y = r * (1 - math.cos(frame)) - R * math.sin((frame+2*math.pi) / 2)
if(frame<2*math.pi):
W1x = center1x + R * math.cos(-param)
W1y = center1y + R * math.sin(-param)
else:
W1x = center1x + R * math.cos(param)
W1y = center1y + R * math.sin(param)
x2.append(W1x)
y2.append(W1y)
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()
将numpy导入为np
将matplotlib.pyplot作为plt导入
输入数学
从matplotlib导入动画
r=浮点(输入('write r\n'))
R=浮点(输入('write R\n'))
#r=1
#R=0.1
x=[]
y=[]
x2=[]
y2=[]
x_1=0
x_2=0
长度x=[0]
冗长=[0]
lengthabs=[0]
图,ax=plt.子批次()
ln,=plt.plot([],[],'r',动画=True)
f=np.linspace(0,2*math.pi,1000)
def init():
ax.set_xlim(-r,4*r*math.pi)
ax.set_ylim(0,4*r)
返回ln,
def update2(帧):
#摆线方程
x0=r*(帧-数学sin(帧))
y0=r*(1-数学cos(框架))
x、 追加(r*(frame-math.sin(frame)))
y、 追加(r*(1-math.cos(frame)))
#弧长
lengthabs.append(math.sqrt((x0 lengthX[-1])*(x0 lengthX[-1])+(y0 lengthX[-1])*(y0 lengthX[-1]))
长度x.append(x0)
附加(y0)
dl=总和(长度)
参数=dl/R
#圆心
center1x=r*(帧-数学sin(帧))+r*数学cos((帧+2*数学pi)/2)
center1y=r*(1-math.cos(frame))-r*math.sin((frame+2*math.pi)/2)
如果你能告诉我你是怎么得到这些公式的吗?根据我的计算,我得到了x(t)=r(t-sin(t))+r/sqrt(2)和y(t)=r(1-cos(t))-r*sqrt((1-cos(t)/2),其中r是第一个摆线的半径,r是第二个摆线的半径。奇怪的是,我的公式给了我一个奇怪的曲线图,而你的曲线图稍微有点道理。我添加了导数(R表示大摆线,R表示小摆线)@MBo您可以积分Sqrt(X'^2+Y'^2)
以获得沿大摆线移动的表面距离,并使用它计算较小圆的旋转(从而计算较小摆线的缩放参数)。这很好,但我想在上面画摆线,而不是在上面。如果你看平行曲线,你会注意到它周期性地重复。我需要删除下半部分。@meowgoesthedog是的,我可以找到弧长。但我怀疑-我是否应该在较小圆的旋转中添加切线?(类比:当r/2圆围绕r圆旋转时,它会经历3个完整的循环,而不是2个循环)不,这不是一个好方法。这更像是一个数学问题,而不是一个编程问题。我在内部AP微积分考试中做了一个非常类似的问题,这不是很容易。你需要找到摆线的参数方程(你做到了),然后是摆线上任意点的斜率,以及摆线从一个角点到任何其他点的长度。使用这些来计算圆沿摆线旋转到摆线上给定点的程度,并将其与斜率和解析几何结合起来,以获得所需的点。我可能晚些时候就能做到这一点r今天。顺便问一句,你是希望epi摆线只沿着基本摆线的一个拱形还是整个摆线的一个拱形?如果是整个摆线,应该如何处理尖点?例如,滚动圆到达拱形末端时做什么?(你的示例图像使用
"""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()
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=0.1
x = []
y = []
x2 = []
y2 = []
x_1=0
x_2=0
lengthX=[0]
lengthY=[0]
lengthabs=[0]
fig, ax = plt.subplots()
ln, = plt.plot([], [], 'r', animated=True)
f = np.linspace(0, 2*math.pi, 1000)
def init():
ax.set_xlim(-r, 4*r*math.pi)
ax.set_ylim(0, 4*r)
return ln,
def update2(frame):
#cycloid's equations
x0 = r * (frame - math.sin(frame))
y0 = r * (1 - math.cos(frame))
x.append(r * (frame - math.sin(frame)))
y.append(r * (1 - math.cos(frame)))
#arc's length
lengthabs.append(math.sqrt((x0-lengthX[-1])*(x0-lengthX[-1])+(y0-lengthY[-1])*(y0-lengthY[-1])))
lengthX.append(x0)
lengthY.append(y0)
dl=sum(lengthabs)
param = dl / R
#center of circle
center1x = r * (frame - math.sin(frame)) + R * math.cos((frame+2*math.pi) / 2)
center1y = r * (1 - math.cos(frame)) - R * math.sin((frame+2*math.pi) / 2)
if(frame<2*math.pi):
W1x = center1x + R * math.cos(-param)
W1y = center1y + R * math.sin(-param)
else:
W1x = center1x + R * math.cos(param)
W1y = center1y + R * math.sin(param)
x2.append(W1x)
y2.append(W1y)
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()