angle.ts 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import type {
  2. Degrees,
  3. GlobalPoint,
  4. LocalPoint,
  5. PolarCoords,
  6. Radians,
  7. } from "./types";
  8. import { PRECISION } from "./utils";
  9. // TODO: Simplify with modulo and fix for angles beyond 4*Math.PI and - 4*Math.PI
  10. export const normalizeRadians = (angle: Radians): Radians => {
  11. if (angle < 0) {
  12. return (angle + 2 * Math.PI) as Radians;
  13. }
  14. if (angle >= 2 * Math.PI) {
  15. return (angle - 2 * Math.PI) as Radians;
  16. }
  17. return angle;
  18. };
  19. /**
  20. * Return the polar coordinates for the given cartesian point represented by
  21. * (x, y) for the center point 0,0 where the first number returned is the radius,
  22. * the second is the angle in radians.
  23. */
  24. export const cartesian2Polar = <P extends GlobalPoint | LocalPoint>([
  25. x,
  26. y,
  27. ]: P): PolarCoords => [Math.hypot(x, y), Math.atan2(y, x)];
  28. export function degreesToRadians(degrees: Degrees): Radians {
  29. return ((degrees * Math.PI) / 180) as Radians;
  30. }
  31. export function radiansToDegrees(degrees: Radians): Degrees {
  32. return ((degrees * 180) / Math.PI) as Degrees;
  33. }
  34. /**
  35. * Determines if the provided angle is a right angle.
  36. *
  37. * @param rads The angle to measure
  38. * @returns TRUE if the provided angle is a right angle
  39. */
  40. export function isRightAngleRads(rads: Radians): boolean {
  41. return Math.abs(Math.sin(2 * rads)) < PRECISION;
  42. }