Skip to content
This repository was archived by the owner on Jul 26, 2025. It is now read-only.

Commit bfeacfb

Browse files
committed
feat: implement getMathAngle
1 parent d69cd6a commit bfeacfb

File tree

2 files changed

+73
-4
lines changed

2 files changed

+73
-4
lines changed

src/maskAnalysis/utils/__tests__/getAngle.test.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { toBeDeepCloseTo } from 'jest-matcher-deep-close-to';
22

3-
import { getAngle } from '../getAngle';
3+
import { getAngle, getMathAngle } from '../getAngle';
44

55
expect.extend({ toBeDeepCloseTo });
66

@@ -38,3 +38,50 @@ test.each([
3838
const result = getAngle(point1, point2);
3939
expect(result).toBeCloseTo(expectedAngle);
4040
});
41+
42+
test.each([
43+
[
44+
'60 degrees',
45+
{ column: 0, row: 0 },
46+
{ column: 1, row: -Math.sqrt(3) },
47+
Math.PI / 3,
48+
],
49+
['45 degrees', { column: 0, row: 0 }, { column: 1, row: -1 }, Math.PI / 4],
50+
[
51+
'30 degrees',
52+
{ column: 0, row: 0 },
53+
{ column: Math.sqrt(3), row: -1 },
54+
Math.PI / 6,
55+
],
56+
[
57+
'-60 degrees',
58+
{ column: 0, row: 0 },
59+
{ column: 1, row: Math.sqrt(3) },
60+
-Math.PI / 3,
61+
],
62+
['-45 degrees', { column: 0, row: 0 }, { column: 1, row: 1 }, -Math.PI / 4],
63+
[
64+
'-30 degrees',
65+
{ column: 0, row: 0 },
66+
{ column: Math.sqrt(3), row: 1 },
67+
-Math.PI / 6,
68+
],
69+
['180 degrees', { column: 0, row: 0 }, { column: -1, row: 0 }, Math.PI],
70+
['270 degrees', { column: 0, row: 0 }, { column: 0, row: 1 }, -Math.PI / 2],
71+
['90 degrees', { column: 0, row: 0 }, { column: 0, row: -1 }, Math.PI / 2],
72+
[
73+
'90 degrees, origin not zero',
74+
{ column: 1, row: 4 },
75+
{ column: 1, row: 3 },
76+
Math.PI / 2,
77+
],
78+
[
79+
'45 degrees, origin not zero',
80+
{ column: 4, row: 5 },
81+
{ column: 5, row: 4 },
82+
Math.PI / 4,
83+
],
84+
])('getMathAngle (%s)', (_, point1, point2, expectedAngle) => {
85+
const result = getMathAngle(point1, point2);
86+
expect(result).toBeCloseTo(expectedAngle);
87+
});

src/maskAnalysis/utils/getAngle.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,31 @@ import { difference, normalize, Point } from '../../utils/geometry/points';
1111
* @returns Rotation angle in radians to make the line horizontal.
1212
*/
1313
export function getAngle(p1: Point, p2: Point): number {
14-
let diff = difference(p2, p1);
15-
let vector = normalize(diff);
16-
let angle = Math.acos(vector.column);
14+
const diff = difference(p2, p1);
15+
const vector = normalize(diff);
16+
const angle = Math.acos(vector.column);
1717
if (vector.row < 0) return -angle;
1818
return angle;
1919
}
20+
21+
/**
22+
* Compute the mathematical angle in radians of the segment p1-p2.
23+
*
24+
* @param p1 - First point.
25+
* @param p2 - Second point.
26+
* @returns The angle of the segment in radians.
27+
*/
28+
export function getMathAngle(p1: Point, p2: Point): number {
29+
const diff = difference(p2, p1);
30+
const vector = normalize(diff);
31+
const atan = -Math.atan(vector.row / vector.column);
32+
if (vector.column < 0) {
33+
if (vector.row < 0) {
34+
return atan - Math.PI;
35+
} else {
36+
return atan + Math.PI;
37+
}
38+
} else {
39+
return atan;
40+
}
41+
}

0 commit comments

Comments
 (0)