mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-06 04:42:15 -05:00
New #contains method, that returns whether a point is on th path or not.\n\nThis resolves most of the failing tests.
This commit is contained in:
parent
ecb18af3c2
commit
94f69e4649
1 changed files with 91 additions and 82 deletions
173
Boolean.js
173
Boolean.js
|
@ -125,6 +125,8 @@
|
||||||
this.linkOut = this.linkOut || this.linkBOut; // linkOut
|
this.linkOut = this.linkOut || this.linkBOut; // linkOut
|
||||||
// Also update the references in links to point to "this" Node
|
// Also update the references in links to point to "this" Node
|
||||||
if( !this.linkIn || !this.linkOut ){
|
if( !this.linkIn || !this.linkOut ){
|
||||||
|
markPoint( this.point, this._intersectionID )
|
||||||
|
console.log( this )
|
||||||
throw { name: 'Boolean Error', message: 'No matching link found at ixID: ' +
|
throw { name: 'Boolean Error', message: 'No matching link found at ixID: ' +
|
||||||
this._intersectionID + " point: " + this.point.toString() };
|
this._intersectionID + " point: " + this.point.toString() };
|
||||||
}
|
}
|
||||||
|
@ -145,9 +147,10 @@
|
||||||
* @param {Node} _nodeOut
|
* @param {Node} _nodeOut
|
||||||
* @param {Any} _id
|
* @param {Any} _id
|
||||||
*/
|
*/
|
||||||
function Link( _nodeIn, _nodeOut, _id, isBaseContour ) {
|
function Link( _nodeIn, _nodeOut, _id, isBaseContour, _winding ) {
|
||||||
this.id = _id;
|
this.id = _id;
|
||||||
this.isBaseContour = isBaseContour;
|
this.isBaseContour = isBaseContour;
|
||||||
|
this.winding = _winding;
|
||||||
this.nodeIn = _nodeIn; // nodeStart
|
this.nodeIn = _nodeIn; // nodeStart
|
||||||
this.nodeOut = _nodeOut; // nodeEnd
|
this.nodeOut = _nodeOut; // nodeEnd
|
||||||
this.nodeIn.linkOut = this; // nodeStart.linkOut
|
this.nodeIn.linkOut = this; // nodeStart.linkOut
|
||||||
|
@ -172,13 +175,14 @@
|
||||||
*/
|
*/
|
||||||
function makeGraph( path, id, isBaseContour ){
|
function makeGraph( path, id, isBaseContour ){
|
||||||
var graph = [];
|
var graph = [];
|
||||||
var segs = path.segments, prevNode = null, firstNode = null, nuLink, nuNode;
|
var segs = path.segments, prevNode = null, firstNode = null, nuLink, nuNode,
|
||||||
|
winding = path.clockwise;
|
||||||
for( i = 0, l = segs.length; i < l; i++ ){
|
for( i = 0, l = segs.length; i < l; i++ ){
|
||||||
// var nuSeg = segs[i].clone();
|
// var nuSeg = segs[i].clone();
|
||||||
var nuSeg = segs[i];
|
var nuSeg = segs[i];
|
||||||
nuNode = new Node( nuSeg.point, nuSeg.handleIn, nuSeg.handleOut, id, isBaseContour );
|
nuNode = new Node( nuSeg.point, nuSeg.handleIn, nuSeg.handleOut, id, isBaseContour );
|
||||||
if( prevNode ) {
|
if( prevNode ) {
|
||||||
nuLink = new Link( prevNode, nuNode, id, isBaseContour );
|
nuLink = new Link( prevNode, nuNode, id, isBaseContour, winding );
|
||||||
graph.push( nuLink );
|
graph.push( nuLink );
|
||||||
}
|
}
|
||||||
prevNode = nuNode;
|
prevNode = nuNode;
|
||||||
|
@ -187,7 +191,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// the path is closed
|
// the path is closed
|
||||||
nuLink = new Link( prevNode, firstNode, id, isBaseContour );
|
nuLink = new Link( prevNode, firstNode, id, isBaseContour, winding );
|
||||||
graph.push( nuLink );
|
graph.push( nuLink );
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
@ -237,11 +241,11 @@
|
||||||
*
|
*
|
||||||
* Does NOT handle selfIntersecting CompoundPaths.
|
* Does NOT handle selfIntersecting CompoundPaths.
|
||||||
*
|
*
|
||||||
* @param {[type]} path [description]
|
* @param {CompoundPath} path Input CompoundPath, Note: This path could be modified if need be.
|
||||||
* @return {[type]} [description]
|
* @return {boolean} the winding direction of the base contour( true if clockwise )
|
||||||
*/
|
*/
|
||||||
function reorientCompoundPath( path ){
|
function reorientCompoundPath( path ){
|
||||||
if( !(path instanceof CompoundPath) ){ return; }
|
if( !(path instanceof CompoundPath) ){ return path.clockwise; }
|
||||||
var children = path.children, len = children.length, baseWinding;
|
var children = path.children, len = children.length, baseWinding;
|
||||||
var bounds = new Array( len );
|
var bounds = new Array( len );
|
||||||
var tmparray = new Array( len );
|
var tmparray = new Array( len );
|
||||||
|
@ -265,6 +269,7 @@
|
||||||
children[i].clockwise = baseWinding;
|
children[i].clockwise = baseWinding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return baseWinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -278,25 +283,32 @@
|
||||||
IntersectionID = 1;
|
IntersectionID = 1;
|
||||||
UNIQUE_ID = 1;
|
UNIQUE_ID = 1;
|
||||||
|
|
||||||
// The boolean operation may modify the original paths
|
// We work on duplicate paths since the algorithm may modify the original paths
|
||||||
var path1 = _path1.clone();
|
var path1 = _path1.clone();
|
||||||
var path2 = _path2.clone();
|
var path2 = _path2.clone();
|
||||||
// if( !path1.clockwise ){ path1.reverse(); }
|
|
||||||
// if( !path2.clockwise ){ path2.reverse(); }
|
|
||||||
//
|
|
||||||
var i, j, k, l, lnk, crv, node, nuNode, leftLink, rightLink;
|
var i, j, k, l, lnk, crv, node, nuNode, leftLink, rightLink;
|
||||||
var path1Clockwise, path2Clockwise;
|
var path1Clockwise = true, path2Clockwise = true;
|
||||||
|
|
||||||
// If one of the operands is empty, resolve self-intersections on the second operand
|
// If one of the operands is empty, resolve self-intersections on the second operand
|
||||||
var childCount1 = (_path1 instanceof CompoundPath)? _path1.children.length : _path1.curves.length;
|
var childCount1 = (_path1 instanceof CompoundPath)? _path1.children.length : _path1.curves.length;
|
||||||
var childCount2 = (_path2 instanceof CompoundPath)? _path2.children.length : _path2.curves.length;
|
var childCount2 = (_path2 instanceof CompoundPath)? _path2.children.length : _path2.curves.length;
|
||||||
var resolveSelfIntersections = !childCount1 | !childCount2;
|
var resolveSelfIntersections = !childCount1 | !childCount2;
|
||||||
|
|
||||||
|
// Reorient the compound paths, i.e. make all the islands wind in the same direction
|
||||||
|
// and holes in the opposit direction.
|
||||||
|
// Do this only if we are not resolving selfIntersections:
|
||||||
|
// Resolving self-intersections work on compound paths, but, we might get different results!
|
||||||
if( !resolveSelfIntersections ){
|
if( !resolveSelfIntersections ){
|
||||||
reorientCompoundPath( path1 );
|
path1Clockwise = reorientCompoundPath( path1 );
|
||||||
reorientCompoundPath( path2 );
|
path2Clockwise = reorientCompoundPath( path2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cache the bounding rectangle of paths
|
||||||
|
// so we can make the test for containment quite a bit faster
|
||||||
|
path1._bounds = (childCount1)? path1.bounds : null;
|
||||||
|
path2._bounds = (childCount2)? path2.bounds : null;
|
||||||
|
|
||||||
// Prepare the graphs. Graphs are list of Links that retains
|
// Prepare the graphs. Graphs are list of Links that retains
|
||||||
// full connectivity information. The order of links in a graph is not important
|
// full connectivity information. The order of links in a graph is not important
|
||||||
// That allows us to sort and merge graphs and 'splice' links with their splits easily.
|
// That allows us to sort and merge graphs and 'splice' links with their splits easily.
|
||||||
|
@ -306,7 +318,6 @@
|
||||||
path1Children = path1.children;
|
path1Children = path1.children;
|
||||||
for (i = 0, base = true, l = path1Children.length; i < l; i++, base = false) {
|
for (i = 0, base = true, l = path1Children.length; i < l; i++, base = false) {
|
||||||
path1Children[i].closed = true;
|
path1Children[i].closed = true;
|
||||||
if( base ){ path1Clockwise = path1Children[i].clockwise; }
|
|
||||||
graph = graph.concat( makeGraph( path1Children[i], 1, base ) );
|
graph = graph.concat( makeGraph( path1Children[i], 1, base ) );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -319,12 +330,12 @@
|
||||||
// if operator === BooleanOps.Subtraction, then reverse path2
|
// if operator === BooleanOps.Subtraction, then reverse path2
|
||||||
// so that the nodes and links will link correctly
|
// so that the nodes and links will link correctly
|
||||||
var reverse = ( operator === BooleanOps.Subtraction )? true: false;
|
var reverse = ( operator === BooleanOps.Subtraction )? true: false;
|
||||||
|
path2Clockwise = (reverse)? !path2Clockwise : path2Clockwise;
|
||||||
if( path2 instanceof CompoundPath ){
|
if( path2 instanceof CompoundPath ){
|
||||||
path2Children = path2.children;
|
path2Children = path2.children;
|
||||||
for (i = 0, base = true, l = path2Children.length; i < l; i++, base = false) {
|
for (i = 0, base = true, l = path2Children.length; i < l; i++, base = false) {
|
||||||
path2Children[i].closed = true;
|
path2Children[i].closed = true;
|
||||||
if( reverse ){ path2Children[i].reverse(); }
|
if( reverse ){path2Children[i].reverse(); }
|
||||||
if( base ){ path2Clockwise = path2Children[i].clockwise; }
|
|
||||||
graph = graph.concat( makeGraph( path2Children[i], 2, base ) );
|
graph = graph.concat( makeGraph( path2Children[i], 2, base ) );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -379,6 +390,7 @@
|
||||||
* for each link that intersects with another one, replace it with new split links.
|
* for each link that intersects with another one, replace it with new split links.
|
||||||
*/
|
*/
|
||||||
var ix, ixPoint, ixHandleI, ixHandleOut, param, isLinear, parts, left, right;
|
var ix, ixPoint, ixHandleI, ixHandleOut, param, isLinear, parts, left, right;
|
||||||
|
var values, nix, niy,nox, noy, niho, nohi, nihox, nihoy, nohix, nohiy;
|
||||||
for ( i = graph.length - 1; i >= 0; i--) {
|
for ( i = graph.length - 1; i >= 0; i--) {
|
||||||
if( graph[i].intersections.length ){
|
if( graph[i].intersections.length ){
|
||||||
ix = graph[i].intersections;
|
ix = graph[i].intersections;
|
||||||
|
@ -386,15 +398,20 @@
|
||||||
if( graph[i].intersections.length > 1 ){ ix.sort( ixSort ); }
|
if( graph[i].intersections.length > 1 ){ ix.sort( ixSort ); }
|
||||||
// Remove the graph link, this link has to be split and replaced with the splits
|
// Remove the graph link, this link has to be split and replaced with the splits
|
||||||
lnk = graph.splice( i, 1 )[0];
|
lnk = graph.splice( i, 1 )[0];
|
||||||
|
|
||||||
|
nix = lnk.nodeIn.point.x; niy = lnk.nodeIn.point.y;
|
||||||
|
nox = lnk.nodeOut.point.x; noy = lnk.nodeOut.point.y;
|
||||||
|
niho = lnk.nodeIn.handleOut; nohi = lnk.nodeOut.handleIn;
|
||||||
|
nihox = nihoy = nohix = nohiy = 0;
|
||||||
|
isLinear = true;
|
||||||
|
if( niho ){ nihox = niho.x; nihoy = niho.y; isLinear = false; }
|
||||||
|
if( nohi ){ nohix = nohi.x; nohiy = nohi.y; isLinear = false; }
|
||||||
|
values = [ nix, niy, nihox + nix, nihoy + niy,
|
||||||
|
nohix + nox, nohiy + noy, nox, noy ];
|
||||||
|
|
||||||
for (j =0, l=ix.length; j<l && lnk; j++) {
|
for (j =0, l=ix.length; j<l && lnk; j++) {
|
||||||
// TODO: optimize getCurve out of here, we only need the values to calculate subdivide
|
param = ix[j].parameter;
|
||||||
crv = lnk.getCurve();
|
// param = crv.getParameterOf( ix[j].point );
|
||||||
// We need to recalculate parameter after each curve split
|
|
||||||
// This operation (except for recalculating the curve parameter),
|
|
||||||
// is fairly similar to Curve.split method, except that it operates on Node and Link objects.
|
|
||||||
// TODO: Interpolate parameters instead of recalculating from points
|
|
||||||
param = crv.getParameterOf( ix[j].point );
|
|
||||||
// var param = crv.getNearestLocation( ix[j] ).parameter;
|
|
||||||
if( param === 0.0 || param === 1.0) {
|
if( param === 0.0 || param === 1.0) {
|
||||||
// Intersection falls on an existing node
|
// Intersection falls on an existing node
|
||||||
// there is no need to split the link
|
// there is no need to split the link
|
||||||
|
@ -409,8 +426,8 @@
|
||||||
rightLink = null;
|
rightLink = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
isLinear = crv.isLinear();
|
// parts = Curve.subdivide(crv.getValues(), param);
|
||||||
parts = Curve.subdivide(crv.getValues(), param);
|
parts = Curve.subdivide(values, param);
|
||||||
left = parts[0];
|
left = parts[0];
|
||||||
right = parts[1];
|
right = parts[1];
|
||||||
// Make new link and convert handles from absolute to relative
|
// Make new link and convert handles from absolute to relative
|
||||||
|
@ -420,6 +437,8 @@
|
||||||
ixHandleOut = new Point(right[2] - ixPoint.x, right[3] - ixPoint.y);
|
ixHandleOut = new Point(right[2] - ixPoint.x, right[3] - ixPoint.y);
|
||||||
} else {
|
} else {
|
||||||
ixHandleIn = ixHandleOut = null;
|
ixHandleIn = ixHandleOut = null;
|
||||||
|
right[2] = right[0];
|
||||||
|
right[3] = right[1];
|
||||||
}
|
}
|
||||||
nuNode = new Node( ixPoint, ixHandleIn, ixHandleOut, lnk.id, lnk.isBaseContour );
|
nuNode = new Node( ixPoint, ixHandleIn, ixHandleOut, lnk.id, lnk.isBaseContour );
|
||||||
nuNode.type = INTERSECTION_NODE;
|
nuNode.type = INTERSECTION_NODE;
|
||||||
|
@ -434,8 +453,10 @@
|
||||||
lnk.nodeOut.handleIn = new Point( right[4] - tmppnt.x, right[5] - tmppnt.y );
|
lnk.nodeOut.handleIn = new Point( right[4] - tmppnt.x, right[5] - tmppnt.y );
|
||||||
}
|
}
|
||||||
// Make new links after the split
|
// Make new links after the split
|
||||||
leftLink = new Link( lnk.nodeIn, nuNode, lnk.id, lnk.isBaseContour );
|
leftLink = new Link( lnk.nodeIn, nuNode, lnk.id, lnk.isBaseContour, lnk.winding );
|
||||||
rightLink = new Link( nuNode, lnk.nodeOut, lnk.id, lnk.isBaseContour );
|
rightLink = new Link( nuNode, lnk.nodeOut, lnk.id, lnk.isBaseContour, lnk.winding );
|
||||||
|
|
||||||
|
values = right;
|
||||||
}
|
}
|
||||||
// Add the first split link back to the graph, since we sorted the intersections
|
// Add the first split link back to the graph, since we sorted the intersections
|
||||||
// already, this link should contain no more intersections to the left.
|
// already, this link should contain no more intersections to the left.
|
||||||
|
@ -445,6 +466,13 @@
|
||||||
// continue with the second split link, to see if
|
// continue with the second split link, to see if
|
||||||
// there are more intersections to deal with
|
// there are more intersections to deal with
|
||||||
lnk = rightLink;
|
lnk = rightLink;
|
||||||
|
// Interpolate the rest of the parameters
|
||||||
|
if( lnk ) {
|
||||||
|
var one_minus_param = (1.0 - param);
|
||||||
|
for (k =j + 1, l=ix.length; k<l; k++) {
|
||||||
|
ix[k]._parameter = ( ix[k].parameter - param ) / one_minus_param;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Add the last split link back to the graph
|
// Add the last split link back to the graph
|
||||||
if( lnk ){
|
if( lnk ){
|
||||||
|
@ -453,55 +481,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// var EPSILON = 10e-12;
|
|
||||||
|
|
||||||
// for ( i = graph.length - 1; i >= 0; i--) {
|
|
||||||
// var lnk1 = graph[i];
|
|
||||||
// var lnk1nodeIn = lnk1.nodeIn, lnk1nodeOut = lnk1.nodeOut;
|
|
||||||
// if( graph[i].nodeIn.type !== INTERSECTION_NODE && graph[i].nodeOut.type !== INTERSECTION_NODE ) { continue; }
|
|
||||||
// annotateCurve( graph[i].getCurve(), "" )
|
|
||||||
// for ( j = i -1; j >= 0; j-- ) {
|
|
||||||
// if( graph[j].nodeIn.type !== INTERSECTION_NODE && graph[j].nodeOut.type !== INTERSECTION_NODE ) { continue; }
|
|
||||||
// var lnk2 = graph[j];
|
|
||||||
// var lnk2nodeIn = lnk2.nodeIn, lnk2nodeOut = lnk2.nodeOut;
|
|
||||||
|
|
||||||
|
|
||||||
// var he1 = false, he2 = false, he3 = false, he4 = false;
|
|
||||||
// if( lnk1nodeIn.handleOut ){ he1 = lnk1nodeIn.handleOut.isClose(lnk2nodeIn.handleOut, EPSILON); }
|
|
||||||
// if( lnk1nodeOut.handleIn ){ he2 = lnk1nodeOut.handleIn.isClose(lnk2nodeOut.handleIn, EPSILON); }
|
|
||||||
// if( lnk1nodeIn.handleOut ){ he3 = lnk1nodeIn.handleOut.isClose(lnk2nodeOut.handleIn, EPSILON); }
|
|
||||||
// if( lnk1nodeOut.handleIn ){ he4 = lnk1nodeOut.handleIn.isClose(lnk2nodeIn.handleOut, EPSILON); }
|
|
||||||
// var handleEq1 = ((lnk1nodeIn.handleOut && lnk1nodeIn.handleOut.isZero()) && (lnk2nodeIn.handleOut && lnk2nodeIn.handleOut.isZero()) || he1);
|
|
||||||
// var handleEq2 = ((lnk1nodeOut.handleIn && lnk1nodeOut.handleIn.isZero()) && (lnk2nodeOut.handleIn && lnk2nodeOut.handleIn.isZero()) || he2);
|
|
||||||
// var handleEq3 = ((lnk1nodeIn.handleOut && lnk1nodeIn.handleOut.isZero()) && (lnk2nodeOut.handleIn && lnk2nodeOut.handleIn.isZero()) || he3);
|
|
||||||
// var handleEq4 = ((lnk1nodeOut.handleIn && lnk1nodeOut.handleIn.isZero()) && (lnk2nodeIn.handleOut && lnk2nodeIn.handleOut.isZero()) || he4);
|
|
||||||
|
|
||||||
// if( i === 5 && j === 2 ){
|
|
||||||
// console.log( handleEq3, handleEq4, lnk1nodeIn.handleOut, lnk2nodeOut.handleIn, i, j )
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if( (lnk1nodeIn.point.isClose(lnk2nodeIn.point, EPSILON) && lnk1nodeOut.point.isClose(lnk2nodeOut.point, EPSILON) &&
|
|
||||||
// handleEq1 && handleEq2 ) ||
|
|
||||||
// (lnk1nodeIn.point.isClose(lnk2nodeOut.point, EPSILON) && lnk1nodeOut.point.isClose(lnk2nodeIn.point, EPSILON) &&
|
|
||||||
// handleEq3 && handleEq4 ) ){
|
|
||||||
|
|
||||||
// annotateCurve( graph[i].getCurve(), "", '#f00' )
|
|
||||||
// annotateCurve( graph[j].getCurve(), "", '#f00' )
|
|
||||||
|
|
||||||
// if( operator === BooleanOps.Union ){
|
|
||||||
// graph[i].INVALID = true;
|
|
||||||
// graph[j].INVALID = true;
|
|
||||||
// } else if( operator === BooleanOps.Intersection ){
|
|
||||||
// graph[i].SKIP_OPERATOR = true;
|
|
||||||
// graph[j].SKIP_OPERATOR = true;
|
|
||||||
// } else if( operator === BooleanOps.Subtraction ){
|
|
||||||
// graph[i].SKIP_OPERATOR = true;
|
|
||||||
// graph[j].INVALID = true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pass 3:
|
* Pass 3:
|
||||||
* Merge matching intersection Node Pairs (type is INTERSECTION_NODE &&
|
* Merge matching intersection Node Pairs (type is INTERSECTION_NODE &&
|
||||||
|
@ -521,16 +500,28 @@
|
||||||
|
|
||||||
// step 1: discard invalid links according to the boolean operator
|
// step 1: discard invalid links according to the boolean operator
|
||||||
for ( i = graph.length - 1; i >= 0; i--) {
|
for ( i = graph.length - 1; i >= 0; i--) {
|
||||||
var insidePath1, insidePath2;
|
var insidePath1 = false, insidePath2 = false, contains;
|
||||||
lnk = graph[i];
|
lnk = graph[i];
|
||||||
if( lnk.SKIP_OPERATOR ) { continue; }
|
// if( lnk.SKIP_OPERATOR ) { continue; }
|
||||||
if( !lnk.INVALID ) {
|
if( !lnk.INVALID ) {
|
||||||
crv = lnk.getCurve();
|
crv = lnk.getCurve();
|
||||||
// var midPoint = new Point(lnk.nodeIn.point);
|
// var midPoint = new Point(lnk.nodeIn.point);
|
||||||
var midPoint = crv.getPoint( 0.5 );
|
var midPoint = crv.getPoint( 0.5 );
|
||||||
// FIXME: new contains function : http://jsfiddle.net/QawX8/
|
// FIXME: new contains function : http://jsfiddle.net/QawX8/
|
||||||
insidePath1 = (lnk.id === 1 )? false : path1.contains( midPoint );
|
// If on a base curve, consider points on the curve and inside,
|
||||||
insidePath2 = (lnk.id === 2 )? false : path2.contains( midPoint );
|
// if not —for example a hole, points on the curve falls outside
|
||||||
|
if( lnk.id !== 1 ){
|
||||||
|
contains = contains2( path1, midPoint );
|
||||||
|
insidePath1 = (lnk.winding === path1Clockwise)? contains > 0: contains > 1;
|
||||||
|
}
|
||||||
|
if( lnk.id !== 2 ){
|
||||||
|
contains = contains2( path2, midPoint );
|
||||||
|
insidePath2 = (lnk.winding === path2Clockwise)? contains > 0: contains > 1;
|
||||||
|
}
|
||||||
|
// insidePath1 = (lnk.id === 1 )? false : contains2( path1, midPoint );
|
||||||
|
// insidePath2 = (lnk.id === 2 )? false : contains2( path2, midPoint );
|
||||||
|
// insidePath1 = (lnk.id === 1 )? false : path1.contains( midPoint );
|
||||||
|
// insidePath2 = (lnk.id === 2 )? false : path2.contains( midPoint );
|
||||||
}
|
}
|
||||||
if( lnk.INVALID || !operator( lnk, insidePath1, insidePath2 ) ){
|
if( lnk.INVALID || !operator( lnk, insidePath1, insidePath2 ) ){
|
||||||
// lnk = graph.splice( i, 1 )[0];
|
// lnk = graph.splice( i, 1 )[0];
|
||||||
|
@ -656,3 +647,21 @@ var _addLineIntersections = function(v1, v2, curve, locations) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function contains2( path, point ){
|
||||||
|
var res = 0;
|
||||||
|
var crv = path.getCurves();
|
||||||
|
var i = 0;
|
||||||
|
var bounds = path._bounds;
|
||||||
|
if( bounds && bounds.contains( point ) ){
|
||||||
|
for( i = 0; i < crv.length && !res; i++ ){
|
||||||
|
var crvi = crv[i];
|
||||||
|
if( crvi.bounds.contains( point ) && crvi.getParameterOf( point ) ){
|
||||||
|
res = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( !res ){
|
||||||
|
res = (path.contains(point))? 2: res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue