Advertisement
Guest User

Untitled

a guest
Mar 2nd, 2017
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.68 KB | None | 0 0
  1. // Copyright (C) 2015 Dominic Charlesworth <dgc336@gmail.com>
  2. // Author: Dominic Charlesworth <dgc336@gmail.com>
  3. // This program is free software; you can redistribute it and/or
  4. // modify it under the terms of the GNU General Public License
  5. // as published by the Free Software Foundation; either version 3
  6. // of the License, or (at your option) any later version.
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU General Public License for more details.
  11. // You should have received a copy of the GNU General Public License
  12. // along with this program. If not, see <dgc336@gmail.com>.
  13.  
  14. function BowyerWatson(pointList) {
  15. var points = pointList.map(function (point) {
  16. return new Point(point.x, point.y);
  17. });
  18. var triangulation = new Triangulation(points);
  19. points.forEach(function (point) {
  20. BowyerWatsonInsert(point, triangulation);
  21. });
  22. return triangulation.edges();
  23. }
  24.  
  25. function BowyerWatsonInsert(point, triangulation) {
  26. var badTriangles = [];
  27. triangulation.triangles.forEach(function (triangle) {
  28. if (triangle.contains(point).inCircumcircle()) {
  29. badTriangles.push(triangle);
  30. }
  31. });
  32. var polygon = [];
  33. badTriangles.forEach(function (triangle) {
  34. triangle.edges.forEach(function (edge) {
  35. if (badTriangles.every(function (t) {
  36. return t === triangle ||
  37. !t.contains(edge).inEdges();
  38. })) {
  39. polygon.push(edge);
  40. }
  41. });
  42. });
  43. badTriangles.forEach(function (triangle) {
  44. triangulation.remove(triangle);
  45. });
  46. polygon.forEach(function (edge) {
  47. triangulation.add(new Triangle(edge.vertices.concat(
  48. point)));
  49. });
  50. }
  51.  
  52. function Triangulation(points) {
  53. this.superTriangle = this.getSuperTriangle(points);
  54. this.triangles = [this.superTriangle];
  55. }
  56. Triangulation.prototype.add = function (triangle) {
  57. this.triangles.push(triangle);
  58. };
  59. Triangulation.prototype.remove = function (triangle) {
  60. var index = this.triangles.indexOf(triangle);
  61. this.triangles.splice(index, 1);
  62. };
  63. Triangulation.prototype.getSuperTriangle = function (points) {
  64. var maxx = Math.max.apply(Math, points.map(function (point) {
  65. return point.x;
  66. }));
  67. var maxy = Math.max.apply(Math, points.map(function (point) {
  68. return point.y;
  69. }));
  70. return new Triangle([
  71. new Point(0, 0),
  72. new Point(maxx * 2, 0),
  73. new Point(0, maxy * 2)
  74. ]);
  75. };
  76. Triangulation.prototype.edges = function () {
  77. var edges = [];
  78. var superVertices = this.superTriangle.vertices;
  79. this.triangles.forEach(function (triangle) {
  80. triangle.edges.forEach(function (edge) {
  81. var element = {
  82. from: edge.vertex(0),
  83. to: edge.vertex(1)
  84. };
  85. if (!(~superVertices.indexOf(element.from) ||
  86. ~superVertices.indexOf(element.to)
  87. )) {
  88. edges.push(element);
  89. }
  90. });
  91. });
  92. return edges;
  93. };
  94.  
  95. function Triangle(vertices) {
  96. this.new = true;
  97. this.vertices = vertices;
  98. this.edges = [
  99. new Vector([this.vertices[0], this.vertices[1]]),
  100. new Vector([this.vertices[0], this.vertices[2]]),
  101. new Vector([this.vertices[1], this.vertices[2]])
  102. ];
  103. this.circumRadius = this.calculateCircumRadius();
  104. this.circumCenter = this.calculateCircumCenter();
  105. }
  106.  
  107. Triangle.prototype.vertex = function (i) {
  108. return this.vertices[i];
  109. };
  110.  
  111. // Calculation methods
  112. Triangle.prototype.calculateCircumRadius = function () {
  113. var a = this.edges[0].length,
  114. b = this.edges[1].length,
  115. c = this.edges[2].length;
  116. var resultant = Math.sqrt((a + b + c) * (b + c - a) * (c + a - b) *
  117. (a + b - c)) || a / 2;
  118. return resultant ? (a * b * c) / resultant : a / 2;
  119. };
  120.  
  121. Triangle.prototype.calculateCircumCenter = function () {
  122. var a = this.vertices[0],
  123. b = this.vertices[1],
  124. c = this.vertices[2];
  125. var D = 2 * ((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x *
  126. (a.y - b.y)));
  127. var Ux = (((Math.pow(a.x, 2) + Math.pow(a.y, 2)) * (b.y - c.y)) +
  128. ((Math.pow(b.x, 2) + Math.pow(b.y, 2)) * (c.y - a.y)) +
  129. ((Math.pow(c.x, 2) + Math.pow(c.y, 2)) * (a.y - b.y))) /
  130. D,
  131. Uy = (((Math.pow(a.x, 2) + Math.pow(a.y, 2)) * (c.x - b.x)) +
  132. ((Math.pow(b.x, 2) + Math.pow(b.y, 2)) * (a.x - c.x)) +
  133. ((Math.pow(c.x, 2) + Math.pow(c.y, 2)) * (b.x - a.x))) /
  134. D;
  135. return new Point(Ux, Uy);
  136. };
  137.  
  138. // Contains methods
  139. Triangle.prototype.contains = function (thing) {
  140. this._contains = thing;
  141. return this;
  142. };
  143. Triangle.prototype.inCircumcircle = function () {
  144. return (new Vector([this.circumCenter, this._contains])).length <=
  145. this.circumRadius ? true : false;
  146. };
  147. Triangle.prototype.inEdges = function () {
  148. var edge = this._contains;
  149. return this.edges.some(function (e) {
  150. return edge.vertices[0] === e.vertices[0] &&
  151. edge.vertices[1] === e.vertices[1];
  152. });
  153. };
  154. Triangle.prototype.inTriangle = function () {
  155. var point = this._contains,
  156. B = this.vertex(1).minus(this.vertex(0)),
  157. C = this.vertex(2).minus(this.vertex(0)),
  158. P = point.minus(this.vertex(0)),
  159. d = (B.x * C.y) - (C.x * B.y);
  160. var weights = [
  161. ((P.x * (B.y - C.y)) + (P.y * (C.x - B.x)) + (B.x * C.y) -
  162. (C.x * B.y)) / d,
  163. ((P.x * C.y) - (P.y * C.x)) / d,
  164. ((P.y * B.x) - (P.x * B.y)) / d
  165. ];
  166. return weights.every(function (w) {
  167. return w >= 0 && w <= 1;
  168. });
  169. };
  170.  
  171. function Vector(vertices) {
  172. this.vertices = vertices;
  173. this.length = this.calculateLength(vertices);
  174. this.midpoint = this.calculateMidpoint(vertices);
  175. }
  176. Vector.prototype.vertex = function (i) {
  177. return this.vertices[i];
  178. };
  179.  
  180. Vector.prototype.calculateLength = function (v) {
  181. return Math.sqrt(Math.pow(Math.abs(v[0].x - v[1].x), 2) +
  182. Math.pow(Math.abs(v[0].y - v[1].y), 2));
  183. };
  184.  
  185. Vector.prototype.calculateMidpoint = function (v) {
  186. return new Point((v[0].x + v[1].x) / 2, (v[0].y + v[1].y) / 2);
  187. };
  188. Vector.prototype.calculateGradient = function (v) {
  189. return (v[1].y - v[0].y) / (v[1].x - v[0].x);
  190. };
  191. Vector.prototype.minus = function (v) {
  192. return new Vector([
  193. new Point(this.vertex(0) - v.vertex(0).x, this.vertex(
  194. 0).y - v.vertex(0).y),
  195. new Point(this.vertex(1) - v.vertex(1).x, this.vertex(
  196. 1).y - v.vertex(1).y)
  197. ]);
  198. };
  199.  
  200. function Point(x, y) {
  201. this.x = x;
  202. this.y = y;
  203. }
  204.  
  205. Point.prototype.minus = function (p) {
  206. return new Point(this.x - p.x, this.y - p.y);
  207. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement