diff --git a/doc/api/api_changes/2017-07-14-IT_qhull_large_offset.rst b/doc/api/api_changes/2017-07-14-IT_qhull_large_offset.rst new file mode 100644 index 000000000000..c60c56c0ff6b --- /dev/null +++ b/doc/api/api_changes/2017-07-14-IT_qhull_large_offset.rst @@ -0,0 +1,10 @@ +Improved Delaunay triangulations with large offsets +``````````````````````````````````````````````````` + +Delaunay triangulations now deal with large x,y offsets in a better +way. This can cause minor changes to any triangulations calculated +using Matplotlib, i.e. any use of `matplotlib.tri.Triangulation` that +requests that a Delaunay triangulation is calculated, which includes +`matplotlib.pyplot.tricontour`, `matplotlib.pyplot.tricontourf`, +`matplotlib.pyplot.tripcolor`, `matplotlib.pyplot.triplot`, +`mlab.griddata` and `mpl_toolkits.mplot3d.plot_trisurf`. diff --git a/lib/matplotlib/tests/baseline_images/test_triangulation/tri_smooth_contouring.png b/lib/matplotlib/tests/baseline_images/test_triangulation/tri_smooth_contouring.png index d6d2b993fd80..80ea47079014 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_triangulation/tri_smooth_contouring.png and b/lib/matplotlib/tests/baseline_images/test_triangulation/tri_smooth_contouring.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_triangulation/tri_smooth_gradient.png b/lib/matplotlib/tests/baseline_images/test_triangulation/tri_smooth_gradient.png index 52b0d21362e4..956eadf30c59 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_triangulation/tri_smooth_gradient.png and b/lib/matplotlib/tests/baseline_images/test_triangulation/tri_smooth_gradient.png differ diff --git a/lib/matplotlib/tests/test_triangulation.py b/lib/matplotlib/tests/test_triangulation.py index 18969afacf39..6dc2078f1384 100644 --- a/lib/matplotlib/tests/test_triangulation.py +++ b/lib/matplotlib/tests/test_triangulation.py @@ -745,7 +745,7 @@ def z(x, y): @image_comparison(baseline_images=['tri_smooth_contouring'], - extensions=['png'], remove_text=True) + extensions=['png'], remove_text=True, tol=0.07) def test_tri_smooth_contouring(): # Image comparison based on example tricontour_smooth_user. n_angles = 20 @@ -786,8 +786,7 @@ def z(x, y): @image_comparison(baseline_images=['tri_smooth_gradient'], - extensions=['png'], remove_text=True, - tol=0.03 if on_win else 0) + extensions=['png'], remove_text=True, tol=0.035) def test_tri_smooth_gradient(): # Image comparison based on example trigradient_demo. @@ -1123,3 +1122,14 @@ def test_internal_cpp_api(): with pytest.raises(ValueError) as excinfo: trifinder.find_many([0], [0, 1]) excinfo.match(r'x and y must be array_like with same shape') + + +def test_qhull_large_offset(): + # github issue 8682. + x = np.asarray([0, 1, 0, 1, 0.5]) + y = np.asarray([0, 0, 1, 1, 0.5]) + + offset = 1e10 + triang = mtri.Triangulation(x, y) + triang_offset = mtri.Triangulation(x + offset, y + offset) + assert len(triang.triangles) == len(triang_offset.triangles) diff --git a/src/qhull_wrap.c b/src/qhull_wrap.c index 38779441b4fd..e71afc7e3700 100644 --- a/src/qhull_wrap.c +++ b/src/qhull_wrap.c @@ -108,6 +108,8 @@ delaunay_impl(int npoints, const double* x, const double* y, PyArrayObject* neighbors = NULL; int* triangles_ptr; int* neighbors_ptr; + double x_mean = 0.0; + double y_mean = 0.0; QHULL_LIB_CHECK @@ -119,10 +121,18 @@ delaunay_impl(int npoints, const double* x, const double* y, goto error_before_qhull; } + /* Determine mean x, y coordinates. */ + for (i = 0; i < npoints; ++i) { + x_mean += x[i]; + y_mean += y[i]; + } + x_mean /= npoints; + y_mean /= npoints; + /* Prepare points array to pass to qhull. */ for (i = 0; i < npoints; ++i) { - points[2*i ] = x[i]; - points[2*i+1] = y[i]; + points[2*i ] = x[i] - x_mean; + points[2*i+1] = y[i] - y_mean; } /* qhull expects a FILE* to write errors to. */