0
0
Fork 0
mirror of https://github.com/liabru/matter-js.git synced 2024-11-23 09:26:51 -05:00

Add removeDuplicatePoints option from polygon-decomp 0.3.0 to Bodies.fromVertices()

This commit is contained in:
Jonathan Deutsch 2018-07-26 14:33:39 -07:00
parent 7894b4b44d
commit 6c5d4065c2
2 changed files with 67 additions and 5 deletions

View file

@ -4,6 +4,7 @@ module.exports = {
quickDecomp: polygonQuickDecomp, quickDecomp: polygonQuickDecomp,
isSimple: polygonIsSimple, isSimple: polygonIsSimple,
removeCollinearPoints: polygonRemoveCollinearPoints, removeCollinearPoints: polygonRemoveCollinearPoints,
removeDuplicatePoints: polygonRemoveDuplicatePoints,
makeCCW: polygonMakeCCW makeCCW: polygonMakeCCW
}; };
@ -179,6 +180,9 @@ function polygonMakeCCW(polygon){
// reverse poly if clockwise // reverse poly if clockwise
if (!isLeft(polygonAt(polygon, br - 1), polygonAt(polygon, br), polygonAt(polygon, br + 1))) { if (!isLeft(polygonAt(polygon, br - 1), polygonAt(polygon, br), polygonAt(polygon, br + 1))) {
polygonReverse(polygon); polygonReverse(polygon);
return true;
} else {
return false;
} }
} }
@ -243,6 +247,27 @@ function polygonCanSee(polygon, a,b) {
return true; return true;
} }
/**
* Check if two vertices in the polygon can see each other
* @method canSee2
* @param {Number} a Vertex index 1
* @param {Number} b Vertex index 2
* @return {Boolean}
*/
function polygonCanSee2(polygon, a,b) {
// for each edge
for (var i = 0; i !== polygon.length; ++i) {
// ignore incident edges
if (i === a || i === b || (i + 1) % polygon.length === a || (i + 1) % polygon.length === b){
continue;
}
if( lineSegmentsIntersect(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i), polygonAt(polygon, i+1)) ){
return false;
}
}
return true;
}
/** /**
* Copy the polygon from vertex i to vertex j. * Copy the polygon from vertex i to vertex j.
* @method copy * @method copy
@ -526,9 +551,12 @@ function polygonQuickDecomp(polygon, result,reflexVertices,steinerPoints,delta,m
} }
for (var j = lowerIndex; j <= upperIndex; ++j) { for (var j = lowerIndex; j <= upperIndex; ++j) {
if (isLeftOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))) { if (
isLeftOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) &&
isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))
) {
d = sqdist(polygonAt(poly, i), polygonAt(poly, j)); d = sqdist(polygonAt(poly, i), polygonAt(poly, j));
if (d < closestDist) { if (d < closestDist && polygonCanSee2(poly, i, j)) {
closestDist = d; closestDist = d;
closestIndex = j % polygon.length; closestIndex = j % polygon.length;
} }
@ -585,6 +613,23 @@ function polygonRemoveCollinearPoints(polygon, precision){
return num; return num;
} }
/**
* Remove duplicate points in the polygon.
* @method removeDuplicatePoints
* @param {Number} [precision] The threshold to use when determining whether two points are the same. Use zero for best precision.
*/
function polygonRemoveDuplicatePoints(polygon, precision){
for(var i=polygon.length-1; i>=1; --i){
var pi = polygon[i];
for(var j=i-1; j>=0; --j){
if(points_eq(pi, polygon[j], precision)){
polygon.splice(i,1);
continue;
}
}
}
}
/** /**
* Check if two scalars are equal * Check if two scalars are equal
* @static * @static
@ -596,9 +641,22 @@ function polygonRemoveCollinearPoints(polygon, precision){
*/ */
function scalar_eq(a,b,precision){ function scalar_eq(a,b,precision){
precision = precision || 0; precision = precision || 0;
return Math.abs(a-b) < precision; return Math.abs(a-b) <= precision;
}
/**
* Check if two points are equal
* @static
* @method points_eq
* @param {Array} a
* @param {Array} b
* @param {Number} [precision]
* @return {Boolean}
*/
function points_eq(a,b,precision){
return scalar_eq(a[0],b[0],precision) && scalar_eq(a[1],b[1],precision);
} }
},{}]},{},[1]) },{}]},{},[1])
(1) (1)
}); });

View file

@ -194,9 +194,10 @@ var decomp;
* @param {bool} [flagInternal=false] * @param {bool} [flagInternal=false]
* @param {number} [removeCollinear=0.01] * @param {number} [removeCollinear=0.01]
* @param {number} [minimumArea=10] * @param {number} [minimumArea=10]
* @param {number} [removeDuplicatePoints=0.1]
* @return {body} * @return {body}
*/ */
Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea) { Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea, removeDuplicatePoints) {
if (!decomp) { if (!decomp) {
decomp = Common._requireGlobal('decomp', 'poly-decomp'); decomp = Common._requireGlobal('decomp', 'poly-decomp');
} }
@ -217,6 +218,7 @@ var decomp;
flagInternal = typeof flagInternal !== 'undefined' ? flagInternal : false; flagInternal = typeof flagInternal !== 'undefined' ? flagInternal : false;
removeCollinear = typeof removeCollinear !== 'undefined' ? removeCollinear : 0.01; removeCollinear = typeof removeCollinear !== 'undefined' ? removeCollinear : 0.01;
minimumArea = typeof minimumArea !== 'undefined' ? minimumArea : 10; minimumArea = typeof minimumArea !== 'undefined' ? minimumArea : 10;
removeDuplicatePoints = typeof removeDuplicatePoints !== 'undefined' ? removeDuplicatePoints : 0.1;
if (!decomp) { if (!decomp) {
Common.warn('Bodies.fromVertices: poly-decomp.js required. Could not decompose vertices. Fallback to convex hull.'); Common.warn('Bodies.fromVertices: poly-decomp.js required. Could not decompose vertices. Fallback to convex hull.');
@ -253,6 +255,8 @@ var decomp;
decomp.makeCCW(concave); decomp.makeCCW(concave);
if (removeCollinear !== false) if (removeCollinear !== false)
decomp.removeCollinearPoints(concave, removeCollinear); decomp.removeCollinearPoints(concave, removeCollinear);
if (removeDuplicatePoints !== false)
decomp.removeDuplicatePoints(concave, removeDuplicatePoints);
// use the quick decomposition algorithm (Bayazit) // use the quick decomposition algorithm (Bayazit)
var decomposed = decomp.quickDecomp(concave); var decomposed = decomp.quickDecomp(concave);