绘制连接两点的曲线而不是直线
Draw a curve connecting two points instead of a straight line
我想做这样的事情:
我有点,但不知道如何绘制曲线而不是直线。
谢谢。
你需要一些表达你想要绘制的曲线,然后你可以用很多线段来制作曲线。
这是一条抛物线:
x = np.linspace(-1, 1, 100)
y = x*x
plt.plot(x, y)
这是一条正弦曲线:
x = np.linspace(-2*np.pi, 2*np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
每一个看起来都很光滑,但实际上是由许多小线段组成的。
要像您展示的那样获得一组曲线,您将需要一些表达式来表示要根据其两个端点绘制的曲线。你图片中的那些看起来像 catenarys 这是(大约)悬挂链在重力作用下呈现的形状:
x = np.linspace(-2*np.pi, 2*np.pi, 100)
y = 2*np.cosh(x/2)
plt.plot(x, y)
您将必须找到一种根据曲线的两个端点来参数化该曲线的方法,这将需要您将 y 和 x 的值代入:
y = a*cosh(x/a) + b
并求解 a 和 b 的方程对。
对于对这个问题感兴趣的人,我听从了 Matthew 的建议并提出了这个实现:
def hanging_line(point1, point2):
import numpy as np
a = (point2[1] - point1[1])/(np.cosh(point2[0]) - np.cosh(point1[0]))
b = point1[1] - a*np.cosh(point1[0])
x = np.linspace(point1[0], point2[0], 100)
y = a*np.cosh(x) + b
return (x,y)
结果如下:
import matplotlib.pyplot as plt
point1 = [0,1]
point2 = [1,2]
x,y = hanging_line(point1, point2)
plt.plot(point1[0], point1[1], 'o')
plt.plot(point2[0], point2[1], 'o')
plt.plot(x,y)
有一种很酷(至少对我而言)的方法可以使用 Bezier curves 在两点之间绘制曲线。只需一些简单的代码,您就可以创建带有点连接点的列表,并使用 matplotlib 绘制它们,例如:
def recta(x1, y1, x2, y2):
a = (y1 - y2) / (x1 - x2)
b = y1 - a * x1
return (a, b)
def curva_b(xa, ya, xb, yb, xc, yc):
(x1, y1, x2, y2) = (xa, ya, xb, yb)
(a1, b1) = recta(xa, ya, xb, yb)
(a2, b2) = recta(xb, yb, xc, yc)
puntos = []
for i in range(0, 1000):
if x1 == x2:
continue
else:
(a, b) = recta(x1, y1, x2, y2)
x = i*(x2 - x1)/1000 + x1
y = a*x + b
puntos.append((x,y))
x1 += (xb - xa)/1000
y1 = a1*x1 + b1
x2 += (xc - xb)/1000
y2 = a2*x2 + b2
return puntos
然后,运行一些起点,中间和终点的函数,并使用matplotlib:
lista1 = curva_b(1, 2, 2, 1, 3, 2.5)
lista2 = curva_b(1, 2, 2.5, 1.5, 3, 2.5)
lista3 = curva_b(1, 2, 2.5, 2, 3, 2.5)
lista4 = curva_b(1, 2, 1.5, 3, 3, 2.5)
fig, ax = plt.subplots()
ax.scatter(*zip(*lista1), s=1, c='b')
ax.scatter(*zip(*lista2), s=1, c='r')
ax.scatter(*zip(*lista3), s=1, c='g')
ax.scatter(*zip(*lista4), s=1, c='k')
这应该是结果:
several Bezier quadratic curves
通过稍微扩展代码,您可以获得如下形式:
Bezier quartic curve
我想做这样的事情:
我有点,但不知道如何绘制曲线而不是直线。
谢谢。
你需要一些表达你想要绘制的曲线,然后你可以用很多线段来制作曲线。
这是一条抛物线:
x = np.linspace(-1, 1, 100)
y = x*x
plt.plot(x, y)
这是一条正弦曲线:
x = np.linspace(-2*np.pi, 2*np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
每一个看起来都很光滑,但实际上是由许多小线段组成的。
要像您展示的那样获得一组曲线,您将需要一些表达式来表示要根据其两个端点绘制的曲线。你图片中的那些看起来像 catenarys 这是(大约)悬挂链在重力作用下呈现的形状:
x = np.linspace(-2*np.pi, 2*np.pi, 100)
y = 2*np.cosh(x/2)
plt.plot(x, y)
您将必须找到一种根据曲线的两个端点来参数化该曲线的方法,这将需要您将 y 和 x 的值代入:
y = a*cosh(x/a) + b
并求解 a 和 b 的方程对。
对于对这个问题感兴趣的人,我听从了 Matthew 的建议并提出了这个实现:
def hanging_line(point1, point2):
import numpy as np
a = (point2[1] - point1[1])/(np.cosh(point2[0]) - np.cosh(point1[0]))
b = point1[1] - a*np.cosh(point1[0])
x = np.linspace(point1[0], point2[0], 100)
y = a*np.cosh(x) + b
return (x,y)
结果如下:
import matplotlib.pyplot as plt
point1 = [0,1]
point2 = [1,2]
x,y = hanging_line(point1, point2)
plt.plot(point1[0], point1[1], 'o')
plt.plot(point2[0], point2[1], 'o')
plt.plot(x,y)
有一种很酷(至少对我而言)的方法可以使用 Bezier curves 在两点之间绘制曲线。只需一些简单的代码,您就可以创建带有点连接点的列表,并使用 matplotlib 绘制它们,例如:
def recta(x1, y1, x2, y2):
a = (y1 - y2) / (x1 - x2)
b = y1 - a * x1
return (a, b)
def curva_b(xa, ya, xb, yb, xc, yc):
(x1, y1, x2, y2) = (xa, ya, xb, yb)
(a1, b1) = recta(xa, ya, xb, yb)
(a2, b2) = recta(xb, yb, xc, yc)
puntos = []
for i in range(0, 1000):
if x1 == x2:
continue
else:
(a, b) = recta(x1, y1, x2, y2)
x = i*(x2 - x1)/1000 + x1
y = a*x + b
puntos.append((x,y))
x1 += (xb - xa)/1000
y1 = a1*x1 + b1
x2 += (xc - xb)/1000
y2 = a2*x2 + b2
return puntos
然后,运行一些起点,中间和终点的函数,并使用matplotlib:
lista1 = curva_b(1, 2, 2, 1, 3, 2.5)
lista2 = curva_b(1, 2, 2.5, 1.5, 3, 2.5)
lista3 = curva_b(1, 2, 2.5, 2, 3, 2.5)
lista4 = curva_b(1, 2, 1.5, 3, 3, 2.5)
fig, ax = plt.subplots()
ax.scatter(*zip(*lista1), s=1, c='b')
ax.scatter(*zip(*lista2), s=1, c='r')
ax.scatter(*zip(*lista3), s=1, c='g')
ax.scatter(*zip(*lista4), s=1, c='k')
这应该是结果:
several Bezier quadratic curves
通过稍微扩展代码,您可以获得如下形式:
Bezier quartic curve