| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- import Coordinate from './Coordinate'
- import IllegalArgumentException from '../../../../java/lang/IllegalArgumentException'
- import DD from '../math/DD'
- import Angle from '../algorithm/Angle'
- import HCoordinate from '../algorithm/HCoordinate'
- export default class Triangle {
- constructor() {
- Triangle.constructor_.apply(this, arguments)
- }
- static constructor_() {
- this.p0 = null
- this.p1 = null
- this.p2 = null
- const p0 = arguments[0], p1 = arguments[1], p2 = arguments[2]
- this.p0 = p0
- this.p1 = p1
- this.p2 = p2
- }
- static area(a, b, c) {
- return Math.abs(((c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y)) / 2)
- }
- static signedArea(a, b, c) {
- return ((c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y)) / 2
- }
- static det(m00, m01, m10, m11) {
- return m00 * m11 - m01 * m10
- }
- static interpolateZ(p, v0, v1, v2) {
- const x0 = v0.x
- const y0 = v0.y
- const a = v1.x - x0
- const b = v2.x - x0
- const c = v1.y - y0
- const d = v2.y - y0
- const det = a * d - b * c
- const dx = p.x - x0
- const dy = p.y - y0
- const t = (d * dx - b * dy) / det
- const u = (-c * dx + a * dy) / det
- const z = v0.getZ() + t * (v1.getZ() - v0.getZ()) + u * (v2.getZ() - v0.getZ())
- return z
- }
- static longestSideLength(a, b, c) {
- const lenAB = a.distance(b)
- const lenBC = b.distance(c)
- const lenCA = c.distance(a)
- let maxLen = lenAB
- if (lenBC > maxLen) maxLen = lenBC
- if (lenCA > maxLen) maxLen = lenCA
- return maxLen
- }
- static circumcentreDD(a, b, c) {
- const ax = DD.valueOf(a.x).subtract(c.x)
- const ay = DD.valueOf(a.y).subtract(c.y)
- const bx = DD.valueOf(b.x).subtract(c.x)
- const by = DD.valueOf(b.y).subtract(c.y)
- const denom = DD.determinant(ax, ay, bx, by).multiply(2)
- const asqr = ax.sqr().add(ay.sqr())
- const bsqr = bx.sqr().add(by.sqr())
- const numx = DD.determinant(ay, asqr, by, bsqr)
- const numy = DD.determinant(ax, asqr, bx, bsqr)
- const ccx = DD.valueOf(c.x).subtract(numx.divide(denom)).doubleValue()
- const ccy = DD.valueOf(c.y).add(numy.divide(denom)).doubleValue()
- return new Coordinate(ccx, ccy)
- }
- static isAcute(a, b, c) {
- if (!Angle.isAcute(a, b, c)) return false
- if (!Angle.isAcute(b, c, a)) return false
- if (!Angle.isAcute(c, a, b)) return false
- return true
- }
- static circumcentre(a, b, c) {
- const cx = c.x
- const cy = c.y
- const ax = a.x - cx
- const ay = a.y - cy
- const bx = b.x - cx
- const by = b.y - cy
- const denom = 2 * Triangle.det(ax, ay, bx, by)
- const numx = Triangle.det(ay, ax * ax + ay * ay, by, bx * bx + by * by)
- const numy = Triangle.det(ax, ax * ax + ay * ay, bx, bx * bx + by * by)
- const ccx = cx - numx / denom
- const ccy = cy + numy / denom
- return new Coordinate(ccx, ccy)
- }
- static perpendicularBisector(a, b) {
- const dx = b.x - a.x
- const dy = b.y - a.y
- const l1 = new HCoordinate(a.x + dx / 2.0, a.y + dy / 2.0, 1.0)
- const l2 = new HCoordinate(a.x - dy + dx / 2.0, a.y + dx + dy / 2.0, 1.0)
- return new HCoordinate(l1, l2)
- }
- static angleBisector(a, b, c) {
- const len0 = b.distance(a)
- const len2 = b.distance(c)
- const frac = len0 / (len0 + len2)
- const dx = c.x - a.x
- const dy = c.y - a.y
- const splitPt = new Coordinate(a.x + frac * dx, a.y + frac * dy)
- return splitPt
- }
- static area3D(a, b, c) {
- const ux = b.x - a.x
- const uy = b.y - a.y
- const uz = b.getZ() - a.getZ()
- const vx = c.x - a.x
- const vy = c.y - a.y
- const vz = c.getZ() - a.getZ()
- const crossx = uy * vz - uz * vy
- const crossy = uz * vx - ux * vz
- const crossz = ux * vy - uy * vx
- const absSq = crossx * crossx + crossy * crossy + crossz * crossz
- const area3D = Math.sqrt(absSq) / 2
- return area3D
- }
- static centroid(a, b, c) {
- const x = (a.x + b.x + c.x) / 3
- const y = (a.y + b.y + c.y) / 3
- return new Coordinate(x, y)
- }
- static inCentre(a, b, c) {
- const len0 = b.distance(c)
- const len1 = a.distance(c)
- const len2 = a.distance(b)
- const circum = len0 + len1 + len2
- const inCentreX = (len0 * a.x + len1 * b.x + len2 * c.x) / circum
- const inCentreY = (len0 * a.y + len1 * b.y + len2 * c.y) / circum
- return new Coordinate(inCentreX, inCentreY)
- }
- area() {
- return Triangle.area(this.p0, this.p1, this.p2)
- }
- signedArea() {
- return Triangle.signedArea(this.p0, this.p1, this.p2)
- }
- interpolateZ(p) {
- if (p === null) throw new IllegalArgumentException('Supplied point is null.')
- return Triangle.interpolateZ(p, this.p0, this.p1, this.p2)
- }
- longestSideLength() {
- return Triangle.longestSideLength(this.p0, this.p1, this.p2)
- }
- isAcute() {
- return Triangle.isAcute(this.p0, this.p1, this.p2)
- }
- circumcentre() {
- return Triangle.circumcentre(this.p0, this.p1, this.p2)
- }
- area3D() {
- return Triangle.area3D(this.p0, this.p1, this.p2)
- }
- centroid() {
- return Triangle.centroid(this.p0, this.p1, this.p2)
- }
- inCentre() {
- return Triangle.inCentre(this.p0, this.p1, this.p2)
- }
- }
|