summaryrefslogtreecommitdiffstats
path: root/packages/math/angle.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/math/angle.ts')
-rw-r--r--packages/math/angle.ts50
1 files changed, 50 insertions, 0 deletions
diff --git a/packages/math/angle.ts b/packages/math/angle.ts
new file mode 100644
index 0000000..8d473cf
--- /dev/null
+++ b/packages/math/angle.ts
@@ -0,0 +1,50 @@
+import type {
+ Degrees,
+ GlobalPoint,
+ LocalPoint,
+ PolarCoords,
+ Radians,
+} from "./types";
+import { PRECISION } from "./utils";
+
+// TODO: Simplify with modulo and fix for angles beyond 4*Math.PI and - 4*Math.PI
+export const normalizeRadians = (angle: Radians): Radians => {
+ if (angle < 0) {
+ return (angle + 2 * Math.PI) as Radians;
+ }
+ if (angle >= 2 * Math.PI) {
+ return (angle - 2 * Math.PI) as Radians;
+ }
+ return angle;
+};
+
+/**
+ * Return the polar coordinates for the given cartesian point represented by
+ * (x, y) for the center point 0,0 where the first number returned is the radius,
+ * the second is the angle in radians.
+ */
+export const cartesian2Polar = <P extends GlobalPoint | LocalPoint>([
+ x,
+ y,
+]: P): PolarCoords => [
+ Math.hypot(x, y),
+ normalizeRadians(Math.atan2(y, x) as Radians),
+];
+
+export function degreesToRadians(degrees: Degrees): Radians {
+ return ((degrees * Math.PI) / 180) as Radians;
+}
+
+export function radiansToDegrees(degrees: Radians): Degrees {
+ return ((degrees * 180) / Math.PI) as Degrees;
+}
+
+/**
+ * Determines if the provided angle is a right angle.
+ *
+ * @param rads The angle to measure
+ * @returns TRUE if the provided angle is a right angle
+ */
+export function isRightAngleRads(rads: Radians): boolean {
+ return Math.abs(Math.sin(2 * rads)) < PRECISION;
+}