-
Notifications
You must be signed in to change notification settings - Fork 0
/
boolean-rectangle.js
81 lines (67 loc) · 2.21 KB
/
boolean-rectangle.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
const VALID_ORDERING = [
// clockwise
"right -> down -> left -> up",
"down -> left -> up -> right",
"left -> up -> right -> down",
"up -> right -> down -> left",
// counter-clockwise
"down -> right -> up -> left",
"right -> up -> left -> down",
"up -> left -> down -> right",
"left -> down -> right -> up"
];
function booleanRectangle(coords, { debug = 0 } = { debug: 0 }) {
if (!Array.isArray(coords)) {
if (debug) {
console.log("[bbox-fns/booleanRectangle] coords is not an array");
}
return false;
}
// unwrap ring from polygon
if (coords.length === 1) coords = coords[0];
// if multi-polygon, may need to unwrap twice
if (coords.length === 1) coords = coords[0];
if (!coords.every(pt => Array.isArray(pt) && pt.every(n => typeof n === "number"))) {
if (debug) console.log("[bbox-fns/booleanRectangle] invalid points");
return false;
}
// first and last coordinate should be the same
if (JSON.stringify(coords[0]) !== JSON.stringify(coords[coords.length - 1])) {
if (debug) console.log("[bbox-fns/booleanRectangle] first and last coordinates not equal");
return false;
}
let order = [];
for (let i = 1; i < coords.length; i++) {
const [x0, y0] = coords[i - 1];
const [x1, y1] = coords[i];
const vertical = x0 === x1;
const horizontal = y0 === y1;
// if both true or both false
if (vertical === horizontal) {
if (debug) console.log("[bbox-fns/booleanRectangle] invalid angle");
return false;
}
let direction;
if (vertical) {
direction = y1 > y0 ? "up" : "down";
} else if (horizontal) {
direction = x1 > x0 ? "right" : "left";
}
if (direction !== order[order.length - 1]) {
if (order.length === 4) {
if (debug) console.log("[bbox-fns/booleanRectangle] more than 4 turns");
return false;
}
order.push(direction);
}
}
order = order.join(" -> ");
if (debug) console.log("[bbox-fns/booleanRectangle] order: " + order);
if (VALID_ORDERING.indexOf(order) === -1) {
if (debug) console.log("[bbox-fns/booleanRectangle] invalid order");
return false;
}
return true;
}
module.exports = booleanRectangle;
module.exports.default = booleanRectangle;