@valeera/mathx
Version:
A math library written in TS.
132 lines (108 loc) • 3.54 kB
text/typescript
import { EPSILON } from "../constants";
import { Vector3, Vector3Like } from "../vector/Vector3";
import { ITriangle3 } from "./interfaces/ITriangle3";
const ab = new Vector3();
const bc = new Vector3();
const ca = new Vector3();
export class Triangle3 implements ITriangle3 {
public static area = (t: ITriangle3): number => {
const c = Triangle3.getABLength(t);
const a = Triangle3.getBCLength(t);
const b = Triangle3.getCALength(t);
const p = (c + a + b) / 2;
return Math.sqrt(p * (p - a) * (p - b) * (p - c));
};
public static centerOfGravity = <T extends Vector3Like>(t: ITriangle3, out: T = new Vector3() as T): T => {
out[0] = t.a[0] + t.b[0] + t.c[0];
out[1] = t.a[1] + t.b[1] + t.c[1];
out[2] = t.a[2] + t.b[2] + t.c[2];
return Vector3.multiplyScalar(out, 1 / 3, out);
}
public static containsPoint = (t: ITriangle3, epsilon = EPSILON, point: Vector3Like): boolean => {
Vector3.minus(t.b, t.a, ab);
Vector3.minus(t.c, t.b, bc);
Vector3.minus(t.a, t.c, ca);
const v1 = Vector3.minus(t.a, point);
const v2 = Vector3.minus(t.b, point);
const v3 = Vector3.minus(t.c, point);
Vector3.normalize(Vector3.cross(v1, v2, ab), ab);
Vector3.normalize(Vector3.cross(v2, v3, bc), bc);
Vector3.normalize(Vector3.cross(v3, v1, ca), ca);
if (Vector3.closeToRect(ab, bc, epsilon) && Vector3.closeToRect(ab, ca, epsilon)) {
return true;
}
return false;
}
public static cosAngle = (t: ITriangle3, point: "a" | "b" | "c" | Vector3Like): number => {
let a: number, other: number[] = [];
const a2 = Vector3.lengthSquared(t.a);
const b2 = Vector3.lengthSquared(t.b);
const c2 = Vector3.lengthSquared(t.c);
if (typeof point === 'string') {
if (point === "a") {
a = a2;
other.push(b2, c2);
} else if (point === "b") {
a = b2;
other.push(a2, c2);
} else {
a = c2;
other.push(a2, b2);
}
} else {
if (point === t.a) {
a = a2;
other.push(b2, c2);
} else if (point === t.b) {
a = b2;
other.push(a2, c2);
} else if (point === t.c) {
a = c2;
other.push(a2, b2);
} else {
throw new Error("The point is not in triangle.");
}
}
return (other[0] + other[1] - a) * 0.5 / Math.sqrt(other[0] * other[1]);
}
public static create = (
a: Vector3 = new Vector3(-1, -1, 0),
b: Vector3 = new Vector3(1, -1, 0),
c: Vector3 = new Vector3(0, 1, 0),
): Triangle3 => {
return new Triangle3(a, b, c);
};
public static getABLength = (t: ITriangle3): number => {
return Vector3.distanceTo(t.a, t.b);
};
public static getBCLength = (t: ITriangle3): number => {
return Vector3.distanceTo(t.b, t.c);
};
public static getCALength = (t: ITriangle3): number => {
return Vector3.distanceTo(t.c, t.a);
};
public static normal = <T extends Vector3Like = Vector3>(t: ITriangle3, out: T = new Vector3() as T): T => {
Vector3.minus(t.c, t.b, bc);
Vector3.minus(t.b, t.a, ab);
Vector3.cross(ab, bc, out);
return Vector3.normalize(out);
};
public static toFloat32Array = (t: ITriangle3, out: Float32Array = new Float32Array(9)): Float32Array => {
out.set(t.a, 0);
out.set(t.b, 3);
out.set(t.c, 6);
return out;
};
public a: Vector3;
public b: Vector3;
public c: Vector3;
public constructor(
a: Vector3 = new Vector3(-1, -1, 0),
b: Vector3 = new Vector3(1, -1, 0),
c: Vector3 = new Vector3(0, 1, 0),
) {
this.a = a;
this.b = b;
this.c = c;
}
}