galines.ts 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import * as GA from "./ga";
  2. import { Line, Point } from "./ga";
  3. /**
  4. * A line is stored as an array `[0, c, a, b, 0, 0, 0, 0]` representing:
  5. * c * e0 + a * e1 + b*e2
  6. *
  7. * This maps to a standard formula `a * x + b * y + c`.
  8. *
  9. * `(-b, a)` correponds to a 2D vector parallel to the line. The lines
  10. * have a natural orientation, corresponding to that vector.
  11. *
  12. * The magnitude ("norm") of the line is `sqrt(a ^ 2 + b ^ 2)`.
  13. * `c / norm(line)` is the oriented distance from line to origin.
  14. */
  15. // Returns line with direction (x, y) through origin
  16. export function vector(x: number, y: number): Line {
  17. return GA.normalized([0, 0, -y, x, 0, 0, 0, 0]);
  18. }
  19. // For equation ax + by + c = 0.
  20. export function equation(a: number, b: number, c: number): Line {
  21. return GA.normalized([0, c, a, b, 0, 0, 0, 0]);
  22. }
  23. export function through(from: Point, to: Point): Line {
  24. return GA.normalized(GA.join(to, from));
  25. }
  26. export function orthogonal(line: Line, point: Point): Line {
  27. return GA.dot(line, point);
  28. }
  29. // Returns a line perpendicular to the line through `against` and `intersection`
  30. // going through `intersection`.
  31. export function orthogonalThrough(against: Point, intersection: Point): Line {
  32. return orthogonal(through(against, intersection), intersection);
  33. }
  34. export function parallel(line: Line, distance: number): Line {
  35. const result = line.slice();
  36. result[1] -= distance;
  37. return (result as unknown) as Line;
  38. }
  39. export function parallelThrough(line: Line, point: Point): Line {
  40. return orthogonal(orthogonal(point, line), point);
  41. }
  42. export function distance(line1: Line, line2: Line): number {
  43. return GA.inorm(GA.meet(line1, line2));
  44. }
  45. export function angle(line1: Line, line2: Line): number {
  46. return Math.acos(GA.dot(line1, line2)[0]);
  47. }
  48. // The orientation of the line
  49. export function sign(line: Line): number {
  50. return Math.sign(line[1]);
  51. }