root/trunk/delaunay/tests/test_triangulate.py

Revision 745, 4.9 KB (checked in by rkern, 4 years ago)

* BUG: fix a leak.
* Add some tests for the duplicate point handling contributed by "pv".

  • Property svn:eol-style set to native
Line 
1import sys
2
3from numpy import random
4import numpy as np
5
6from scikits import delaunay as dlny
7
8def onright(x0, y0, x1, y1, x, y):
9    """Return True if (x,y) is to the right of the vector from (x0,y0) to
10    (x1,y1).
11    """
12    return (y0-y)*(x1-x) > (x0-x)*(y1-y)
13
14def incircle(cx, cy, r, x, y):
15    """Return True if (x,y) is strictly inside the circle centered at (cx,cy)
16    with radius r.
17    """
18    r2 = np.hypot(x-cx, y-cy)
19    assert r2 < r
20
21
22class TestSanity(object):
23    def setup(self):
24        self.rs = random.RandomState(1234567890)
25
26    def test_counts(self):
27        for n in (10, 30, 100, 300, 1000, 3000):
28            x, y = self.rs.uniform(0, 1, size=(2, n))
29            tri = dlny.Triangulation(x, y)
30            k = len(tri.hull)
31            ntriangles = 2*n - 2 - k
32            nedges = 3*n - 3 - k
33            assert tri.triangle_nodes.shape == (ntriangles, 3)
34            assert tri.triangle_neighbors.shape == (ntriangles, 3)
35            assert tri.edge_db.shape == (nedges, 2)
36            assert tri.circumcenters.shape == (ntriangles, 2)
37            assert np.sum((tri.triangle_neighbors == -1).astype(np.int32).flat) == k
38
39    def test_ccw_triangles(self):
40        for n in (10, 30, 100, 300, 1000, 3000):
41            x, y = self.rs.uniform(0, 1, size=(2, n))
42            tri = dlny.Triangulation(x, y)
43
44            for i,j,k in tri.triangle_nodes:
45                assert not onright(x[i], y[i], x[j], y[j], x[k], y[k])
46
47    def test_ccw_hull(self):
48        for n in (10, 30, 100, 300, 1000, 3000):
49            x, y = self.rs.uniform(0, 1, size=(2, n))
50            tri = dlny.Triangulation(x, y)
51
52            hull = list(tri.hull)
53            hull.append(hull[0])
54            hull.append(hull[1])
55
56            for i,j,k in zip(hull[:-2], hull[1:-1], hull[2:]):
57                assert not onright(x[i], y[i], x[j], y[j], x[k], y[k])
58
59    def test_circle_condition(self):
60        assert False, "doesn't work perfectly given floating point imprecision"
61        for n in (10, 30, 100, 300, 1000, 3000):
62            x, y = self.rs.uniform(0, 1, size=(2, n))
63            tri = dlny.Triangulation(x, y)
64
65            i = tri.triangle_nodes[:,0]
66            r2 = ((x[i] - tri.circumcenters[:,0])**2
67                + (y[i] - tri.circumcenters[:,1])**2)
68            alldist2 = (np.subtract.outer(x, tri.circumcenters[:,0])**2
69                      + np.subtract.outer(y, tri.circumcenters[:,1])**2)
70            good = (r2 <= (alldist2 + 1e-12))
71            assert np.alltrue(good)
72
73
74data = np.array([
75    [-3.14, -3.14], [-3.14, -2.36], [-3.14, -1.57], [-3.14, -0.79], [-3.14, 0.0],
76    [-3.14, 0.79], [-3.14, 1.57], [-3.14, 2.36], [-3.14, 3.14], [-2.36, -3.14],
77    [-2.36, -2.36], [-2.36, -1.57], [-2.36, -0.79], [-2.36, 0.0], [-2.36, 0.79],
78    [-2.36, 1.57], [-2.36, 2.36], [-2.36, 3.14], [-1.57, -0.79], [-1.57, 0.79],
79    [-1.57, -1.57], [-1.57, 0.0], [-1.57, 1.57], [-1.57, -3.14], [-1.57, -2.36],
80    [-1.57, 2.36], [-1.57, 3.14], [-0.79, -1.57], [-0.79, 1.57], [-0.79, -3.14],
81    [-0.79, -2.36], [-0.79, -0.79], [-0.79, 0.0], [-0.79, 0.79], [-0.79, 2.36],
82    [-0.79, 3.14], [0.0, -3.14], [0.0, -2.36], [0.0, -1.57], [0.0, -0.79],
83    [0.0, 0.0], [0.0, 0.79], [0.0, 1.57], [0.0, 2.36], [0.0, 3.14],
84    [0.79, -3.14], [0.79, -2.36], [0.79, -0.79], [0.79, 0.0], [0.79, 0.79],
85    [0.79, 2.36], [0.79, 3.14], [0.79, -1.57], [0.79, 1.57], [1.57, -3.14],
86    [1.57, -2.36], [1.57, 2.36], [1.57, 3.14], [1.57, -1.57], [1.57, 0.0],
87    [1.57, 1.57], [1.57, -0.79], [1.57, 0.79], [2.36, -3.14], [2.36, -2.36],
88    [2.36, -1.57], [2.36, -0.79], [2.36, 0.0], [2.36, 0.79], [2.36, 1.57],
89    [2.36, 2.36], [2.36, 3.14], [3.14, -3.14], [3.14, -2.36], [3.14, -1.57],
90    [3.14, -0.79], [3.14, 0.0], [3.14, 0.79], [3.14, 1.57], [3.14, 2.36],
91    [3.14, 3.14],
92])
93
94class TestRegression(object):
95
96    def test_ticket_376(self):
97        x  = np.array([0, 1, 0, 1], dtype=np.float64)
98        y  = np.array([0, 0, 1, 1], dtype=np.float64)
99        z  = np.array([1, 2, 3, 4], dtype=np.float64)
100
101        tri1 = dlny.Triangulation(x, y)
102        nn1 = tri1.nn_interpolator(z)
103
104        xp = np.r_[x, x]
105        yp = np.r_[y, y]
106        zp = np.r_[z, z]
107
108        # shouldn't fail on duplicate points
109        tri2 = dlny.Triangulation(xp, yp)
110        nn2 = tri2.nn_interpolator(zp)
111
112        assert nn1(0.3, 0.5) == nn2(0.3, 0.5)
113
114    def test_ticket_376_2(self):
115        tri = dlny.Triangulation(data[:,0], data[:,1])
116        # should pass
117
118    def test_ticket_382(self):
119        x, y = np.meshgrid(np.linspace(0,1,4), np.linspace(0,1,3))
120
121        tri = dlny.Triangulation(x.flatten(), y.flatten())
122        refcount1 = sys.getrefcount(tri.x)
123        interp = tri.nn_interpolator(x.flatten())
124        refcount2 = sys.getrefcount(tri.x)
125        interp(x.flatten(), y.flatten())
126        refcount3 = sys.getrefcount(tri.x)
127
128        # shouldn't leak references
129        assert refcount1 == refcount2
130        assert refcount1 == refcount3
131
132if __name__ == '__main__':
133    import nose
134    nose.main()
Note: See TracBrowser for help on using the browser.