Skip to content

Commit c946957

Browse files
authored
Tested and debugged surrounds. (#97)
1 parent 6177f2a commit c946957

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

src/extras/BuildingShapeUtils.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -344,11 +344,12 @@ class BuildingShapeUtils extends ShapeUtils {
344344
}
345345

346346
/**
347-
* Count the number of times that a line horizontal from point intersects shape
347+
* Is the given point within the given shape?
348348
*
349-
* if an odd number are crossed, it is inside.
350-
* todo, test holes
351-
* Test edge conditions.
349+
* @param {THREE.Shape} shape - the shape
350+
* @param {[number, number]} point - an x, y pair.
351+
*
352+
* @return {boolean}
352353
*/
353354
static surrounds(shape, point) {
354355
var count = 0;
@@ -361,8 +362,13 @@ class BuildingShapeUtils extends ShapeUtils {
361362
if (vec.x === point[0] && vec.y === point[1]) {
362363
return true;
363364
}
364-
if ((vec.x >= point[0] || nextvec.x >= point[0]) && (vec.y >= point[1] !== nextvec.y >= point[1])) {
365+
const slope = (nextvec.y - vec.y) / (nextvec.x - vec.x);
366+
const intercept = vec.y / slope / vec.x;
367+
const intersection = (point[1] - intercept) / slope;
368+
if (intersection > point[0]) {
365369
count++;
370+
} else if (intersection === point[0]) {
371+
return true;
366372
}
367373
}
368374
return count % 2 === 1;

test/utils.test.js

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,13 @@ test('Longest side angle', () => {
7676
expect(BuildingShapeUtils.longestSideAngle(rightTriangle)).toBe(-Math.PI / 4);
7777
});
7878

79-
describe('isSelfIntersecting', () => {
80-
test.each([
81-
['<way id="1"><nd ref="1"/><nd ref="2"/></way>', false, 'open non-intersecting'],
82-
['<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="1"/></way>', false, 'closed non-intersecting'],
83-
['<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="2"/></way>', true, 'open intersecting'],
84-
['<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="4"/><nd ref="3"/><nd ref="1"/></way>', true, 'closed intersecting'],
85-
])('${description}', (way, expected, description) => {
79+
describe.each([
80+
['<way id="1"><nd ref="1"/><nd ref="2"/></way>', false, 'open non-intersecting'],
81+
['<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="1"/></way>', false, 'closed non-intersecting'],
82+
['<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="2"/></way>', true, 'open intersecting'],
83+
['<way id="1"><nd ref="1"/><nd ref="2"/><nd ref="3"/><nd ref="4"/><nd ref="3"/><nd ref="1"/></way>', true, 'closed intersecting'],
84+
])('isSelfIntersecting', (way, expected, description) => {
85+
test(`${description}`, () => {
8686
let parser = new window.DOMParser();
8787
let xml = parser.parseFromString(way, 'text/xml').getElementsByTagName('way')[0];
8888
expect(BuildingShapeUtils.isSelfIntersecting(xml)).toBe(expected);
@@ -108,6 +108,16 @@ rightTriangle2.lineTo(1, -1);
108108
test('Vertex Angles counterclockwise', () => {
109109
expect(BuildingShapeUtils.vertexAngle(rightTriangle2)).toStrictEqual([-Math.PI / 2, -Math.PI / 4, -Math.PI / 4]);
110110
});
111-
// test surrounds
111+
112+
describe.each([
113+
[[-1, -1], false, 'Outside'],
114+
[[1, 1], true, 'Share Node'],
115+
[[.5, .5], true, 'Inside'],
116+
[[0, 0], true, 'Border'],
117+
])('Surrounds', (point, expected, description) => {
118+
test(`${description}`, () => {
119+
expect(BuildingShapeUtils.surrounds(rightTriangle, point)).toBe(expected);
120+
});
121+
});
112122

113123
// test calcRadius

0 commit comments

Comments
 (0)