poly2tri
Version:
A 2D constrained Delaunay triangulation library
180 lines (152 loc) • 4.04 kB
JavaScript
/*
* Poly2Tri Copyright (c) 2009-2014, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* poly2tri.js (JavaScript port) (c) 2009-2014, Poly2Tri Contributors
* https://github.com/r3mi/poly2tri.js
*
* All rights reserved.
*
* Distributed under the 3-clause BSD License, see LICENSE.txt
*/
/* jshint maxcomplexity:11 */
"use strict";
/*
* Note
* ====
* the structure of this JavaScript version of poly2tri intentionally follows
* as closely as possible the structure of the reference C++ version, to make it
* easier to keep the 2 versions in sync.
*/
// -------------------------------------------------------------------------Node
/**
* Advancing front node
* @constructor
* @private
* @struct
* @param {!XY} p - Point
* @param {Triangle=} t triangle (optional)
*/
var Node = function(p, t) {
/** @type {XY} */
this.point = p;
/** @type {Triangle|null} */
this.triangle = t || null;
/** @type {Node|null} */
this.next = null;
/** @type {Node|null} */
this.prev = null;
/** @type {number} */
this.value = p.x;
};
// ---------------------------------------------------------------AdvancingFront
/**
* @constructor
* @private
* @struct
* @param {Node} head
* @param {Node} tail
*/
var AdvancingFront = function(head, tail) {
/** @type {Node} */
this.head_ = head;
/** @type {Node} */
this.tail_ = tail;
/** @type {Node} */
this.search_node_ = head;
};
/** @return {Node} */
AdvancingFront.prototype.head = function() {
return this.head_;
};
/** @param {Node} node */
AdvancingFront.prototype.setHead = function(node) {
this.head_ = node;
};
/** @return {Node} */
AdvancingFront.prototype.tail = function() {
return this.tail_;
};
/** @param {Node} node */
AdvancingFront.prototype.setTail = function(node) {
this.tail_ = node;
};
/** @return {Node} */
AdvancingFront.prototype.search = function() {
return this.search_node_;
};
/** @param {Node} node */
AdvancingFront.prototype.setSearch = function(node) {
this.search_node_ = node;
};
/** @return {Node} */
AdvancingFront.prototype.findSearchNode = function(/*x*/) {
// TODO: implement BST index
return this.search_node_;
};
/**
* @param {number} x value
* @return {Node}
*/
AdvancingFront.prototype.locateNode = function(x) {
var node = this.search_node_;
/* jshint boss:true */
if (x < node.value) {
while (node = node.prev) {
if (x >= node.value) {
this.search_node_ = node;
return node;
}
}
} else {
while (node = node.next) {
if (x < node.value) {
this.search_node_ = node.prev;
return node.prev;
}
}
}
return null;
};
/**
* @param {!XY} point - Point
* @return {Node}
*/
AdvancingFront.prototype.locatePoint = function(point) {
var px = point.x;
var node = this.findSearchNode(px);
var nx = node.point.x;
if (px === nx) {
// Here we are comparing point references, not values
if (point !== node.point) {
// We might have two nodes with same x value for a short time
if (point === node.prev.point) {
node = node.prev;
} else if (point === node.next.point) {
node = node.next;
} else {
throw new Error('poly2tri Invalid AdvancingFront.locatePoint() call');
}
}
} else if (px < nx) {
/* jshint boss:true */
while (node = node.prev) {
if (point === node.point) {
break;
}
}
} else {
while (node = node.next) {
if (point === node.point) {
break;
}
}
}
if (node) {
this.search_node_ = node;
}
return node;
};
// ----------------------------------------------------------------------Exports
module.exports = AdvancingFront;
module.exports.Node = Node;