Browse code

make point_in_simplex and circumcircle global methods

this way you can import them into other files

Jorn Hoofwijk authored on 17/07/2018 21:24:43
Showing 1 changed files
... ...
@@ -30,6 +30,17 @@ def fast_2d_point_in_simplex(point, simplex, eps=1e-8):
30 30
     return (t >= -eps) and (s + t <= 1 + eps)
31 31
 
32 32
 
33
+def point_in_simplex(point, simplex, eps=1e-8):
34
+    if len(point) == 2:
35
+        return fast_2d_point_in_simplex(point, simplex, eps)
36
+
37
+    x0 = np.array(simplex[0], dtype=float)
38
+    vectors = np.array(simplex[1:], dtype=float) - x0
39
+    alpha = np.linalg.solve(vectors.T, point - x0)
40
+
41
+    return all(alpha > -eps) and sum(alpha) < 1 + eps
42
+
43
+
33 44
 def fast_2d_circumcircle(points):
34 45
     """Compute the center and radius of the circumscribed circle of a triangle
35 46
 
... ...
@@ -107,6 +118,32 @@ def fast_3d_circumcircle(points):
107 118
     return tuple(center), radius
108 119
 
109 120
 
121
+def circumsphere(pts):
122
+    dim = len(pts) - 1
123
+    if dim == 2:
124
+        return fast_2d_circumcircle(pts)
125
+    if dim == 3:
126
+        return fast_3d_circumcircle(pts)
127
+
128
+    # Modified method from http://mathworld.wolfram.com/Circumsphere.html
129
+    mat = [[np.sum(np.square(pt)), *pt, 1] for pt in pts]
130
+
131
+    center = []
132
+    for i in range(1, len(pts)):
133
+        r = np.delete(mat, i, 1)
134
+        factor = (-1) ** (i + 1)
135
+        center.append(factor * np.linalg.det(r))
136
+
137
+    a = np.linalg.det(np.delete(mat, 0, 1))
138
+    center = [x / (2 * a) for x in center]
139
+
140
+    x0 = pts[0]
141
+    vec = np.subtract(center, x0)
142
+    radius = fast_norm(vec)
143
+
144
+    return tuple(center), radius
145
+
146
+
110 147
 def orientation(face, origin):
111 148
     """Compute the orientation of the face with respect to a point, origin.
112 149
 
... ...
@@ -242,15 +279,8 @@ class Triangulation:
242 279
         return [simplex[i] for i in result]
243 280
 
244 281
     def point_in_simplex(self, point, simplex, eps=1e-8):
245
-        if self.dim == 2:
246
-            vertices = self.get_vertices(simplex)
247
-            return fast_2d_point_in_simplex(point, vertices, eps)
248
-        elif self.dim == 3:
249
-            # XXX: Better to write a separate function for this
250
-            return len(self.get_reduced_simplex(point, simplex, eps)) > 0
251
-        else:
252
-            # XXX: Better to write a separate function for this
253
-            return len(self.get_reduced_simplex(point, simplex, eps)) > 0
282
+        vertices = self.get_vertices(simplex)
283
+        return point_in_simplex(point, vertices, eps)
254 284
 
255 285
     def locate_point(self, point):
256 286
         """Find to which simplex the point belongs.
... ...
@@ -345,28 +375,7 @@ class Triangulation:
345 375
             The center and radius of the circumscribed circle
346 376
         """
347 377
         pts = np.dot(self.get_vertices(simplex), transform)
348
-        if self.dim == 2:
349
-            return fast_2d_circumcircle(pts)
350
-        if self.dim == 3:
351
-            return fast_3d_circumcircle(pts)
352
-
353
-        # Modified method from http://mathworld.wolfram.com/Circumsphere.html
354
-        mat = [[np.sum(np.square(pt)), *pt, 1] for pt in pts]
355
-
356
-        center = []
357
-        for i in range(1, len(simplex)):
358
-            r = np.delete(mat, i, 1)
359
-            factor = (-1) ** (i+1)
360
-            center.append(factor * np.linalg.det(r))
361
-
362
-        a = np.linalg.det(np.delete(mat, 0, 1))
363
-        center = [x / (2*a) for x in center]
364
-
365
-        x0 = self.vertices[next(iter(simplex))]
366
-        vec = np.subtract(center, x0)
367
-        radius = fast_norm(vec)
368
-
369
-        return tuple(center), radius
378
+        return circumsphere(pts)
370 379
 
371 380
     def point_in_cicumcircle(self, pt_index, simplex, transform):
372 381
         # return self.fast_point_in_circumcircle(pt_index, simplex, transform)