提交 78e2be1a 编写于 作者: J Juergen Ahting

THREE.Path.toShapes is now independent of the order of specification of holes...

THREE.Path.toShapes is now independent of the order of specification of holes and shapes. It moves holes to those shapes that contain them if unambiguous. Otherwise it respects specification order.
上级 a347231b
......@@ -440,6 +440,51 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
THREE.Path.prototype.toShapes = function( isCCW ) {
function isPointInsidePolygon( inPt, inPolygon ) {
var EPSILON = 0.0000000001;
var polyLen = inPolygon.length;
// inPt on polygon contour => immediate success or
// toggling of inside/outside at every single! intersection point of an edge
// with the horizontal line through inPt, left of inPt
// not counting lowerY endpoints of edges and whole edges on that line
var inside = false;
for( var p = polyLen - 1, q = 0; q < polyLen; p = q++ ) {
var edgeLowPt = inPolygon[ p ];
var edgeHighPt = inPolygon[ q ];
var edgeDx = edgeHighPt.x - edgeLowPt.x;
var edgeDy = edgeHighPt.y - edgeLowPt.y;
if ( Math.abs(edgeDy) > EPSILON ) { // not parallel
if ( edgeDy < 0 ) {
edgeLowPt = inPolygon[ q ]; edgeDx = -edgeDx;
edgeHighPt = inPolygon[ p ]; edgeDy = -edgeDy;
}
if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue;
if ( inPt.y == edgeLowPt.y ) {
if ( inPt.x == edgeLowPt.x ) return true; // inPt is on contour ?
// continue; // no intersection or edgeLowPt => doesn't count !!!
} else {
var perpEdge = edgeDy * (inPt.x - edgeLowPt.x) - edgeDx * (inPt.y - edgeLowPt.y);
if ( perpEdge == 0 ) return true; // inPt is on contour ?
if ( perpEdge < 0 ) continue;
inside = !inside; // true intersection left of inPt
}
} else { // parallel or colinear
if ( inPt.y != edgeLowPt.y ) continue; // parallel
// egde lies on the same horizontal line as inPt
if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||
( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour !
// continue;
}
}
return inside;
}
var i, il, item, action, args;
var subPaths = [], lastPath = new THREE.Path();
......@@ -493,66 +538,88 @@ THREE.Path.prototype.toShapes = function( isCCW ) {
holesFirst = isCCW ? !holesFirst : holesFirst;
// console.log("Holes first", holesFirst);
var betterShapeHoles = [];
var newShapes = [];
var newShapeHoles = [];
var mainIdx = 0;
var tmpPoints;
if ( holesFirst ) {
newShapes[mainIdx] = undefined;
newShapeHoles[mainIdx] = [];
tmpShape = new THREE.Shape();
for ( i = 0, il = subPaths.length; i < il; i ++ ) {
for ( i = 0, il = subPaths.length; i < il; i ++ ) {
tmpPath = subPaths[ i ];
solid = THREE.Shape.Utils.isClockWise( tmpPath.getPoints() );
solid = isCCW ? !solid : solid;
tmpPath = subPaths[ i ];
tmpPoints = tmpPath.getPoints();
solid = THREE.Shape.Utils.isClockWise( tmpPoints );
solid = isCCW ? !solid : solid;
if ( solid ) {
if ( solid ) {
tmpShape.actions = tmpPath.actions;
tmpShape.curves = tmpPath.curves;
if ( (! holesFirst ) && ( newShapes[mainIdx] ) ) mainIdx++;
shapes.push( tmpShape );
tmpShape = new THREE.Shape();
newShapes[mainIdx] = { s: new THREE.Shape(), p: tmpPoints };
newShapes[mainIdx].s.actions = tmpPath.actions;
newShapes[mainIdx].s.curves = tmpPath.curves;
if ( holesFirst ) mainIdx++;
newShapeHoles[mainIdx] = [];
//console.log('cw', i);
//console.log('cw', i);
} else {
} else {
tmpShape.holes.push( tmpPath );
newShapeHoles[mainIdx].push( { h: tmpPath, p: tmpPoints[0] } );
//console.log('ccw', i);
}
//console.log('ccw', i);
}
} else {
// Shapes first
tmpShape = undefined;
for ( i = 0, il = subPaths.length; i < il; i ++ ) {
tmpPath = subPaths[ i ];
solid = THREE.Shape.Utils.isClockWise( tmpPath.getPoints() );
solid = isCCW ? !solid : solid;
if ( solid ) {
if ( tmpShape ) shapes.push( tmpShape );
tmpShape = new THREE.Shape();
tmpShape.actions = tmpPath.actions;
tmpShape.curves = tmpPath.curves;
} else {
}
tmpShape.holes.push( tmpPath );
if ( newShapes.length > 1 ) {
var ambigious = false;
var toChange = [];
for (var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++ ) {
betterShapeHoles[sIdx] = [];
}
for (var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++ ) {
var sh = newShapes[sIdx];
var sho = newShapeHoles[sIdx];
for (var hIdx = 0; hIdx < sho.length; hIdx++ ) {
var ho = sho[hIdx];
var hole_unassigned = true;
for (var s2Idx = 0; s2Idx < newShapes.length; s2Idx++ ) {
if ( isPointInsidePolygon( ho.p, newShapes[s2Idx].p ) ) {
if ( sIdx != s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } );
if ( hole_unassigned ) {
hole_unassigned = false;
betterShapeHoles[s2Idx].push( ho );
} else {
ambigious = true;
}
}
}
if ( hole_unassigned ) { betterShapeHoles[sIdx].push( ho ); }
}
}
// console.log("ambigious: ", ambigious);
if ( toChange.length > 0 ) {
// console.log("to change: ", toChange);
if (! ambigious) newShapeHoles = betterShapeHoles;
}
}
var tmpHoles, j, jl;
for ( i = 0, il = newShapes.length; i < il; i ++ ) {
tmpShape = newShapes[i].s;
shapes.push( tmpShape );
tmpHoles = newShapeHoles[i];
for ( j = 0, jl = tmpHoles.length; j < jl; j ++ ) {
tmpShape.holes.push( tmpHoles[j].h );
}
}
//console.log("shape", shapes);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册