Triangle.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import Coordinate from './Coordinate'
  2. import IllegalArgumentException from '../../../../java/lang/IllegalArgumentException'
  3. import DD from '../math/DD'
  4. import Angle from '../algorithm/Angle'
  5. import HCoordinate from '../algorithm/HCoordinate'
  6. export default class Triangle {
  7. constructor() {
  8. Triangle.constructor_.apply(this, arguments)
  9. }
  10. static constructor_() {
  11. this.p0 = null
  12. this.p1 = null
  13. this.p2 = null
  14. const p0 = arguments[0], p1 = arguments[1], p2 = arguments[2]
  15. this.p0 = p0
  16. this.p1 = p1
  17. this.p2 = p2
  18. }
  19. static area(a, b, c) {
  20. return Math.abs(((c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y)) / 2)
  21. }
  22. static signedArea(a, b, c) {
  23. return ((c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y)) / 2
  24. }
  25. static det(m00, m01, m10, m11) {
  26. return m00 * m11 - m01 * m10
  27. }
  28. static interpolateZ(p, v0, v1, v2) {
  29. const x0 = v0.x
  30. const y0 = v0.y
  31. const a = v1.x - x0
  32. const b = v2.x - x0
  33. const c = v1.y - y0
  34. const d = v2.y - y0
  35. const det = a * d - b * c
  36. const dx = p.x - x0
  37. const dy = p.y - y0
  38. const t = (d * dx - b * dy) / det
  39. const u = (-c * dx + a * dy) / det
  40. const z = v0.getZ() + t * (v1.getZ() - v0.getZ()) + u * (v2.getZ() - v0.getZ())
  41. return z
  42. }
  43. static longestSideLength(a, b, c) {
  44. const lenAB = a.distance(b)
  45. const lenBC = b.distance(c)
  46. const lenCA = c.distance(a)
  47. let maxLen = lenAB
  48. if (lenBC > maxLen) maxLen = lenBC
  49. if (lenCA > maxLen) maxLen = lenCA
  50. return maxLen
  51. }
  52. static circumcentreDD(a, b, c) {
  53. const ax = DD.valueOf(a.x).subtract(c.x)
  54. const ay = DD.valueOf(a.y).subtract(c.y)
  55. const bx = DD.valueOf(b.x).subtract(c.x)
  56. const by = DD.valueOf(b.y).subtract(c.y)
  57. const denom = DD.determinant(ax, ay, bx, by).multiply(2)
  58. const asqr = ax.sqr().add(ay.sqr())
  59. const bsqr = bx.sqr().add(by.sqr())
  60. const numx = DD.determinant(ay, asqr, by, bsqr)
  61. const numy = DD.determinant(ax, asqr, bx, bsqr)
  62. const ccx = DD.valueOf(c.x).subtract(numx.divide(denom)).doubleValue()
  63. const ccy = DD.valueOf(c.y).add(numy.divide(denom)).doubleValue()
  64. return new Coordinate(ccx, ccy)
  65. }
  66. static isAcute(a, b, c) {
  67. if (!Angle.isAcute(a, b, c)) return false
  68. if (!Angle.isAcute(b, c, a)) return false
  69. if (!Angle.isAcute(c, a, b)) return false
  70. return true
  71. }
  72. static circumcentre(a, b, c) {
  73. const cx = c.x
  74. const cy = c.y
  75. const ax = a.x - cx
  76. const ay = a.y - cy
  77. const bx = b.x - cx
  78. const by = b.y - cy
  79. const denom = 2 * Triangle.det(ax, ay, bx, by)
  80. const numx = Triangle.det(ay, ax * ax + ay * ay, by, bx * bx + by * by)
  81. const numy = Triangle.det(ax, ax * ax + ay * ay, bx, bx * bx + by * by)
  82. const ccx = cx - numx / denom
  83. const ccy = cy + numy / denom
  84. return new Coordinate(ccx, ccy)
  85. }
  86. static perpendicularBisector(a, b) {
  87. const dx = b.x - a.x
  88. const dy = b.y - a.y
  89. const l1 = new HCoordinate(a.x + dx / 2.0, a.y + dy / 2.0, 1.0)
  90. const l2 = new HCoordinate(a.x - dy + dx / 2.0, a.y + dx + dy / 2.0, 1.0)
  91. return new HCoordinate(l1, l2)
  92. }
  93. static angleBisector(a, b, c) {
  94. const len0 = b.distance(a)
  95. const len2 = b.distance(c)
  96. const frac = len0 / (len0 + len2)
  97. const dx = c.x - a.x
  98. const dy = c.y - a.y
  99. const splitPt = new Coordinate(a.x + frac * dx, a.y + frac * dy)
  100. return splitPt
  101. }
  102. static area3D(a, b, c) {
  103. const ux = b.x - a.x
  104. const uy = b.y - a.y
  105. const uz = b.getZ() - a.getZ()
  106. const vx = c.x - a.x
  107. const vy = c.y - a.y
  108. const vz = c.getZ() - a.getZ()
  109. const crossx = uy * vz - uz * vy
  110. const crossy = uz * vx - ux * vz
  111. const crossz = ux * vy - uy * vx
  112. const absSq = crossx * crossx + crossy * crossy + crossz * crossz
  113. const area3D = Math.sqrt(absSq) / 2
  114. return area3D
  115. }
  116. static centroid(a, b, c) {
  117. const x = (a.x + b.x + c.x) / 3
  118. const y = (a.y + b.y + c.y) / 3
  119. return new Coordinate(x, y)
  120. }
  121. static inCentre(a, b, c) {
  122. const len0 = b.distance(c)
  123. const len1 = a.distance(c)
  124. const len2 = a.distance(b)
  125. const circum = len0 + len1 + len2
  126. const inCentreX = (len0 * a.x + len1 * b.x + len2 * c.x) / circum
  127. const inCentreY = (len0 * a.y + len1 * b.y + len2 * c.y) / circum
  128. return new Coordinate(inCentreX, inCentreY)
  129. }
  130. area() {
  131. return Triangle.area(this.p0, this.p1, this.p2)
  132. }
  133. signedArea() {
  134. return Triangle.signedArea(this.p0, this.p1, this.p2)
  135. }
  136. interpolateZ(p) {
  137. if (p === null) throw new IllegalArgumentException('Supplied point is null.')
  138. return Triangle.interpolateZ(p, this.p0, this.p1, this.p2)
  139. }
  140. longestSideLength() {
  141. return Triangle.longestSideLength(this.p0, this.p1, this.p2)
  142. }
  143. isAcute() {
  144. return Triangle.isAcute(this.p0, this.p1, this.p2)
  145. }
  146. circumcentre() {
  147. return Triangle.circumcentre(this.p0, this.p1, this.p2)
  148. }
  149. area3D() {
  150. return Triangle.area3D(this.p0, this.p1, this.p2)
  151. }
  152. centroid() {
  153. return Triangle.centroid(this.p0, this.p1, this.p2)
  154. }
  155. inCentre() {
  156. return Triangle.inCentre(this.p0, this.p1, this.p2)
  157. }
  158. }