| 1 | /**************************************************************************/ |
| 2 | /* triangulate.cpp */ |
| 3 | /**************************************************************************/ |
| 4 | /* This file is part of: */ |
| 5 | /* GODOT ENGINE */ |
| 6 | /* https://godotengine.org */ |
| 7 | /**************************************************************************/ |
| 8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
| 9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
| 10 | /* */ |
| 11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
| 12 | /* a copy of this software and associated documentation files (the */ |
| 13 | /* "Software"), to deal in the Software without restriction, including */ |
| 14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
| 15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
| 16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
| 17 | /* the following conditions: */ |
| 18 | /* */ |
| 19 | /* The above copyright notice and this permission notice shall be */ |
| 20 | /* included in all copies or substantial portions of the Software. */ |
| 21 | /* */ |
| 22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
| 23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
| 24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
| 25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
| 26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
| 27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
| 28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
| 29 | /**************************************************************************/ |
| 30 | |
| 31 | #include "triangulate.h" |
| 32 | |
| 33 | real_t Triangulate::get_area(const Vector<Vector2> &contour) { |
| 34 | int n = contour.size(); |
| 35 | const Vector2 *c = &contour[0]; |
| 36 | |
| 37 | real_t A = 0.0; |
| 38 | |
| 39 | for (int p = n - 1, q = 0; q < n; p = q++) { |
| 40 | A += c[p].cross(c[q]); |
| 41 | } |
| 42 | return A * 0.5f; |
| 43 | } |
| 44 | |
| 45 | /* `is_inside_triangle` decides if a point P is inside the triangle |
| 46 | * defined by A, B, C. */ |
| 47 | bool Triangulate::is_inside_triangle(real_t Ax, real_t Ay, |
| 48 | real_t Bx, real_t By, |
| 49 | real_t Cx, real_t Cy, |
| 50 | real_t Px, real_t Py, |
| 51 | bool include_edges) { |
| 52 | real_t ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy; |
| 53 | real_t cCROSSap, bCROSScp, aCROSSbp; |
| 54 | |
| 55 | ax = Cx - Bx; |
| 56 | ay = Cy - By; |
| 57 | bx = Ax - Cx; |
| 58 | by = Ay - Cy; |
| 59 | cx = Bx - Ax; |
| 60 | cy = By - Ay; |
| 61 | apx = Px - Ax; |
| 62 | apy = Py - Ay; |
| 63 | bpx = Px - Bx; |
| 64 | bpy = Py - By; |
| 65 | cpx = Px - Cx; |
| 66 | cpy = Py - Cy; |
| 67 | |
| 68 | aCROSSbp = ax * bpy - ay * bpx; |
| 69 | cCROSSap = cx * apy - cy * apx; |
| 70 | bCROSScp = bx * cpy - by * cpx; |
| 71 | |
| 72 | if (include_edges) { |
| 73 | return ((aCROSSbp > 0.0f) && (bCROSScp > 0.0f) && (cCROSSap > 0.0f)); |
| 74 | } else { |
| 75 | return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | bool Triangulate::snip(const Vector<Vector2> &p_contour, int u, int v, int w, int n, const Vector<int> &V, bool relaxed) { |
| 80 | int p; |
| 81 | real_t Ax, Ay, Bx, By, Cx, Cy, Px, Py; |
| 82 | const Vector2 *contour = &p_contour[0]; |
| 83 | |
| 84 | Ax = contour[V[u]].x; |
| 85 | Ay = contour[V[u]].y; |
| 86 | |
| 87 | Bx = contour[V[v]].x; |
| 88 | By = contour[V[v]].y; |
| 89 | |
| 90 | Cx = contour[V[w]].x; |
| 91 | Cy = contour[V[w]].y; |
| 92 | |
| 93 | // It can happen that the triangulation ends up with three aligned vertices to deal with. |
| 94 | // In this scenario, making the check below strict may reject the possibility of |
| 95 | // forming a last triangle with these aligned vertices, preventing the triangulation |
| 96 | // from completing. |
| 97 | // To avoid that we allow zero-area triangles if all else failed. |
| 98 | float threshold = relaxed ? -CMP_EPSILON : CMP_EPSILON; |
| 99 | |
| 100 | if (threshold > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) { |
| 101 | return false; |
| 102 | } |
| 103 | |
| 104 | for (p = 0; p < n; p++) { |
| 105 | if ((p == u) || (p == v) || (p == w)) { |
| 106 | continue; |
| 107 | } |
| 108 | Px = contour[V[p]].x; |
| 109 | Py = contour[V[p]].y; |
| 110 | if (is_inside_triangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py, relaxed)) { |
| 111 | return false; |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | return true; |
| 116 | } |
| 117 | |
| 118 | bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &result) { |
| 119 | /* allocate and initialize list of Vertices in polygon */ |
| 120 | |
| 121 | int n = contour.size(); |
| 122 | if (n < 3) { |
| 123 | return false; |
| 124 | } |
| 125 | |
| 126 | Vector<int> V; |
| 127 | V.resize(n); |
| 128 | |
| 129 | /* we want a counter-clockwise polygon in V */ |
| 130 | |
| 131 | if (0.0f < get_area(contour)) { |
| 132 | for (int v = 0; v < n; v++) { |
| 133 | V.write[v] = v; |
| 134 | } |
| 135 | } else { |
| 136 | for (int v = 0; v < n; v++) { |
| 137 | V.write[v] = (n - 1) - v; |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | bool relaxed = false; |
| 142 | |
| 143 | int nv = n; |
| 144 | |
| 145 | /* remove nv-2 Vertices, creating 1 triangle every time */ |
| 146 | int count = 2 * nv; /* error detection */ |
| 147 | |
| 148 | for (int v = nv - 1; nv > 2;) { |
| 149 | /* if we loop, it is probably a non-simple polygon */ |
| 150 | if (0 >= (count--)) { |
| 151 | if (relaxed) { |
| 152 | //** Triangulate: ERROR - probable bad polygon! |
| 153 | return false; |
| 154 | } else { |
| 155 | // There may be aligned vertices that the strict |
| 156 | // checks prevent from triangulating. In this situation |
| 157 | // we are better off adding flat triangles than |
| 158 | // failing, so we relax the checks and try one last |
| 159 | // round. |
| 160 | // Only relaxing the constraints as a last resort avoids |
| 161 | // degenerate triangles when they aren't necessary. |
| 162 | count = 2 * nv; |
| 163 | relaxed = true; |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | /* three consecutive vertices in current polygon, <u,v,w> */ |
| 168 | int u = v; |
| 169 | if (nv <= u) { |
| 170 | u = 0; /* previous */ |
| 171 | } |
| 172 | v = u + 1; |
| 173 | if (nv <= v) { |
| 174 | v = 0; /* new v */ |
| 175 | } |
| 176 | int w = v + 1; |
| 177 | if (nv <= w) { |
| 178 | w = 0; /* next */ |
| 179 | } |
| 180 | |
| 181 | if (snip(contour, u, v, w, nv, V, relaxed)) { |
| 182 | int a, b, c, s, t; |
| 183 | |
| 184 | /* true names of the vertices */ |
| 185 | a = V[u]; |
| 186 | b = V[v]; |
| 187 | c = V[w]; |
| 188 | |
| 189 | /* output Triangle */ |
| 190 | result.push_back(a); |
| 191 | result.push_back(b); |
| 192 | result.push_back(c); |
| 193 | |
| 194 | /* remove v from remaining polygon */ |
| 195 | for (s = v, t = v + 1; t < nv; s++, t++) { |
| 196 | V.write[s] = V[t]; |
| 197 | } |
| 198 | |
| 199 | nv--; |
| 200 | |
| 201 | /* reset error detection counter */ |
| 202 | count = 2 * nv; |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | return true; |
| 207 | } |
| 208 | |