| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 0cf4085 commit 47dded2
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,7 @@ | |||
| 10 | 10 | from nose.tools import assert_raises, assert_equal | |
| 11 | 11 | from matplotlib.testing.decorators import image_comparison | |
| 12 | 12 | import matplotlib.pyplot as plt | |
| 13 | + from matplotlib import transforms | ||
| 13 | 14 | ||
| 14 | 15 | ||
| 15 | 16 | def test_readonly_path(): | |
@@ -111,6 +112,41 @@ def test_marker_paths_pdf(): | |||
| 111 | 112 | plt.ylim(-1, 7) | |
| 112 | 113 | ||
| 113 | 114 | ||
| 115 | + def test_path_no_doubled_point_in_to_polygon(): | ||
| 116 | + hand = np.array( | ||
| 117 | + [[1.64516129, 1.16145833], | ||
| 118 | + [1.64516129, 1.59375], | ||
| 119 | + [1.35080645, 1.921875], | ||
| 120 | + [1.375, 2.18229167], | ||
| 121 | + [1.68548387, 1.9375], | ||
| 122 | + [1.60887097, 2.55208333], | ||
| 123 | + [1.68548387, 2.69791667], | ||
| 124 | + [1.76209677, 2.56770833], | ||
| 125 | + [1.83064516, 1.97395833], | ||
| 126 | + [1.89516129, 2.75], | ||
| 127 | + [1.9516129, 2.84895833], | ||
| 128 | + [2.01209677, 2.76041667], | ||
| 129 | + [1.99193548, 1.99479167], | ||
| 130 | + [2.11290323, 2.63020833], | ||
| 131 | + [2.2016129, 2.734375], | ||
| 132 | + [2.25403226, 2.60416667], | ||
| 133 | + [2.14919355, 1.953125], | ||
| 134 | + [2.30645161, 2.36979167], | ||
| 135 | + [2.39112903, 2.36979167], | ||
| 136 | + [2.41532258, 2.1875], | ||
| 137 | + [2.1733871, 1.703125], | ||
| 138 | + [2.07782258, 1.16666667]]) | ||
| 139 | + | ||
| 140 | + (r0, c0, r1, c1) = (1.0, 1.5, 2.1, 2.5) | ||
| 141 | + | ||
| 142 | + poly = Path(np.vstack((hand[:, 1], hand[:, 0])).T, closed=True) | ||
| 143 | + clip_rect = transforms.Bbox([[r0, c0], [r1, c1]]) | ||
| 144 | + poly_clipped = poly.clip_to_bbox(clip_rect).to_polygons()[0] | ||
| 145 | + | ||
| 146 | + assert np.all(poly_clipped[-2] != poly_clipped[-1]) | ||
| 147 | + assert np.all(poly_clipped[-1] == poly_clipped[0]) | ||
| 148 | + | ||
| 149 | + | ||
| 114 | 150 | if __name__ == '__main__': | |
| 115 | 151 | import nose | |
| 116 | 152 | nose.runmodule(argv=['-s', '--with-doctest'], exit=False) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -162,7 +162,7 @@ def onselect(epress, erelease): | |||
| 162 | 162 | extents = [int(e) for e in tool.extents] | |
| 163 | 163 | assert extents == [70, 129, 70, 130], extents | |
| 164 | 164 | ||
| 165 | - assert tool.geometry.shape == (2, 74) | ||
| 165 | + assert tool.geometry.shape == (2, 73) | ||
| 166 | 166 | assert_allclose(tool.geometry[:, 0], [70., 100]) | |
| 167 | 167 | ||
| 168 | 168 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -245,7 +245,7 @@ def on_clicked(self, func): | |||
| 245 | 245 | """ | |
| 246 | 246 | When the button is clicked, call this *func* with event. | |
| 247 | 247 | ||
| 248 | - A connection id is returned. It can be used to disconnect | ||
| 248 | + A connection id is returned. It can be used to disconnect | ||
| 249 | 249 | the button from its callback. | |
| 250 | 250 | """ | |
| 251 | 251 | cid = self.cnt | |
@@ -265,7 +265,7 @@ class Slider(AxesWidget): | |||
| 265 | 265 | """ | |
| 266 | 266 | A slider representing a floating point range. | |
| 267 | 267 | ||
| 268 | - For the slider to remain responsive you must maintain a | ||
| 268 | + For the slider to remain responsive you must maintain a | ||
| 269 | 269 | reference to it. | |
| 270 | 270 | ||
| 271 | 271 | The following attributes are defined | |
@@ -2036,7 +2036,7 @@ def geometry(self): | |||
| 2036 | 2036 | if hasattr(self.to_draw, 'get_verts'): | |
| 2037 | 2037 | xfm = self.ax.transData.inverted() | |
| 2038 | 2038 | y, x = xfm.transform(self.to_draw.get_verts()).T | |
| 2039 | - return np.array([x[:-1], y[:-1]]) | ||
| 2039 | + return np.array([x, y]) | ||
| 2040 | 2040 | else: | |
| 2041 | 2041 | return np.array(self.to_draw.get_data()) | |
| 2042 | 2042 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,6 +27,16 @@ struct XY | |||
| 27 | 27 | XY(double x_, double y_) : x(x_), y(y_) | |
| 28 | 28 | { | |
| 29 | 29 | } | |
| 30 | + | ||
| 31 | + bool operator==(const XY& o) | ||
| 32 | + { | ||
| 33 | + return (x == o.x && y == o.y); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + bool operator!=(const XY& o) | ||
| 37 | + { | ||
| 38 | + return (x != o.x || y != o.y); | ||
| 39 | + } | ||
| 30 | 40 | }; | |
| 31 | 41 | ||
| 32 | 42 | // | |
@@ -838,6 +848,25 @@ bool path_intersects_path(PathIterator1 &p1, PathIterator2 &p2) | |||
| 838 | 848 | return false; | |
| 839 | 849 | } | |
| 840 | 850 | ||
| 851 | + void _finalize_polygon(std::vector<Polygon> &result) | ||
| 852 | + { | ||
| 853 | + Polygon &polygon = result.back(); | ||
| 854 | + | ||
| 855 | + if (result.size() == 0) { | ||
| 856 | + return; | ||
| 857 | + } | ||
| 858 | + | ||
| 859 | + /* Clean up the last polygon in the result. If less than a | ||
| 860 | + triangle, remove it. */ | ||
| 861 | + if (polygon.size() < 3) { | ||
| 862 | + result.pop_back(); | ||
| 863 | + } else { | ||
| 864 | + if (polygon.front() != polygon.back()) { | ||
| 865 | + polygon.push_back(polygon.front()); | ||
| 866 | + } | ||
| 867 | + } | ||
| 868 | + } | ||
| 869 | + | ||
| 841 | 870 | template <class PathIterator> | |
| 842 | 871 | void convert_path_to_polygons(PathIterator &path, | |
| 843 | 872 | agg::trans_affine &trans, | |
@@ -867,24 +896,20 @@ void convert_path_to_polygons(PathIterator &path, | |||
| 867 | 896 | ||
| 868 | 897 | while ((code = curve.vertex(&x, &y)) != agg::path_cmd_stop) { | |
| 869 | 898 | if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) { | |
| 870 | - if (polygon->size() >= 1) { | ||
| 871 | - polygon->push_back((*polygon)[0]); | ||
| 872 | - result.push_back(Polygon()); | ||
| 873 | - polygon = &result.back(); | ||
| 874 | - } | ||
| 899 | + _finalize_polygon(result); | ||
| 900 | + result.push_back(Polygon()); | ||
| 901 | + polygon = &result.back(); | ||
| 875 | 902 | } else { | |
| 876 | - if (code == agg::path_cmd_move_to && polygon->size() >= 1) { | ||
| 877 | - polygon->push_back((*polygon)[0]); | ||
| 903 | + if (code == agg::path_cmd_move_to) { | ||
| 904 | + _finalize_polygon(result); | ||
| 878 | 905 | result.push_back(Polygon()); | |
| 879 | 906 | polygon = &result.back(); | |
| 880 | 907 | } | |
| 881 | 908 | polygon->push_back(XY(x, y)); | |
| 882 | 909 | } | |
| 883 | 910 | } | |
| 884 | 911 | ||
| 885 | - if (polygon->size() == 0) { | ||
| 886 | - result.pop_back(); | ||
| 887 | - } | ||
| 912 | + _finalize_polygon(result); | ||
| 888 | 913 | } | |
| 889 | 914 | ||
| 890 | 915 | template <class VertexSource> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,16 +8,29 @@ | |||
| 8 | 8 | PyObject *convert_polygon_vector(std::vector<Polygon> &polygons) | |
| 9 | 9 | { | |
| 10 | 10 | PyObject *pyresult = PyList_New(polygons.size()); | |
| 11 | + bool fix_endpoints; | ||
| 11 | 12 | ||
| 12 | 13 | for (size_t i = 0; i < polygons.size(); ++i) { | |
| 13 | 14 | Polygon poly = polygons[i]; | |
| 14 | - npy_intp dims[] = {(npy_intp)poly.size() + 1, 2 }; | ||
| 15 | - numpy::array_view<double, 2> subresult(dims); | ||
| 15 | + npy_intp dims[2]; | ||
| 16 | + dims[1] = 2; | ||
| 17 | + | ||
| 18 | + if (poly.front() != poly.back()) { | ||
| 19 | + /* Make last point same as first, if not already */ | ||
| 20 | + dims[0] = (npy_intp)poly.size() + 1; | ||
| 21 | + fix_endpoints = true; | ||
| 22 | + } else { | ||
| 23 | + dims[0] = (npy_intp)poly.size(); | ||
| 24 | + fix_endpoints = false; | ||
| 25 | + } | ||
| 16 | 26 | ||
| 17 | - /* Make last point same as first. */ | ||
| 27 | + numpy::array_view<double, 2> subresult(dims); | ||
| 18 | 28 | memcpy(subresult.data(), &poly[0], sizeof(double) * poly.size() * 2); | |
| 19 | - subresult(poly.size(), 0) = poly[0].x; | ||
| 20 | - subresult(poly.size(), 1) = poly[0].y; | ||
| 29 | + | ||
| 30 | + if (fix_endpoints) { | ||
| 31 | + subresult(poly.size(), 0) = poly.front().x; | ||
| 32 | + subresult(poly.size(), 1) = poly.front().y; | ||
| 33 | + } | ||
| 21 | 34 | ||
| 22 | 35 | if (PyList_SetItem(pyresult, i, subresult.pyobj())) { | |
| 23 | 36 | Py_DECREF(pyresult); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments