/
util.ts
121 lines (101 loc) 路 2.26 KB
/
util.ts
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
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
* @ignore
*/
import {getRange, isEmpty, isFunction, isString, parseDate} from "../../module/util";
/**
* Check if point is in region
* @param {object} point Point
* @param {Array} region Region
* @returns {boolean}
* @private
*/
function pointInRegion(point, region): boolean { // thanks to: http://bl.ocks.org/bycoffe/5575904
// ray-casting algorithm based on
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
const x = point.x;
const y = point.value;
let inside = false;
for (let i = 0, j = region.length - 1; i < region.length; j = i++) {
const xi = region[i].x;
const yi = region[i].y;
const xj = region[j].x;
const yj = region[j].y;
const intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) {
inside = !inside;
}
}
return inside;
}
/**
* Compare epochs
* @param {object} a Target
* @param {object} b Source
* @returns {number}
* @private
*/
function compareEpochs(a, b): number {
if (a.epochs < b.epochs) {
return -1;
}
if (a.epochs > b.epochs) {
return 1;
}
return 0;
}
/**
* Get region area
* @param {Array} points Points
* @returns {number}
* @private
*/
function getRegionArea(points): number { // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript
let area = 0;
let point1;
let point2;
for (let i = 0, l = points.length, j = l - 1; i < l; j = i, i++) {
point1 = points[i];
point2 = points[j];
area += point1.x * point2.y;
area -= point1.y * point2.x;
}
area /= 2;
return area;
}
/**
* Get centroid
* @param {Array} points Points
* @returns {object}
* @private
*/
function getCentroid(points) {
const area = getRegionArea(points);
let x = 0;
let y = 0;
let f;
for (let i = 0, l = points.length, j = l - 1; i < l; j = i, i++) {
const point1 = points[i];
const point2 = points[j];
f = point1.x * point2.y - point2.x * point1.y;
x += (point1.x + point2.x) * f;
y += (point1.y + point2.y) * f;
}
f = area * 6;
return {
x: x / f,
y: y / f
};
}
export {
compareEpochs,
getCentroid,
getRange,
getRegionArea,
isEmpty,
isFunction,
isString,
parseDate,
pointInRegion
};