【问题标题】:What is wrong with Path.CURVE3 and Path.CURVE4? Bézier curve messes up in a certain pointPath.CURVE3 和 Path.CURVE4 有什么问题?贝塞尔曲线在某个点搞砸了
【发布时间】:2020-11-17 19:50:11
【问题描述】:

我想用 Python 在 JupyterLab 上绘制贝塞尔曲线,我正在使用 MatplotLib 来制作兰博基尼的复制品。绘图必须是忠实的复制品,所以我使用 NumPy 将Lamborghini 图像作为背景,只要我可以在它上面绘制并操纵它的属性,例如不透明度。但无论我做什么,这些笨蛋的第一点都会发疯。我尝试使用 Path.CURVE3 和 Path.CURVE4、Path.STOP 以及 Path.LINETO 以使 Bézier 曲线在给定点 (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()

【问题讨论】:

    标签: python numpy matplotlib jupyter-lab bezier


    【解决方案1】:

    所以,经过一段时间的研究,我在 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 个点。当我们要绘制贝塞尔曲线时,我们必须分析它是否必须是CURVE3CURVE4。如果你有 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)
    

    重要提示:另外,如果您正在绘制单条长曲线,当部分线完成时,您必须从最后一个点开始延续线,这将给你一个连续的。这就是我发现的,我希望这可以帮助别人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多