| function dot2D(vectorA, vectorB) { return vectorA[0] * vectorB[0] + vectorA[1] * vectorB[1]; } | |
| function cross2D(vectorA, vectorB) { return vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0]; } | |
| function magnitude2D(vector) { return Math.sqrt(dot2D(vector, vector)); } | |
| function perpendicular2D(v) { return [v[1], -v[0]]; } | |
| function reverse2D(v) { return [-v[0], -v[1]]; } | |
| function normalize2D(v) { | |
| let length = Math.sqrt(dot2D(v, v)); | |
| if (length < 0.0001) { return [0.0, 0.0]; } | |
| return [v[0] / length, v[1] / length]; | |
| } | |
| function signedAngle(lhs, rhs) {return Math.atan2(cross2D(lhs, rhs), dot2D(lhs, rhs));} | |
| function angleBetween(lhs, rhs) {return Math.abs(signedAngle(lhs, rhs));} | |
| function positiveAngle(lhs, rhs) { | |
| var a = signedAngle(lhs, rhs); | |
| return a < 0 ? a + Math.PI * 2 : a; | |
| } | |
| function getSide(A, B, C, D) { | |
| const BA = [A[0] - B[0], A[1] - B[1]]; | |
| const BD = [D[0] - B[0], D[1] - B[1]]; | |
| const BC = [C[0] - B[0], C[1] - B[1]]; | |
| const theta0 = positiveAngle(BA, BD); | |
| const theta1 = positiveAngle(BA, BC); | |
| if (theta0 == 0 || theta0 == theta1) { | |
| return 0; | |
| } else if (theta0 < theta1) { | |
| return 1; | |
| } else { | |
| return -1 | |
| } | |
| } | |
| function slerp2D(ca, cb, t) { | |
| const calen = magnitude2D(ca); | |
| const cblen = magnitude2D(cb); | |
| const lent = calen + (cblen - calen) * t; | |
| const cq = [ca[0] * lent / calen, ca[1] * lent / calen]; | |
| const angle = signedAngle(ca, cb) * t; | |
| const xt = cq[0] * Math.cos(angle) - cq[1] * Math.sin(angle); | |
| const yt = cq[0] * Math.sin(angle) + cq[1] * Math.cos(angle); | |
| return [xt, yt]; | |
| } | |