compas-dev / compas

Core packages of the COMPAS framework.
https://compas.dev/compas/
MIT License
311 stars 106 forks source link

mesh_dual is not useful for voronoi if all vertices are on boundary #10

Closed tomvanmele closed 6 years ago

tomvanmele commented 6 years ago

wip solution based on numpy/scipy on hotfix branch 0.1.0-#10

tomvanmele commented 6 years ago
from compas.datastructures import Mesh
from compas.plotters import MeshPlotter
from compas.geometry import closest_point_on_line_xy
from compas.topology.triangulation import voronoi_from_points_numpy

mesh = Mesh()

mesh.add_vertex(x=0, y=0)
mesh.add_vertex(x=1.5, y=0)
mesh.add_vertex(x=1, y=1)
mesh.add_vertex(x=0, y=2)

mesh.add_face([0, 1, 2, 3])

sites = mesh.get_vertices_attributes('xy')
voronoi = voronoi_from_points_numpy(sites)

points = []
for xy in voronoi.vertices:
    points.append({
        'pos'       : xy,
        'radius'    : 0.02,
        'facecolor' : '#ff0000',
        'edgecolor' : '#ffffff',
    })

lines = []
arrows = []
for (a, b), (c, d) in zip(voronoi.ridge_vertices, voronoi.ridge_points):
    if a > -1 and b > -1:
        lines.append({
            'start' : voronoi.vertices[a],
            'end'   : voronoi.vertices[b],
            'width' : 1.0,
            'color' : '#ff0000',
        })
    elif a == -1:
        sp = voronoi.vertices[b]
        ep = closest_point_on_line_xy(sp, (voronoi.points[c], voronoi.points[d]))
        arrows.append({
            'start' : sp,
            'end'   : ep,
            'width' : 1.0,
            'color' : '#00ff00',
            'arrow' : 'end'
        })
    else:
        sp = voronoi.vertices[a]
        ep = closest_point_on_line_xy(sp, (voronoi.points[c], voronoi.points[d]))
        arrows.append({
            'start' : sp,
            'end'   : ep,
            'width' : 1.0,
            'color' : '#00ff00',
            'arrow' : 'end'
        })

plotter = MeshPlotter(mesh, figsize=(10, 7))
plotter.draw_points(points)
plotter.draw_lines(lines)
plotter.draw_arrows(arrows)
plotter.draw_vertices(radius=0.02)
plotter.draw_faces()
plotter.show()