-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdata-types.mjs
96 lines (78 loc) · 2.27 KB
/
data-types.mjs
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
// ==================================================================
// PRIMITIVE DATA TYPE CLASSES
// ------------------------------------------------------------------
import { HALF_PI, deg2Rad } from './globals.mjs';
// ------------------------------------------------------------------
// Class to represent a Cartesian 2D point
export class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
copy() {
return new Point(this.x, this.y);
}
isEqualTo(otherPoint) {
return (
this.x === otherPoint.x &&
this.y === otherPoint.y
);
}
getAngleTo(otherPoint) {
return Math.atan2(otherPoint.y - this.y, otherPoint.x - this.x);
}
getDistanceTo(otherPoint) {
return Math.hypot(otherPoint.y - this.y, otherPoint.x - this.x);
}
translate(δPoint) {
this.x += δPoint.x;
this.y += δPoint.y;
return this;
}
scale(factor) {
this.x *= factor;
this.y *= factor;
return this;
}
rotate(θ) {
const cosΘ = Math.cos(θ);
const sinΘ = Math.sin(θ);
const original = this.copy();
this.x = original.x * cosΘ - original.y * sinΘ;
this.y = original.x * sinΘ + original.y * cosΘ;
return this;
}
// Returns an SVG-friendly string representation of the point and
// rounded to at most numPlaces decimal points
toString(numPlaces = 2) {
return (
`${this.x.toFixed(numPlaces)},${this.y.toFixed(numPlaces)}`
.replace(/\.0+\b/g, '')
.replace(/(\.[0-9]*[1-9]+)0+\b/g, '$1')
);
}
}
// ------------------------------------------------------------------
// Class to represent a pair of coordinates on Earth
export class LatLon {
constructor(lat, lon) {
this.lat = lat;
this.lon = lon;
}
copy() {
return new LatLon(this.lat, this.lon);
}
// Assuming object is in degrees, returns a new object in radians
toRadians() {
return new LatLon(deg2Rad(this.lat), deg2Rad(this.lon));
}
// Return the distance in radians to another LatLon object assuming this
// object is already in radians
getDistanceTo(otherLatLon) {
const cosΔLon = Math.cos(this.lon - otherLatLon.lon);
return HALF_PI - Math.asin(
Math.sin(this.lat) * Math.sin(otherLatLon.lat) +
Math.cos(this.lat) * Math.cos(otherLatLon.lat) * cosΔLon
);
}
};