Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在其他函数(其他摆线)的曲线上绘制摆线?_Python_Math_Geometry_Drawing - Fatal编程技术网

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()