Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
let lastCandidate = parseInt(chunks.length) - 1
for (let j = firstCandidate; j < lastCandidate; j++) {
let intersections = chunks[i].intersects(chunks[j])
if (intersections.length > 0) {
let intersection = intersections.pop()
let trimmedStart = chunks.slice(0, i)
let trimmedEnd = chunks.slice(parseInt(j) + 1)
let glue = new Path()
let first = true
for (let k of [i, j]) {
let ops = chunks[k].ops
if (ops[1].type === 'line') {
glue.line(intersection)
} else if (ops[1].type === 'curve') {
// handle curve
let curve = new Bezier(
{ x: ops[0].to.x, y: ops[0].to.y },
{ x: ops[1].cp1.x, y: ops[1].cp1.y },
{ x: ops[1].cp2.x, y: ops[1].cp2.y },
{ x: ops[1].to.x, y: ops[1].to.y }
)
let t = pointOnCurve(ops[0].to, ops[1].cp1, ops[1].cp2, ops[1].to, intersection)
let split = curve.split(t)
let side
if (first) side = split.left
else side = split.right
glue.curve(
new Point(side.points[1].x, side.points[1].y),
new Point(side.points[2].x, side.points[2].y),
new Point(side.points[3].x, side.points[3].y)
)
}
export function curvesIntersect(fromA, cp1A, cp2A, toA, fromB, cp1B, cp2B, toB) {
let precision = 0.005 // See https://github.com/Pomax/bezierjs/issues/99
let intersections = []
let curveA = new Bezier(
{ x: fromA.x, y: fromA.y },
{ x: cp1A.x, y: cp1A.y },
{ x: cp2A.x, y: cp2A.y },
{ x: toA.x, y: toA.y }
)
let curveB = new Bezier(
{ x: fromB.x, y: fromB.y },
{ x: cp1B.x, y: cp1B.y },
{ x: cp2B.x, y: cp2B.y },
{ x: toB.x, y: toB.y }
)
for (let tvalues of curveA.intersects(curveB, precision)) {
let intersection = curveA.get(tvalues.substr(0, tvalues.indexOf('/')))
intersections.push(new Point(intersection.x, intersection.y))
}
if (!arrowLength || arrowLength < 0) return;
const start = link.source;
const end = link.target;
if (!start.hasOwnProperty('x') || !end.hasOwnProperty('x')) return; // skip invalid link
const startR = Math.sqrt(Math.max(0, getNodeVal(start) || 1)) * state.nodeRelSize;
const endR = Math.sqrt(Math.max(0, getNodeVal(end) || 1)) * state.nodeRelSize;
const arrowRelPos = Math.min(1, Math.max(0, getRelPos(link)));
const arrowColor = getColor(link) || 'rgba(0,0,0,0.28)';
const arrowHalfWidth = arrowLength / ARROW_WH_RATIO / 2;
// Construct bezier for curved lines
const bzLine = link.__controlPoints && new Bezier(start.x, start.y, ...link.__controlPoints, end.x, end.y);
const getCoordsAlongLine = bzLine
? t => bzLine.get(t) // get position along bezier line
: t => ({ // straight line: interpolate linearly
x: start.x + (end.x - start.x) * t || 0,
y: start.y + (end.y - start.y) * t || 0
});
const lineLen = bzLine
? bzLine.length()
: Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2));
const posAlongLine = startR + arrowLength + (lineLen - startR - endR - arrowLength) * arrowRelPos;
const arrowHead = getCoordsAlongLine(posAlongLine / lineLen);
const arrowTail = getCoordsAlongLine((posAlongLine - arrowLength) / lineLen);
break;
}
case 'bezierCurveTo': {
let bez = new Bezier(currentPoint.x, currentPoint.y, args[0], args[1],
args[2], args[3], args[4], args[5]);
length += bez.length();
currentPoint.x = args[4];
currentPoint.y = args[5];
pushBezier_(bez);
expandBoundsToBezier_(bez);
break;
}
case 'quadraticCurveTo': {
let bez = new Bezier(currentPoint.x, currentPoint.y, args[0], args[1], args[2], args[3]);
length += bez.length();
currentPoint.x = args[2];
currentPoint.y = args[3];
pushBezier_(bez);
expandBoundsToBezier_(bez);
break;
}
case '__arc__': {
let [currentPointX, currentPointY,
rx, ry, xAxisRotation,
largeArcFlag, sweepFlag,
tempPoint1X, tempPoint1Y] = args;
if (currentPointX == tempPoint1X && currentPointY == tempPoint1Y) {
// degenerate to point (0 length)
const start = link.source;
const end = link.target;
if (!start.hasOwnProperty('x') || !end.hasOwnProperty('x')) return; // skip invalid link
const particleSpeed = getSpeed(link);
const photons = link.__photons || [];
const photonR = Math.max(0, getDiameter(link) / 2) / Math.sqrt(state.globalScale);
const photonColor = getColor(link) || 'rgba(0,0,0,0.28)';
ctx.fillStyle = photonColor;
// Construct bezier for curved lines
const bzLine = link.__controlPoints
? new Bezier(start.x, start.y, ...link.__controlPoints, end.x, end.y)
: null;
let cyclePhotonIdx = 0;
let needsCleanup = false; // whether some photons need to be removed from list
photons.forEach(photon => {
const singleHop = !!photon.__singleHop;
if (!photon.hasOwnProperty('__progressRatio')) {
photon.__progressRatio = singleHop ? 0 : cyclePhotonIdx / numCyclePhotons;
}
!singleHop && cyclePhotonIdx++; // increase regular photon index
photon.__progressRatio += particleSpeed;
if (photon.__progressRatio >=1) {
}
if (rx == 0 || ry == 0) {
// degenerate to line
length += dist_(currentPointX, currentPointY, tempPoint1X, tempPoint1Y);
expandBounds_(tempPoint1X, tempPoint1Y);
return;
}
let bezierCoords = arcToBeziers_(currentPointX, currentPointY,
rx, ry, xAxisRotation,
largeArcFlag, sweepFlag,
tempPoint1X, tempPoint1Y);
for (let i = 0; i < bezierCoords.length; i += 8) {
let bez = new Bezier(currentPoint.x, currentPoint.y,
bezierCoords[i + 2], bezierCoords[i + 3],
bezierCoords[i + 4], bezierCoords[i + 5],
bezierCoords[i + 6], bezierCoords[i + 7]);
length += bez.length();
currentPoint.x = bezierCoords[i + 6];
currentPoint.y = bezierCoords[i + 7];
expandBoundsToBezier_(bez);
}
currentPoint.x = tempPoint1X;
currentPoint.y = tempPoint1Y;
break;
}
}
});
commands.forEach(({command, args}) => {
switch (command) {
case 'moveTo': {
// start new sub-path
currentSubPath = [];
subPaths.push(currentSubPath);
lastMovePoint = {x:args[0], y:args[1]};
currentPoint.x = args[0];
currentPoint.y = args[1];
expandBounds_(args[0], args[1]);
break;
}
case 'lineTo': {
length += MathUtil.dist(args[0], args[1], currentPoint.x, currentPoint.y);
pushBezier_(new Bezier(
currentPoint.x, currentPoint.y,
args[0], args[1],
args[0], args[1]));
currentPoint.x = args[0];
currentPoint.y = args[1];
expandBounds_(args[0], args[1]);
break;
}
case 'closePath': {
if (lastMovePoint) {
length += MathUtil.dist(lastMovePoint.x, lastMovePoint.y, currentPoint.x, currentPoint.y);
pushBezier_(new Bezier(
currentPoint.x, currentPoint.y,
lastMovePoint.x, lastMovePoint.y,
lastMovePoint.x, lastMovePoint.y));
if (rx == 0 || ry == 0) {
// degenerate to line
length += MathUtil.dist(currentPointX, currentPointY, tempPoint1X, tempPoint1Y);
expandBounds_(tempPoint1X, tempPoint1Y);
currentPoint.x = tempPoint1X;
currentPoint.y = tempPoint1Y;
return;
}
let bezierCoords = arcToBeziers_(currentPointX, currentPointY,
rx, ry, xAxisRotation,
largeArcFlag, sweepFlag,
tempPoint1X, tempPoint1Y);
for (let i = 0; i < bezierCoords.length; i += 8) {
let bez = new Bezier(currentPoint.x, currentPoint.y,
bezierCoords[i + 2], bezierCoords[i + 3],
bezierCoords[i + 4], bezierCoords[i + 5],
bezierCoords[i + 6], bezierCoords[i + 7]);
length += bez.length();
currentPoint.x = bezierCoords[i + 6];
currentPoint.y = bezierCoords[i + 7];
expandBoundsToBezier_(bez);
pushBezier_(bez);
}
currentPoint.x = tempPoint1X;
currentPoint.y = tempPoint1Y;
break;
}
}
});
Path.prototype.shiftAlong = function(distance) {
let len = 0
let current
for (let i in this.ops) {
let op = this.ops[i]
if (op.type === 'line') {
let thisLen = op.to.dist(current)
if (len + thisLen > distance) return current.shiftTowards(op.to, distance - len)
else len += thisLen
} else if (op.type === 'curve') {
let bezier = new Bezier(
{ x: current.x, y: current.y },
{ x: op.cp1.x, y: op.cp1.y },
{ x: op.cp2.x, y: op.cp2.y },
{ x: op.to.x, y: op.to.y }
)
let thisLen = bezier.length()
if (len + thisLen > distance) return shiftAlongBezier(distance - len, bezier)
else len += thisLen
}
current = op.to
}
throw new Error(
`Error in Path.shiftAlong(): Ran out of path to shift along. Distance requested was ${distance}, path length is${this.length()}.`
)
}
export function lineIntersectsCurve(start, end, from, cp1, cp2, to) {
let intersections = []
let bz = new Bezier(
{ x: from.x, y: from.y },
{ x: cp1.x, y: cp1.y },
{ x: cp2.x, y: cp2.y },
{ x: to.x, y: to.y }
)
let line = {
p1: { x: start.x, y: start.y },
p2: { x: end.x, y: end.y }
}
for (let t of bz.intersects(line)) {
let isect = bz.get(t)
intersections.push(new Point(isect.x, isect.y))
}
if (intersections.length === 0) return false
else if (intersections.length === 1) return intersections[0]