Skip to content

Commit 178d453

Browse files
committed
Do not correct orientation of triangles returned by Qhull
1 parent 4884115 commit 178d453

File tree

5 files changed

+40
-8
lines changed

5 files changed

+40
-8
lines changed

lib/matplotlib/tests/test_triangulation.py

+23
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,29 @@ def test_trirefiner_fortran_contiguous_triangles():
985985
assert_array_equal(fine_triang1.triangles, fine_triang2.triangles)
986986

987987

988+
def test_qhull_triangle_orientation():
989+
# github issue 4437.
990+
xi = np.linspace(-2, 2, 100)
991+
x, y = map(np.ravel, np.meshgrid(xi, xi))
992+
w = np.logical_and(x > y - 1, np.logical_and(x < -1.95, y > -1.2))
993+
x, y = x[w], y[w]
994+
theta = np.radians(25)
995+
x1 = x*np.cos(theta) - y*np.sin(theta)
996+
y1 = x*np.sin(theta) + y*np.cos(theta)
997+
998+
# Calculate Delaunay triangulation using Qhull.
999+
triang = mtri.Triangulation(x1, y1)
1000+
1001+
# Neighbors returned by Qhull.
1002+
qhull_neighbors = triang.neighbors
1003+
1004+
# Obtain neighbors using own C++ calculation.
1005+
triang._neighbors = None
1006+
own_neighbors = triang.neighbors
1007+
1008+
assert_array_equal(qhull_neighbors, own_neighbors)
1009+
1010+
9881011
if __name__ == '__main__':
9891012
import nose
9901013
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

lib/matplotlib/tri/_tri.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -222,15 +222,17 @@ Triangulation::Triangulation(const CoordinateArray& x,
222222
const TriangleArray& triangles,
223223
const MaskArray& mask,
224224
const EdgeArray& edges,
225-
const NeighborArray& neighbors)
225+
const NeighborArray& neighbors,
226+
int correct_triangle_orientations)
226227
: _x(x),
227228
_y(y),
228229
_triangles(triangles),
229230
_mask(mask),
230231
_edges(edges),
231232
_neighbors(neighbors)
232233
{
233-
correct_triangles();
234+
if (correct_triangle_orientations)
235+
correct_triangles();
234236
}
235237

236238
void Triangulation::calculate_boundaries()

lib/matplotlib/tri/_tri.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,17 @@ class Triangulation
186186
* once.
187187
* neighbors: Optional int array of shape (ntri,3) indicating which
188188
* triangles are the neighbors of which TriEdges, or -1 if
189-
* there is no such neighbor. */
189+
* there is no such neighbor.
190+
* correct_triangle_orientations: Whether or not should correct triangle
191+
* orientations so that vertices are
192+
* ordered anticlockwise. */
190193
Triangulation(const CoordinateArray& x,
191194
const CoordinateArray& y,
192195
const TriangleArray& triangles,
193196
const MaskArray& mask,
194197
const EdgeArray& edges,
195-
const NeighborArray& neighbors);
198+
const NeighborArray& neighbors,
199+
int correct_triangle_orientations);
196200

197201
/* Calculate plane equation coefficients for all unmasked triangles from
198202
* the point (x,y) coordinates and point z-array of shape (npoints) passed

lib/matplotlib/tri/_tri_wrapper.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,17 @@ static int PyTriangulation_init(PyTriangulation* self, PyObject* args, PyObject*
3535
Triangulation::MaskArray mask;
3636
Triangulation::EdgeArray edges;
3737
Triangulation::NeighborArray neighbors;
38+
int correct_triangle_orientations;
3839

3940
if (!PyArg_ParseTuple(args,
40-
"O&O&O&O&O&O&",
41+
"O&O&O&O&O&O&i",
4142
&x.converter, &x,
4243
&y.converter, &y,
4344
&triangles.converter, &triangles,
4445
&mask.converter, &mask,
4546
&edges.converter, &edges,
46-
&neighbors.converter, &neighbors)) {
47+
&neighbors.converter, &neighbors,
48+
&correct_triangle_orientations)) {
4749
return -1;
4850
}
4951

@@ -80,7 +82,8 @@ static int PyTriangulation_init(PyTriangulation* self, PyObject* args, PyObject*
8082

8183
CALL_CPP_INIT("Triangulation",
8284
(self->ptr = new Triangulation(x, y, triangles, mask,
83-
edges, neighbors)));
85+
edges, neighbors,
86+
correct_triangle_orientations)));
8487
return 0;
8588
}
8689

lib/matplotlib/tri/triangulation.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def get_cpp_triangulation(self):
107107
if self._cpp_triangulation is None:
108108
self._cpp_triangulation = _tri.Triangulation(
109109
self.x, self.y, self.triangles, self.mask, self._edges,
110-
self._neighbors)
110+
self._neighbors, not self.is_delaunay)
111111
return self._cpp_triangulation
112112

113113
def get_masked_triangles(self):

0 commit comments

Comments
 (0)