-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathangles.js
128 lines (108 loc) · 2.83 KB
/
angles.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**
* Copyright 2012-2018, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
var PI = Math.PI;
function deg2rad(deg) {
return deg / 180 * PI;
}
function rad2deg(rad) {
return rad / PI * 180;
}
function wrap360(deg) {
var out = deg % 360;
return out < 0 ? out + 360 : out;
}
function wrap180(deg) {
if(Math.abs(deg) > 180) deg -= Math.round(deg / 360) * 360;
return deg;
}
/* is sector a full circle?
* ... this comes up a lot in SVG path-drawing routines
*
* @param {2-item array} sector sector angles in *degrees*
* @return {boolean}
*/
function isFullCircle(sector) {
var arc = Math.abs(sector[1] - sector[0]);
return arc === 360;
}
/* angular delta between angle 'a' and 'b'
*
* solution taken from: https://stackoverflow.com/a/2007279
*
* @param {number} a : first angle in *radians*
* @param {number} b : second angle in *radians*
* @return {number} angular delta in *radians*
*/
function angleDelta(a, b) {
var d = b - a;
return Math.atan2(Math.sin(d), Math.cos(d));
}
/* angular distance between angle 'a' and 'b'
*
* @param {number} a : first angle in *radians*
* @param {number} b : second angle in *radians*
* @return {number} angular distance in *radians*
*/
function angleDist(a, b) {
return Math.abs(angleDelta(a, b));
}
/* is angle inside sector?
*
* @param {number} a : angle to test in *radians*
* @param {2-item array} sector : sector angles in *degrees*
* @param {boolean}
*/
function isAngleInsideSector(a, sector) {
if(isFullCircle(sector)) return true;
var s0, s1;
if(sector[0] < sector[1]) {
s0 = sector[0];
s1 = sector[1];
} else {
s0 = sector[1];
s1 = sector[0];
}
s0 = wrap360(s0);
s1 = wrap360(s1);
if(s0 > s1) s1 += 360;
var a0 = wrap360(rad2deg(a));
var a1 = a0 + 360;
return (a0 >= s0 && a0 <= s1) || (a1 >= s0 && a1 <= s1);
}
/* is pt (r,a) inside sector?
*
* @param {number} r : pt's radial coordinate
* @param {number} a : pt's angular coordinate in *radians*
* @param {2-item array} rRng : sector's radial range
* @param {2-item array} sector : sector angles in *degrees*
* @return {boolean}
*/
function isPtInsideSector(r, a, rRng, sector) {
if(!isAngleInsideSector(a, sector)) return false;
var r0, r1;
if(rRng[0] < rRng[1]) {
r0 = rRng[0];
r1 = rRng[1];
} else {
r0 = rRng[1];
r1 = rRng[0];
}
return r >= r0 && r <= r1;
}
module.exports = {
deg2rad: deg2rad,
rad2deg: rad2deg,
wrap360: wrap360,
wrap180: wrap180,
angleDelta: angleDelta,
angleDist: angleDist,
isFullCircle: isFullCircle,
isAngleInsideSector: isAngleInsideSector,
isPtInsideSector: isPtInsideSector
};