source: codes/mesh_generation/scvt/delaunay.py @ 1035

Last change on this file since 1035 was 974, checked in by dubos, 5 years ago

mesh_generation : creation

File size: 2.1 KB
Line 
1import numpy as np
2from scipy.spatial.qhull import _QhullUser
3from scipy.spatial.qhull import _Qhull
4
5from scvt.timer import Timer
6from scvt.sphere import unit_vector
7from scvt.topology import simplex
8
9########################################################
10
11# custom Delaunay class, slightly more efficient
12
13class Delaunay(_QhullUser):
14    def __init__(self, points):
15        qhull_options = b"Qbb Qc Qz Q12"
16        # Run qhull
17        qhull = _Qhull(b"d", points, qhull_options, required_options=b"Qt")
18        _QhullUser.__init__(self, qhull)
19    def _update(self, qhull):
20        qhull.triangulate()
21        self.paraboloid_scale, self.paraboloid_shift = \
22                               qhull.get_paraboloid_shift_scale()
23        self.simplices, self.neighbors, self.equations, self.coplanar = qhull.get_simplex_facet_array()
24        _QhullUser._update(self, qhull)
25
26########################################################       
27
28def testn(z): return z>0.
29def tests(z): return z<=0.
30
31def north_south(points, verbose):
32    with Timer('in stereographic projection', verbose):
33        north,south = [],[]
34        for i in range(points.shape[0]):
35            xyz=unit_vector(points[i,:])
36            points[i,:]=xyz
37            x,y,z=xyz
38            zn, zs = 1.+z, 1.-z
39            if(zn>0.): north.append([i,[x/zn,y/zn]])
40            if(zs>0.):  south.append([i,[x/zs,y/zs]])
41        indn, xyn = zip(*north)
42        inds, xys = zip(*south)
43    with Timer('in planar Delaunay', verbose):
44        trin, tris = Delaunay(np.asarray(xyn)), Delaunay(np.asarray(xys))
45
46    return points[:,2], (indn, trin, testn), (inds, tris, tests)
47
48def enum_simplices(z,domains):
49    # domains is a list of tuples (ind, tri, test)
50    for ind, tri, test in domains:
51        for i,j,k in tri.simplices:
52            ii, jj, kk = ind[i], ind[j], ind[k] # global indices
53            zi, zj, zk = z[ii], z[jj], z[kk]
54            if test(zi) | test(zj) | test(zk): yield simplex(ii,jj,kk)
55
56def delaunay(points, verbose=False):
57    z, north, south = north_south(points, verbose)
58    with Timer('enumerating simplices', verbose):
59        simplices = list(set( enum_simplices(z, (north, south) ) ))
60    return simplices
Note: See TracBrowser for help on using the repository browser.