Skip to content

Commit 745ccff

Browse files
committed
Added equals() function
1 parent 6144cbf commit 745ccff

File tree

8 files changed

+101
-14
lines changed

8 files changed

+101
-14
lines changed

Diff for: LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 Robert Eisele
3+
Copyright (c) 2025 Robert Eisele
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

Diff for: README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ Determines what the shortest rotation direction is to go from one angle to anoth
5959

6060
Determines if an angle `n` is between two other angles `a, b`. The angles don't have to be normalized.
6161

62+
### equals(a, b)
63+
64+
Determines if two angles `a` and `b` are equal.
65+
6266
### diff(a, b)
6367

6468
Calculates the angular difference between two angles
@@ -142,5 +146,5 @@ npm run test
142146

143147
## Copyright and Licensing
144148

145-
Copyright (c) 2024, [Robert Eisele](https://raw.org/)
149+
Copyright (c) 2025, [Robert Eisele](https://raw.org/)
146150
Licensed under the MIT license.

Diff for: dist/angles.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
var TAU = 2 * Math.PI;
4-
var EPS = 1e-15;
4+
var EPS = 1e-10;
55

66
// var DIRECTIONS = ["N", "E", "S", "W"];
77
var DIRECTIONS = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"];
@@ -292,6 +292,25 @@ var Angles = {
292292

293293
return Math.atan2(y, x) * s / TAU;
294294
},
295+
/**
296+
* Determines if two angles are equal
297+
*
298+
* @param {number} angle1
299+
* @param {number} angle2
300+
* @returns {boolean}
301+
*/
302+
'equals': function (angle1, angle2) {
303+
304+
var m = this['SCALE'];
305+
306+
const normalizedAngle1 = mod(angle1, m);
307+
const normalizedAngle2 = mod(angle2, m);
308+
309+
const diff1 = Math.abs(normalizedAngle1 - normalizedAngle2);
310+
const diff2 = Math.abs(diff1 - 2 * Math.PI);
311+
312+
return diff1 < EPS || diff2 < EPS;
313+
}
295314
};
296315

297316
Object.defineProperty(Angles, "__esModule", { 'value': true });

Diff for: dist/angles.min.js

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: dist/angles.mjs

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
var TAU = 2 * Math.PI;
4-
var EPS = 1e-15;
4+
var EPS = 1e-10;
55

66
// var DIRECTIONS = ["N", "E", "S", "W"];
77
var DIRECTIONS = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"];
@@ -292,6 +292,25 @@ var Angles = {
292292

293293
return Math.atan2(y, x) * s / TAU;
294294
},
295+
/**
296+
* Determines if two angles are equal
297+
*
298+
* @param {number} angle1
299+
* @param {number} angle2
300+
* @returns {boolean}
301+
*/
302+
'equals': function (angle1, angle2) {
303+
304+
var m = this['SCALE'];
305+
306+
const normalizedAngle1 = mod(angle1, m);
307+
const normalizedAngle2 = mod(angle2, m);
308+
309+
const diff1 = Math.abs(normalizedAngle1 - normalizedAngle2);
310+
const diff2 = Math.abs(diff1 - 2 * Math.PI);
311+
312+
return diff1 < EPS || diff2 < EPS;
313+
}
295314
};
296315
export {
297316
Angles as default, Angles

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "angles",
33
"title": "Angles.js",
4-
"version": "0.3.0",
4+
"version": "0.4.0",
55
"homepage": "https://github.com/rawify/Angles.js",
66
"bugs": "https://github.com/rawify/Angles.js/issues",
77
"description": "A function collection for working with angles",

Diff for: src/angles.js

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
/**
2-
* @license Angles.js v0.3.0 10/22/2024
2+
* @license Angles.js v0.4.0 3/13/2025
33
* https://github.com/rawify/Angles.js
44
*
5-
* Copyright (c) 2024, Robert Eisele (https://raw.org/)
5+
* Copyright (c) 2025, Robert Eisele (https://raw.org/)
66
* Licensed under the MIT license.
77
**/
88

99
var TAU = 2 * Math.PI;
10-
var EPS = 1e-15;
10+
var EPS = 1e-10;
1111

1212
// var DIRECTIONS = ["N", "E", "S", "W"];
1313
var DIRECTIONS = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"];
@@ -298,4 +298,23 @@ var Angles = {
298298

299299
return Math.atan2(y, x) * s / TAU;
300300
},
301+
/**
302+
* Determines if two angles are equal
303+
*
304+
* @param {number} angle1
305+
* @param {number} angle2
306+
* @returns {boolean}
307+
*/
308+
'equals': function (angle1, angle2) {
309+
310+
var m = this['SCALE'];
311+
312+
const normalizedAngle1 = mod(angle1, m);
313+
const normalizedAngle2 = mod(angle2, m);
314+
315+
const diff1 = Math.abs(normalizedAngle1 - normalizedAngle2);
316+
const diff2 = Math.abs(diff1 - 2 * Math.PI);
317+
318+
return diff1 < EPS || diff2 < EPS;
319+
}
301320
};

Diff for: tests/angles.test.js

+26
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,32 @@ var tests = [
5454
{ m: 'lerp', p: [-30, 30, 0.25, 1], r: 255, s: 360 },
5555
{ m: 'lerp', p: [10, 10, 0.5, -1], r: 10, s: 360 },
5656
{ m: 'lerp', p: [10, 10, 0.5, 1], r: 10, s: 360 },
57+
{ m: 'equals', p: [0, 360], r: true, s: 360 },
58+
{ m: 'equals', p: [90, -270], r: true, s: 360 },
59+
{ m: 'equals', p: [-180, 180], r: true, s: 360 },
60+
{ m: 'equals', p: [45, 405], r: true, s: 360 },
61+
{ m: 'equals', p: [180, 540], r: true, s: 360 },
62+
{ m: 'equals', p: [30, -330], r: true, s: 360 },
63+
{ m: 'equals', p: [90, 270], r: false, s: 360 }, // Should be different
64+
{ m: 'equals', p: [-720, 0], r: true, s: 360 }, // -2 full turns
65+
{ m: 'equals', p: [0, 1e-12 * 180 / Math.PI], r: true, s: 360 }, // Small difference within tolerance
66+
{ m: 'equals', p: [0, 1e-7 * 180 / Math.PI], r: false, s: 360 }, // Small difference outside tolerance
67+
{ m: 'equals', p: [359.999999999999999, 0], r: true, s: 360 }, // Edge case close to wrap-around
68+
{ m: 'equals', p: [180, -180.00000000001], r: true, s: 360 }, // Slightly below -180°
69+
{ m: 'equals', p: [180, -179.9999999999999], r: true, s: 360 }, // Slightly above -180°
70+
{ m: 'equals', p: [0, 2 * Math.PI], r: true, s: 2 * Math.PI },
71+
{ m: 'equals', p: [Math.PI / 2, -3 * Math.PI / 2], r: true, s: 2 * Math.PI },
72+
{ m: 'equals', p: [-Math.PI, Math.PI], r: true, s: 2 * Math.PI },
73+
{ m: 'equals', p: [Math.PI / 4, 9 * Math.PI / 4], r: true, s: 2 * Math.PI },
74+
{ m: 'equals', p: [Math.PI, 3 * Math.PI], r: true, s: 2 * Math.PI },
75+
{ m: 'equals', p: [Math.PI / 6, -11 * Math.PI / 6], r: true, s: 2 * Math.PI },
76+
{ m: 'equals', p: [Math.PI / 2, 3 * Math.PI / 2], r: false, s: 2 * Math.PI }, // Should be different
77+
{ m: 'equals', p: [-4 * Math.PI, 0], r: true, s: 2 * Math.PI }, // -2 full turns
78+
{ m: 'equals', p: [0, 1e-12], r: true, s: 2 * Math.PI }, // Small difference within tolerance
79+
{ m: 'equals', p: [0, 1e-7], r: false, s: 2 * Math.PI }, // Small difference outside tolerance
80+
{ m: 'equals', p: [2 * Math.PI - 1e-9, 0], r: true, s: 2 * Math.PI }, // Edge case close to wrap-around
81+
{ m: 'equals', p: [Math.PI, -Math.PI - 1e-12], r: true, s: 2 * Math.PI }, // Slightly below -π
82+
{ m: 'equals', p: [Math.PI, -Math.PI + 1e-12], r: true, s: 2 * Math.PI } // Slightly above -π
5783
];
5884

5985
for (var i = 0; i <= 360; i += 2) {

0 commit comments

Comments
 (0)