You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Matplotlib Polygon填充外溢:Voronoi多边形顶点顺序自动修正咨询

解决Matplotlib中Voronoi多边形填充顺序错误的问题

我之前也踩过这个坑!Matplotlib的Polygon组件确实对顶点的环绕方向(顺时针/逆时针)有隐式要求——它默认把逆时针排列的顶点围成的区域当作多边形内部,要是顶点是顺时针排列,填充时就会把整个画布除了多边形本身的区域都当成“内部”来渲染,这就是你看到的填充到外部的原因。

下面给你两种解决思路,从自动处理到手动检测修正都有:

一、让Matplotlib自动处理顶点顺序(最简单的方法)

其实Matplotlib的Path类自带了修正路径的功能,你可以不用手动判断顺序,直接让它帮你调整:

from matplotlib.patches import Polygon
from matplotlib.path import Path

# 假设你的多边形顶点是一个numpy数组或列表poly_vertices
polygon = Polygon(poly_vertices)
# 调用Path的cleaned方法自动修正环绕方向
cleaned_path = polygon.get_path().cleaned()
# 用修正后的路径重新创建Polygon
fixed_polygon = Polygon(cleaned_path.vertices, closed=True)

这个cleaned()方法会自动检测路径的环绕方向,将其调整为Matplotlib期望的方向,同时还能处理一些路径的小问题(比如重复顶点)。

二、手动检测并修正顶点顺序(适合需要自定义逻辑的场景)

如果你不想依赖Matplotlib的自动处理,或者需要明确控制顺序,可以通过计算多边形的有向面积来判断顶点顺序:

在Matplotlib的坐标系(原点左下角,y轴向上)中,逆时针排列的多边形有向面积为正,顺时针则为负。我们可以用这个特性来判断是否需要反转顶点:

import numpy as np

def fix_polygon_vertices(vertices):
    # 将顶点转换为numpy数组,方便计算
    vertices = np.array(vertices)
    # 计算有向面积的2倍(避免除以2,不影响符号判断)
    x, y = vertices[:, 0], vertices[:, 1]
    area_double = np.sum(x[:-1] * y[1:] - x[1:] * y[:-1])
    # 如果面积为负,说明是顺时针排列,反转顶点顺序
    if area_double < 0:
        return vertices[::-1].tolist()
    else:
        return vertices.tolist()

# 用法示例:
fixed_vertices = fix_polygon_vertices(your_voronoi_polygon_vertices)
polygon = Polygon(fixed_vertices)

注意点:

  • 这个方法只适用于简单多边形(没有自相交的情况),而Voronoi区域刚好都是简单多边形,所以完全适用。
  • 如果你的坐标系是y轴向下的(比如某些图像坐标系),判断逻辑要反过来——面积为正的时候需要反转。

额外提示:Scipy Voronoi的小细节

Scipy的Voronoi生成的区域顶点顺序并非完全随机,它基于Delaunay三角剖分生成,所以部分区域的顶点顺序可能刚好是顺时针。你可以在生成Voronoi区域后,直接对每个区域的顶点应用上面的修正函数,再传入Matplotlib绘制。

内容的提问来源于stack exchange,提问作者arnsholt

火山引擎 最新活动