1

我想限制无限的 Voronoi 区域出现在舞台上。所以对于示例在此处输入图像描述 我希望区域不是无限的。

我试图理解scipy.spartial.Voronoi 文档很多天。我设法将点与区域联系起来,但区域与顶点(我的代码)联系起来。我还修改了 voronoi_plot_2d函数来获得有限的山脊:

import numpy as np
from scipy.spatial import Voronoi
import matplotlib.pyplot as plt
from plotutils_moje import voronoi_plot_2d

class VoronoiPlaceholders:
    def __init__(self, vertex1, point_idxs, points, vertex_placeholder=None, vertex2=None):
        self.vertex1 = vertex1
        self.vertex2 = vertex2
        self.vertex_placeholder = vertex_placeholder
        self.point_idxs = point_idxs
        self.points = points

    def __str__(self):
        text = f'VoronoiPlaceholders(v1:{self.vertex1},'
        if self.vertex2:
            text = f'{text} v2:{self.vertex2};'
        if self.vertex_placeholder:
            text = f'{text} v2~{self.vertex_placeholder};'
        text = f'{text} p1:{self.points[0]} ({self.point_idxs[0]}) and p2:{self.points[1]} ({self.point_idxs[1]}))'
        return text

    def __repr__(self):
        return str(self)

    def point_index_belongs_to(self, point_index):
        return point_index in self.point_idxs

    def is_precise_vertex2_available(self):
        if self.vertex2:
            return True
        return False

def calculate_placeholders_for_all_points(vor):
    """ inspiration: https://github.com/scipy/scipy/blob/main/scipy/spatial/_plotutils.py#L231-L261 """
    center = vor.points.mean(axis=0)
    ptp_bound = vor.points.ptp(axis=0)

    infinite_segments = []
    finite_segments = []
    index = -1
    for pointidx, simplex in zip(vor.ridge_points, vor.ridge_vertices):
        simplex = np.asarray(simplex)
        index += 1

        point1 = vor.points[pointidx[0]]
        point2 = vor.points[pointidx[1]]
        p1, p2 = pointidx

        if np.all(simplex >= 0):
            vertex1, vertex2 = vor.vertices[simplex]
            x1, y1 = vertex1
            x2, y2 = vertex2
            vor_obj = VoronoiPlaceholders(vertex1=(x1, y1), vertex2=(x2, y2),
                                          point_idxs=(p1, p2), points=(point1, point2))
            finite_segments.append(vor_obj)
            continue

        i = simplex[simplex >= 0][0]  # finite end Voronoi vertex

        t = vor.points[pointidx[1]] - vor.points[pointidx[0]]  # tangent
        t /= np.linalg.norm(t)
        n = np.array([-t[1], t[0]])  # normal

        midpoint = vor.points[pointidx].mean(axis=0)
        direction = np.sign(np.dot(midpoint - center, n)) * n
        if vor.furthest_site:
            direction = -direction
        far_point = vor.vertices[i] + direction * ptp_bound.max()

        x1, y1 = vor.vertices[i]
        x2, y2 = far_point

        vor_obj = VoronoiPlaceholders(vertex1=(x1, y1), vertex_placeholder=(x2, y2),
                                      point_idxs=(p1, p2), points=(point1, point2))
        infinite_segments.append(vor_obj)

    return infinite_segments + finite_segments

但我不知道如何将具有有限顶点的脊与区域连接起来。有人可以帮忙吗?

4

0 回答 0