Fix isConvex() to correctly test the angle that closes the way.

This commit is contained in:
Bryan Housel
2014-04-23 14:12:20 -04:00
parent 33782a3958
commit d245121b19
2 changed files with 40 additions and 20 deletions
+9 -4
View File
@@ -58,12 +58,17 @@ _.extend(iD.Way.prototype, {
isConvex: function(resolver) {
if (!this.isClosed() || this.isDegenerate()) return null;
var coords = _.pluck(resolver.childNodes(this), 'loc'),
var nodes = _.uniq(resolver.childNodes(this)),
coords = _.pluck(nodes, 'loc'),
curr = 0, prev = 0;
for (var i = 1; i < coords.length - 1; i++) {
curr = iD.geo.cross(coords[i-1], coords[i], coords[i+1]);
curr = (curr > 0) ? 1 : (curr < 0) ? -1 : 0;
for (var i = 0; i < coords.length; i++) {
var o = coords[(i+1) % coords.length],
a = coords[i],
b = coords[(i+2) % coords.length],
res = iD.geo.cross(o, a, b);
curr = (res > 0) ? 1 : (res < 0) ? -1 : 0;
if (curr === 0) {
continue;
} else if (prev && curr !== prev) {
+31 -16
View File
@@ -89,36 +89,51 @@ describe('iD.Way', function() {
describe('#isConvex', function() {
it('returns true for convex ways', function() {
// d -- e
// | \
// | a
// | /
// c -- b
var graph = iD.Graph([
iD.Node({id: 'a', loc: [-0.0002, 0.0002]}),
iD.Node({id: 'b', loc: [ 0.0002, 0.0002]}),
iD.Node({id: 'c', loc: [ 0.0003, 0.0000]}),
iD.Node({id: 'd', loc: [ 0.0002, -0.0002]}),
iD.Node({id: 'e', loc: [-0.0002, -0.0002]}),
iD.Node({id: 'a', loc: [ 0.0003, 0.0000]}),
iD.Node({id: 'b', loc: [ 0.0002, -0.0002]}),
iD.Node({id: 'c', loc: [-0.0002, -0.0002]}),
iD.Node({id: 'd', loc: [-0.0002, 0.0002]}),
iD.Node({id: 'e', loc: [ 0.0002, 0.0002]}),
iD.Way({id: 'w', nodes: ['a','b','c','d','e','a']})
]);
expect(graph.entity('w').isConvex(graph)).to.be.true;
});
it('returns false for concave ways', function() {
// d -- e
// | /
// | a
// | \
// c -- b
var graph = iD.Graph([
iD.Node({id: 'a', loc: [-0.0002, 0.0002]}),
iD.Node({id: 'b', loc: [ 0.0002, 0.0002]}),
iD.Node({id: 'c', loc: [ 0.0000, 0.0000]}),
iD.Node({id: 'd', loc: [ 0.0002, -0.0002]}),
iD.Node({id: 'e', loc: [-0.0002, -0.0002]}),
iD.Node({id: 'a', loc: [ 0.0000, 0.0000]}),
iD.Node({id: 'b', loc: [ 0.0002, -0.0002]}),
iD.Node({id: 'c', loc: [-0.0002, -0.0002]}),
iD.Node({id: 'd', loc: [-0.0002, 0.0002]}),
iD.Node({id: 'e', loc: [ 0.0002, 0.0002]}),
iD.Way({id: 'w', nodes: ['a','b','c','d','e','a']})
]);
expect(graph.entity('w').isConvex(graph)).to.be.false;
});
it('returns null for non-closed ways', function() {
// d -- e
// |
// | a
// | \
// c -- b
var graph = iD.Graph([
iD.Node({id: 'a', loc: [-0.0002, 0.0002]}),
iD.Node({id: 'b', loc: [ 0.0002, 0.0002]}),
iD.Node({id: 'c', loc: [ 0.0000, 0.0000]}),
iD.Node({id: 'd', loc: [ 0.0002, -0.0002]}),
iD.Node({id: 'e', loc: [-0.0002, -0.0002]}),
iD.Node({id: 'a', loc: [ 0.0000, 0.0000]}),
iD.Node({id: 'b', loc: [ 0.0002, -0.0002]}),
iD.Node({id: 'c', loc: [-0.0002, -0.0002]}),
iD.Node({id: 'd', loc: [-0.0002, 0.0002]}),
iD.Node({id: 'e', loc: [ 0.0002, 0.0002]}),
iD.Way({id: 'w', nodes: ['a','b','c','d','e']})
]);
expect(graph.entity('w').isConvex(graph)).to.be.null;
@@ -126,7 +141,7 @@ describe('iD.Way', function() {
it('returns null for degenerate ways', function() {
var graph = iD.Graph([
iD.Node({id: 'a', loc: [-0.0002, 0.0002]}),
iD.Node({id: 'a', loc: [0.0000, 0.0000]}),
iD.Way({id: 'w', nodes: ['a','a']})
]);
expect(graph.entity('w').isConvex(graph)).to.be.null;