Skip to content

Commit

Permalink
fixed intersection finding for degeneracies by looping over vertices …
Browse files Browse the repository at this point in the history
…for relative positions separately #5
  • Loading branch information
mischkew committed Nov 23, 2015
1 parent cdf418a commit 3565e4c
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 10 deletions.
35 changes: 28 additions & 7 deletions src/polygon.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,12 @@ function insertDegeneratedIntersection(context) {
!context.currentVertex._isIntersection
) {
context.currentVertex._isIntersection = true
context.currentVertex._relativePosition = 'on'

if (
context.isCorrespondingVertex1OnLine &&
context.currentVertex.equals(context.correspondingVertex1)
) {
context.correspondingVertex1._isIntersection = true
context.correspondingVertex1._relativePosition = 'on'

linkVertices(
context.currentVertex,
Expand All @@ -238,7 +236,6 @@ function insertDegeneratedIntersection(context) {
context.isCorrespondingVertex2OnLine &&
context.currentVertex.equals(context.correspondingVertex2)) {
context.correspondingVertex2._isIntersection = true
context.correspondingVertex2._relativePosition = 'on'

linkVertices(
context.currentVertex,
Expand All @@ -254,7 +251,10 @@ function insertDegeneratedIntersection(context) {
context.correspondingVertex2
)

linkVertices(context.currentVertex, intersectionVertex)
linkVertices(
context.currentVertex,
intersectionVertex
)

// sort into polygon
context.polygon.insertVertex(
Expand Down Expand Up @@ -317,6 +317,7 @@ function findIntersections(source, clip) {

do {
var clipNext = Polygon.getNext(clipVertex)

var intersection = new Intersection(
sourceVertex,
sourceNext,
Expand Down Expand Up @@ -468,7 +469,7 @@ Polygon.prototype.labelEntryOrExit = function (vertex) {
} else if (currentPairing == 'in/in') {
vertex._isEntry = true
} else if (currentPairing == 'on/on') {
labelEntryOrExit(vertex._corresponding);
this.labelEntryOrExit(vertex._corresponding);
vertex._isEntry = !vertex._corresponding._isEntry;
}
}
Expand All @@ -479,6 +480,22 @@ Polygon.prototype.labelEntryOrExit = function (vertex) {
}
};

function setRelativePositions(polygon, relativePolygon) {
var vertex = polygon.first
do {
if (vertex._isIntersection) {
vertex._relativePosition = 'on'
} else {
vertex.setRelativePosition(relativePolygon)
}
vertex = vertex.next
} while(vertex != polygon.first)
}

Polygon.prototype.setRelativePositions = function (polygon) {
setRelativePositions(this, polygon)
}

/**
== labelEntriesAndExits: source, clip ==
= pre-condition: every vertex in source and clip is labelled as 'entry' =
Expand Down Expand Up @@ -547,6 +564,7 @@ Polygon.prototype.labelEntriesAndExits = function(
vertex._corresponding._relativePosition = 'out'
}
}
vertex = vertex.next
} while (vertex != this.first)
}

Expand Down Expand Up @@ -723,12 +741,15 @@ Polygon.prototype.clip = function(clip, sourceForwards, clipForwards) {
this.findIntersections(clip)

// phase two - identify entry/exit points
this.setRelativePositions(clip)
clip.setRelativePositions(this)

var sourceInClip = this.first.isInside(clip);
var clipInSource = clip.first.isInside(this);

// TODO: explain why
sourceForwards ^= sourceInClip;
clipForwards ^= clipInSource;
// sourceForwards ^= sourceInClip;
// clipForwards ^= clipInSource;

this.labelEntriesAndExits(clip, sourceForwards, clipForwards)

Expand Down
1 change: 0 additions & 1 deletion src/vertex.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ Vertex.createIntersection = function(x, y, distance) {
var vertex = new Vertex(x, y)
vertex._distance = distance
vertex._isIntersection = true
vertex._isEntry = false
vertex._relativePosition = 'on'
return vertex
};
Expand Down
11 changes: 11 additions & 0 deletions test/clip-findIntersections.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ describe('Find Intersections', function() {
var p2 = new Polygon(points)

p1.findIntersections(p2)
p1.setRelativePositions(p2)
p2.setRelativePositions(p1)


expect(p1.vertices).to.equal(4)
expect(p2.vertices).to.equal(4)
Expand Down Expand Up @@ -66,6 +69,9 @@ describe('Find Intersections', function() {
])

p1.findIntersections(p2)
p1.setRelativePositions(p2)
p2.setRelativePositions(p1)


expect(p1.vertices).to.equal(6)
expect(p2.vertices).to.equal(6)
Expand Down Expand Up @@ -145,6 +151,8 @@ describe('Find Intersections', function() {
])

p1.findIntersections(p2)
p1.setRelativePositions(p2)
p2.setRelativePositions(p1)

expect(p1.vertices).to.equal(6)
expect(p2.vertices).to.equal(4)
Expand Down Expand Up @@ -214,6 +222,9 @@ describe('Find Intersections', function() {
])

p1.findIntersections(p2)
p1.setRelativePositions(p2)
p2.setRelativePositions(p1)


expect(p1.vertices).to.equal(4)
expect(p2.vertices).to.equal(3)
Expand Down
163 changes: 163 additions & 0 deletions test/clip-labelEntriesAndExits.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
var chai = require('chai')
var expect = chai.expect
var Polygon = require('../src/polygon')

function testOnPolygon(polygon, testResult, testFunction) {
var vertex = polygon.first
var index = 0
do {
if (testFunction(vertex, testResult[index])) {
index++
}
vertex = vertex.next
} while (vertex != polygon.first)
}

describe('Labelling Phase', function() {
var polygons = null
beforeEach(function() {
polygons = [
new Polygon([
[0, 0],
[4, 0],
[4, 2],
[0, 2]
]),
new Polygon([
[1, -1],
[3, -1],
[3, 3],
[1, 3]
])
]
})

it('should set relative positions correctly before labelling', function() {
polygons[0].findIntersections(polygons[1])
polygons[0].setRelativePositions(polygons[1])
polygons[1].setRelativePositions(polygons[0])

var testResults = [
'out',
'on',
'on',
'out',
'out',
'on',
'on',
'out'
]
var testResults1 = [
'out',
'out',
'on',
'on',
'out',
'out',
'on',
'on'
]

testOnPolygon(
polygons[0],
testResults,
function(vertex, testResult) {
expect(vertex._relativePosition).to.equal(testResult)
return true
}
)
testOnPolygon(
polygons[1],
testResults1,
function(vertex, testResult) {
expect(vertex._relativePosition).to.equal(testResult)
return true
}
)
})

it('should contain correct intersections for labelling', function() {
polygons[0].findIntersections(polygons[1])
var testResults = [
{x: 1, y: 0},
{x: 3, y: 0},
{x: 3, y: 2},
{x: 1, y: 2}
]

var testResults1 = [
{x: 3, y: 0},
{x: 3, y: 2},
{x: 1, y: 2},
{x: 1, y: 0}
]

testOnPolygon(
polygons[0],
testResults,
function(vertex, testResult) {
if (vertex._isIntersection) {
expect(vertex.equals(testResult)).to.be.true
return true
}
return false
}
)
testOnPolygon(
polygons[1],
testResults1,
function(vertex, testResult) {
if (vertex._isIntersection) {
expect(vertex.equals(testResult)).to.be.true
return true
}
return false
}
)
})

it('should label all nodes as entry before labbeling phase', function() {
polygons[0].findIntersections(polygons[1])

testOnPolygon(
polygons[0],
[],
function(vertex, testResult) {
expect(vertex._isEntry).to.be.true
return false
}
)
testOnPolygon(
polygons[1],
[],
function(vertex, testResult) {
expect(vertex._isEntry).to.be.true
return false
}
)

})

it('should label intersections correctly', function() {
var result = polygons[0].clip(polygons[1], true, true)
var testResults = [
true,
false,
true,
false
]

testOnPolygon(
polygons[0],
testResults,
function(vertex, testResult) {
if (vertex._isIntersection) {
console.log(vertex.x, vertex.y, vertex._isEntry, 't', testResult)
expect(vertex._isEntry).to.equal(testResult)
return true
}
return false
}
)
})
})
2 changes: 1 addition & 1 deletion test/clip.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var helpers = require('./helpers.js')
var wrapIntoObject = helpers.wrapIntoObject


describe('clip', function() {
describe('Arbitrary Clipping', function() {

var disjoint = []
var inherent = { in: null, out: null }
Expand Down
2 changes: 1 addition & 1 deletion test/vertex.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('Vertex Object', function() {
expect(v.y).to.equal(5)
expect(v._distance).to.equal(10)
expect(v._isIntersection).to.be.true
expect(v._isEntry).to.be.false
expect(v._isEntry).to.be.true
})

it('should detect two vertices as unequal', function() {
Expand Down

0 comments on commit 3565e4c

Please sign in to comment.