Path.CURVE3 和 Path.CURVE4 有什么问题?贝塞尔曲线在某一点混乱
What is wrong with Path.CURVE3 and Path.CURVE4? Bézier curve messes up in a certain point
我想用 Python 在 JupyterLab 上绘制贝塞尔曲线,我正在使用 MatplotLib 来制作兰博基尼的复制品。绘图必须是忠实的复制品,所以我使用 NumPy 带来 Lamborghini image as a background, as long as I can draw over it and manipulate its properties such as opacity. But no matter what I do, these very first points of the bumber just go crazy. I tried using Path.CURVE3 and Path.CURVE4, Path.STOP and also Path.LINETO in order to make the Bézier curve stop properly on a given point (curve going crazy)。我也尝试制作更小的曲线,但我看不到我想要的东西。我必须完全按照汽车的曲线行驶。我用GIMP提取了我需要的点。
这是我的代码,实际上,这种情况比我在这里暴露的还要普遍,即使没有使用 NumPy 图像处理也会发生这种情况。使用 CURVE 对象的规则是什么?有什么限制?是什么让我的曲线变得疯狂?
import math
import matplotlib.patches as mpatches
import matplotlib.path as mpath
import matplotlib.pyplot as plt
import numpy as np
Path = mpath.Path
fig, ax = plt.subplots()
bumper = mpatches.PathPatch(
Path(
[(22, 163), (12, 134), (13, 132), (30.6, 117.65), (43, 118)],
[Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, Path.CURVE4],
),
fc="none",
transform=ax.transData,
color="green",
lw=1,
)
ax.add_patch(bumper)
ax.set_title("Lamborghini Sián FKP 37", fontfamily="Tahoma", fontsize=22)
ax.set_aspect(1)
plt.xticks(np.linspace(0, 1180, 21), fontsize=10)
plt.yticks(np.linspace(0, 330, 9), fontsize=10)
plt.grid(color="gray", ls=":", lw=0.2)
lambo = plt.imread("Lamborghini Sian FKP 37 Right Side.png")
plt.imshow(lambo, alpha=0.35, extent=[0, 1180, 0, 330])
plt.rcParams["figure.figsize"] = (15, 6)
plt.show()
于是,经过一段时间的研究,我在MatplotLib文档中找到了this,弄明白了Path的二次曲线Path.CURVE3
和三次曲线Path.CURVE4
属性的含义。 CURVE3
表示您只能绘制具有 2 个给定点的曲线,CURVE4
具有 3 个点。我们要记住:起点就像把铅笔放在纸上,第一个点; 控制点才是真正的曲线,你可以想象一根绳子在两点之间完全笔直,被拉动,形成曲线; 终点 是您停止绘图并将铅笔从纸上拿开的最后一个点。
Path.MOVETO
是当你把铅笔放在纸上(开始一个新的轨迹)
Path.CURVE3
必须与精确的 2 点一起使用:
- 1 个控制点。 (
Path.CURVE3
)
- 1 终点。 (
Path.CURVE3
)
Path.CURVE4
必须与精确的 3 点一起使用:
- 2 个控制点。 (
Path.CURVE4
)
- 1 终点。 (
Path.CURVE4
)
我的努力是将很多点放在 verts
列表中,如下所示:[(x,y),(x,y),(x,y),(x,y),(x,y)]
并拥有一个 codes
列表,如下所示:[Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, Path.CURVE4]
。请注意,在此示例中,我们有 5 个点。当我们要绘制贝塞尔曲线时,我们必须分析它必须是 CURVE3
还是 CURVE4
。如果你有4点,就用CURVE4
,如果有3点就用CURVE3
。我们必须做一些变通方法来划分要定义的路径。如果你有超过点数的限制,你必须重新启动关于曲线大小的路径。像这样:
bezier1 = mpatches.PathPatch( # Everything in the same patch
Path([(5, 30), (15, 55), (25, 15), (35, 40), # 4 first points
(20, 10), (30, 0), (35, 10)], # 3 new points, so start a new curve and use
[Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, # Begin the curve
Path.MOVETO, Path.CURVE3, Path.CURVE3]), # Restart the process with a new one
fc="none", transform=ax.transData, color="red", lw=2)
重要提示:另外,如果你绘制的是一条长曲线,当线条的一部分完成时,你必须通过立即开始线条的延续最后一点,这会给你一个连续的。这就是我发现的,我希望这可以帮助别人。
我想用 Python 在 JupyterLab 上绘制贝塞尔曲线,我正在使用 MatplotLib 来制作兰博基尼的复制品。绘图必须是忠实的复制品,所以我使用 NumPy 带来 Lamborghini image as a background, as long as I can draw over it and manipulate its properties such as opacity. But no matter what I do, these very first points of the bumber just go crazy. I tried using Path.CURVE3 and Path.CURVE4, Path.STOP and also Path.LINETO in order to make the Bézier curve stop properly on a given point (curve going crazy)。我也尝试制作更小的曲线,但我看不到我想要的东西。我必须完全按照汽车的曲线行驶。我用GIMP提取了我需要的点。
这是我的代码,实际上,这种情况比我在这里暴露的还要普遍,即使没有使用 NumPy 图像处理也会发生这种情况。使用 CURVE 对象的规则是什么?有什么限制?是什么让我的曲线变得疯狂?
import math
import matplotlib.patches as mpatches
import matplotlib.path as mpath
import matplotlib.pyplot as plt
import numpy as np
Path = mpath.Path
fig, ax = plt.subplots()
bumper = mpatches.PathPatch(
Path(
[(22, 163), (12, 134), (13, 132), (30.6, 117.65), (43, 118)],
[Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, Path.CURVE4],
),
fc="none",
transform=ax.transData,
color="green",
lw=1,
)
ax.add_patch(bumper)
ax.set_title("Lamborghini Sián FKP 37", fontfamily="Tahoma", fontsize=22)
ax.set_aspect(1)
plt.xticks(np.linspace(0, 1180, 21), fontsize=10)
plt.yticks(np.linspace(0, 330, 9), fontsize=10)
plt.grid(color="gray", ls=":", lw=0.2)
lambo = plt.imread("Lamborghini Sian FKP 37 Right Side.png")
plt.imshow(lambo, alpha=0.35, extent=[0, 1180, 0, 330])
plt.rcParams["figure.figsize"] = (15, 6)
plt.show()
于是,经过一段时间的研究,我在MatplotLib文档中找到了this,弄明白了Path的二次曲线Path.CURVE3
和三次曲线Path.CURVE4
属性的含义。 CURVE3
表示您只能绘制具有 2 个给定点的曲线,CURVE4
具有 3 个点。我们要记住:起点就像把铅笔放在纸上,第一个点; 控制点才是真正的曲线,你可以想象一根绳子在两点之间完全笔直,被拉动,形成曲线; 终点 是您停止绘图并将铅笔从纸上拿开的最后一个点。
Path.MOVETO
是当你把铅笔放在纸上(开始一个新的轨迹)Path.CURVE3
必须与精确的 2 点一起使用:- 1 个控制点。 (
Path.CURVE3
) - 1 终点。 (
Path.CURVE3
)
- 1 个控制点。 (
Path.CURVE4
必须与精确的 3 点一起使用:- 2 个控制点。 (
Path.CURVE4
) - 1 终点。 (
Path.CURVE4
)
- 2 个控制点。 (
我的努力是将很多点放在 verts
列表中,如下所示:[(x,y),(x,y),(x,y),(x,y),(x,y)]
并拥有一个 codes
列表,如下所示:[Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, Path.CURVE4]
。请注意,在此示例中,我们有 5 个点。当我们要绘制贝塞尔曲线时,我们必须分析它必须是 CURVE3
还是 CURVE4
。如果你有4点,就用CURVE4
,如果有3点就用CURVE3
。我们必须做一些变通方法来划分要定义的路径。如果你有超过点数的限制,你必须重新启动关于曲线大小的路径。像这样:
bezier1 = mpatches.PathPatch( # Everything in the same patch
Path([(5, 30), (15, 55), (25, 15), (35, 40), # 4 first points
(20, 10), (30, 0), (35, 10)], # 3 new points, so start a new curve and use
[Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, # Begin the curve
Path.MOVETO, Path.CURVE3, Path.CURVE3]), # Restart the process with a new one
fc="none", transform=ax.transData, color="red", lw=2)
重要提示:另外,如果你绘制的是一条长曲线,当线条的一部分完成时,你必须通过立即开始线条的延续最后一点,这会给你一个连续的。这就是我发现的,我希望这可以帮助别人。