Skip to content

Commit c98cfaa

Browse files
committed
Update circumcenter() to work with numpy arrays
1 parent 1557e3f commit c98cfaa

1 file changed

Lines changed: 50 additions & 31 deletions

File tree

  • conda_package/mpas_tools/mesh/creation
Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,70 @@
1-
import collections
21
import numpy as np
32

4-
point = collections.namedtuple('Point', ['x', 'y', 'z'])
5-
63

74
def circumcenter(on_sphere, x1, y1, z1, x2, y2, z2, x3, y3, z3):
85
"""
96
Compute the circumcenter of the triangle (possibly on a sphere)
107
with the three given vertices in Cartesian coordinates.
118
9+
Parameters
10+
----------
11+
on_sphere : bool
12+
If True, the circumcenter is computed on a sphere.
13+
If False, the circumcenter is computed in Cartesian coordinates.
14+
15+
x1, y1, z1 : float or numpy.ndarray
16+
Cartesian coordinates of the first vertex
17+
18+
x2, y2, z2 : float or numpy.ndarray
19+
Cartesian coordinates of the second vertex
20+
21+
x3, y3, z3 : float or numpy.ndarray
22+
Cartesian coordinates of the third vertex
23+
1224
Returns
1325
-------
14-
center : point
15-
The circumcenter of the triangle with x, y and z attributes
16-
26+
xv, yv, zv : float or numpy.ndarray
27+
The circumcenter(s) of the triangle(s)
1728
"""
18-
p1 = point(x1, y1, z1)
19-
p2 = point(x2, y2, z2)
20-
p3 = point(x3, y3, z3)
29+
x1 = np.asarray(x1)
30+
y1 = np.asarray(y1)
31+
z1 = np.asarray(z1)
32+
x2 = np.asarray(x2)
33+
y2 = np.asarray(y2)
34+
z2 = np.asarray(z2)
35+
x3 = np.asarray(x3)
36+
y3 = np.asarray(y3)
37+
z3 = np.asarray(z3)
38+
2139
if on_sphere:
22-
a = (p2.x - p3.x)**2 + (p2.y - p3.y)**2 + (p2.z - p3.z)**2
23-
b = (p3.x - p1.x)**2 + (p3.y - p1.y)**2 + (p3.z - p1.z)**2
24-
c = (p1.x - p2.x)**2 + (p1.y - p2.y)**2 + (p1.z - p2.z)**2
40+
a = (x2 - x3) ** 2 + (y2 - y3) ** 2 + (z2 - z3) ** 2
41+
b = (x3 - x1) ** 2 + (y3 - y1) ** 2 + (z3 - z1) ** 2
42+
c = (x1 - x2) ** 2 + (y1 - y2) ** 2 + (z1 - z2) ** 2
2543

2644
pbc = a * (-a + b + c)
2745
apc = b * (a - b + c)
2846
abp = c * (a + b - c)
2947

30-
xv = (pbc * p1.x + apc * p2.x + abp * p3.x) / (pbc + apc + abp)
31-
yv = (pbc * p1.y + apc * p2.y + abp * p3.y) / (pbc + apc + abp)
32-
zv = (pbc * p1.z + apc * p2.z + abp * p3.z) / (pbc + apc + abp)
48+
denom = pbc + apc + abp
49+
xv = (pbc * x1 + apc * x2 + abp * x3) / denom
50+
yv = (pbc * y1 + apc * y2 + abp * y3) / denom
51+
zv = (pbc * z1 + apc * z2 + abp * z3) / denom
3352
else:
34-
d = 2 * (p1.x * (p2.y - p3.y) + p2.x *
35-
(p3.y - p1.y) + p3.x * (p1.y - p2.y))
53+
d = 2 * (x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2))
3654

37-
xv = ((p1.x**2 + p1.y**2) * (p2.y - p3.y) + (p2.x**2 + p2.y**2)
38-
* (p3.y - p1.y) + (p3.x**2 + p3.y**2) * (p1.y - p2.y)) / d
39-
yv = ((p1.x**2 + p1.y**2) * (p3.x - p2.x) + (p2.x**2 + p2.y**2)
40-
* (p1.x - p3.x) + (p3.x**2 + p3.y**2) * (p2.x - p1.x)) / d
41-
zv = 0.0
55+
xv = (
56+
(x1**2 + y1**2) * (y2 - y3)
57+
+ (x2**2 + y2**2) * (y3 - y1)
58+
+ (x3**2 + y3**2) * (y1 - y2)
59+
) / d
60+
yv = (
61+
(x1**2 + y1**2) * (x3 - x2)
62+
+ (x2**2 + y2**2) * (x1 - x3)
63+
+ (x3**2 + y3**2) * (x2 - x1)
64+
) / d
65+
zv = np.zeros_like(xv)
4266

43-
# Optional method to use barycenter instead.
44-
# xv = p1.x + p2.x + p3.x
45-
# xv = xv / 3.0
46-
# yv = p1.y + p2.y + p3.y
47-
# yv = yv / 3.0
48-
return point(xv, yv, zv)
67+
return xv, yv, zv
4968

5069

5170
def lonlat2xyz(lon, lat, R=6378206.4):
@@ -69,8 +88,8 @@ def lonlat2xyz(lon, lat, R=6378206.4):
6988

7089
lon = np.deg2rad(lon)
7190
lat = np.deg2rad(lat)
72-
x = R*np.multiply(np.cos(lon), np.cos(lat))
73-
y = R*np.multiply(np.sin(lon), np.cos(lat))
74-
z = R*np.sin(lat)
91+
x = R * np.multiply(np.cos(lon), np.cos(lat))
92+
y = R * np.multiply(np.sin(lon), np.cos(lat))
93+
z = R * np.sin(lat)
7594

7695
return x, y, z

0 commit comments

Comments
 (0)