Vertex.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. import NotRepresentableException from '../../algorithm/NotRepresentableException'
  2. import Coordinate from '../../geom/Coordinate'
  3. import TrianglePredicate from './TrianglePredicate'
  4. import System from '../../../../../java/lang/System'
  5. import HCoordinate from '../../algorithm/HCoordinate'
  6. export default class Vertex {
  7. constructor() {
  8. Vertex.constructor_.apply(this, arguments)
  9. }
  10. static constructor_() {
  11. this._p = null
  12. if (arguments.length === 1) {
  13. const _p = arguments[0]
  14. this._p = new Coordinate(_p)
  15. } else if (arguments.length === 2) {
  16. const _x = arguments[0], _y = arguments[1]
  17. this._p = new Coordinate(_x, _y)
  18. } else if (arguments.length === 3) {
  19. const _x = arguments[0], _y = arguments[1], _z = arguments[2]
  20. this._p = new Coordinate(_x, _y, _z)
  21. }
  22. }
  23. static interpolateZ() {
  24. if (arguments.length === 3) {
  25. const p = arguments[0], p0 = arguments[1], p1 = arguments[2]
  26. const segLen = p0.distance(p1)
  27. const ptLen = p.distance(p0)
  28. const dz = p1.getZ() - p0.getZ()
  29. const pz = p0.getZ() + dz * (ptLen / segLen)
  30. return pz
  31. } else if (arguments.length === 4) {
  32. const p = arguments[0], v0 = arguments[1], v1 = arguments[2], v2 = arguments[3]
  33. const x0 = v0.x
  34. const y0 = v0.y
  35. const a = v1.x - x0
  36. const b = v2.x - x0
  37. const c = v1.y - y0
  38. const d = v2.y - y0
  39. const det = a * d - b * c
  40. const dx = p.x - x0
  41. const dy = p.y - y0
  42. const t = (d * dx - b * dy) / det
  43. const u = (-c * dx + a * dy) / det
  44. const z = v0.getZ() + t * (v1.getZ() - v0.getZ()) + u * (v2.getZ() - v0.getZ())
  45. return z
  46. }
  47. }
  48. circleCenter(b, c) {
  49. const a = new Vertex(this.getX(), this.getY())
  50. const cab = this.bisector(a, b)
  51. const cbc = this.bisector(b, c)
  52. const hcc = new HCoordinate(cab, cbc)
  53. let cc = null
  54. try {
  55. cc = new Vertex(hcc.getX(), hcc.getY())
  56. } catch (nre) {
  57. if (nre instanceof NotRepresentableException) {
  58. System.err.println('a: ' + a + ' b: ' + b + ' c: ' + c)
  59. System.err.println(nre)
  60. } else {
  61. throw nre
  62. }
  63. } finally {}
  64. return cc
  65. }
  66. dot(v) {
  67. return this._p.x * v.getX() + this._p.y * v.getY()
  68. }
  69. magn() {
  70. return Math.sqrt(this._p.x * this._p.x + this._p.y * this._p.y)
  71. }
  72. getZ() {
  73. return this._p.getZ()
  74. }
  75. bisector(a, b) {
  76. const dx = b.getX() - a.getX()
  77. const dy = b.getY() - a.getY()
  78. const l1 = new HCoordinate(a.getX() + dx / 2.0, a.getY() + dy / 2.0, 1.0)
  79. const l2 = new HCoordinate(a.getX() - dy + dx / 2.0, a.getY() + dx + dy / 2.0, 1.0)
  80. return new HCoordinate(l1, l2)
  81. }
  82. equals() {
  83. if (arguments.length === 1) {
  84. const _x = arguments[0]
  85. if (this._p.x === _x.getX() && this._p.y === _x.getY())
  86. return true
  87. else
  88. return false
  89. } else if (arguments.length === 2) {
  90. const _x = arguments[0], tolerance = arguments[1]
  91. if (this._p.distance(_x.getCoordinate()) < tolerance)
  92. return true
  93. else
  94. return false
  95. }
  96. }
  97. getCoordinate() {
  98. return this._p
  99. }
  100. isInCircle(a, b, c) {
  101. return TrianglePredicate.isInCircleRobust(a._p, b._p, c._p, this._p)
  102. }
  103. interpolateZValue(v0, v1, v2) {
  104. const x0 = v0.getX()
  105. const y0 = v0.getY()
  106. const a = v1.getX() - x0
  107. const b = v2.getX() - x0
  108. const c = v1.getY() - y0
  109. const d = v2.getY() - y0
  110. const det = a * d - b * c
  111. const dx = this.getX() - x0
  112. const dy = this.getY() - y0
  113. const t = (d * dx - b * dy) / det
  114. const u = (-c * dx + a * dy) / det
  115. const z = v0.getZ() + t * (v1.getZ() - v0.getZ()) + u * (v2.getZ() - v0.getZ())
  116. return z
  117. }
  118. midPoint(a) {
  119. const xm = (this._p.x + a.getX()) / 2.0
  120. const ym = (this._p.y + a.getY()) / 2.0
  121. const zm = (this._p.getZ() + a.getZ()) / 2.0
  122. return new Vertex(xm, ym, zm)
  123. }
  124. rightOf(e) {
  125. return this.isCCW(e.dest(), e.orig())
  126. }
  127. isCCW(b, c) {
  128. return (b._p.x - this._p.x) * (c._p.y - this._p.y) - (b._p.y - this._p.y) * (c._p.x - this._p.x) > 0
  129. }
  130. getX() {
  131. return this._p.x
  132. }
  133. crossProduct(v) {
  134. return this._p.x * v.getY() - this._p.y * v.getX()
  135. }
  136. setZ(_z) {
  137. this._p.setZ(_z)
  138. }
  139. times(c) {
  140. return new Vertex(c * this._p.x, c * this._p.y)
  141. }
  142. cross() {
  143. return new Vertex(this._p.y, -this._p.x)
  144. }
  145. leftOf(e) {
  146. return this.isCCW(e.orig(), e.dest())
  147. }
  148. toString() {
  149. return 'POINT (' + this._p.x + ' ' + this._p.y + ')'
  150. }
  151. sub(v) {
  152. return new Vertex(this._p.x - v.getX(), this._p.y - v.getY())
  153. }
  154. getY() {
  155. return this._p.y
  156. }
  157. classify(p0, p1) {
  158. const p2 = this
  159. const a = p1.sub(p0)
  160. const b = p2.sub(p0)
  161. const sa = a.crossProduct(b)
  162. if (sa > 0.0) return Vertex.LEFT
  163. if (sa < 0.0) return Vertex.RIGHT
  164. if (a.getX() * b.getX() < 0.0 || a.getY() * b.getY() < 0.0) return Vertex.BEHIND
  165. if (a.magn() < b.magn()) return Vertex.BEYOND
  166. if (p0.equals(p2)) return Vertex.ORIGIN
  167. if (p1.equals(p2)) return Vertex.DESTINATION
  168. return Vertex.BETWEEN
  169. }
  170. sum(v) {
  171. return new Vertex(this._p.x + v.getX(), this._p.y + v.getY())
  172. }
  173. distance(v1, v2) {
  174. return Math.sqrt(Math.pow(v2.getX() - v1.getX(), 2.0) + Math.pow(v2.getY() - v1.getY(), 2.0))
  175. }
  176. circumRadiusRatio(b, c) {
  177. const x = this.circleCenter(b, c)
  178. const radius = this.distance(x, b)
  179. let edgeLength = this.distance(this, b)
  180. let el = this.distance(b, c)
  181. if (el < edgeLength)
  182. edgeLength = el
  183. el = this.distance(c, this)
  184. if (el < edgeLength)
  185. edgeLength = el
  186. return radius / edgeLength
  187. }
  188. }
  189. Vertex.LEFT = 0
  190. Vertex.RIGHT = 1
  191. Vertex.BEYOND = 2
  192. Vertex.BEHIND = 3
  193. Vertex.BETWEEN = 4
  194. Vertex.ORIGIN = 5
  195. Vertex.DESTINATION = 6