✨ Added path.trim()
This commit is contained in:
parent
c44b888323
commit
3738b5e98c
2 changed files with 41 additions and 58 deletions
47
src/path.js
47
src/path.js
|
@ -287,15 +287,17 @@ function asPath(bezier) {
|
||||||
/** Joins path segments together into one path */
|
/** Joins path segments together into one path */
|
||||||
function joinPaths(paths, closed = false) {
|
function joinPaths(paths, closed = false) {
|
||||||
let joint = new Path().move(paths[0].ops[0].to);
|
let joint = new Path().move(paths[0].ops[0].to);
|
||||||
|
let current;
|
||||||
for (let p of paths) {
|
for (let p of paths) {
|
||||||
for (let op of p.ops) {
|
for (let op of p.ops) {
|
||||||
if (op.type === "curve") {
|
if (op.type === "curve") {
|
||||||
joint.curve(op.cp1, op.cp2, op.to);
|
joint.curve(op.cp1, op.cp2, op.to);
|
||||||
} else if (op.type !== "close") {
|
} else if (op.type !== "close") {
|
||||||
joint.line(op.to);
|
if (current && !op.to.sitsOn(current)) joint.line(op.to);
|
||||||
} else {
|
} else {
|
||||||
throw "Cannot join a closed paths with another";
|
throw "Cannot join a closed paths with another";
|
||||||
}
|
}
|
||||||
|
if (op.to) current = op.to;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (closed) joint.close();
|
if (closed) joint.close();
|
||||||
|
@ -507,9 +509,9 @@ Path.prototype.divide = function() {
|
||||||
for (let i in this.ops) {
|
for (let i in this.ops) {
|
||||||
let op = this.ops[i];
|
let op = this.ops[i];
|
||||||
if (op.type === "move") {
|
if (op.type === "move") {
|
||||||
current = op.to;
|
|
||||||
start = op.to;
|
start = op.to;
|
||||||
} else if (op.type === "line") {
|
} else if (op.type === "line") {
|
||||||
|
if (!op.to.sitsOn(current))
|
||||||
paths.push(new Path().move(current).line(op.to));
|
paths.push(new Path().move(current).line(op.to));
|
||||||
} else if (op.type === "curve") {
|
} else if (op.type === "curve") {
|
||||||
paths.push(new Path().move(current).curve(op.cp1, op.cp2, op.to));
|
paths.push(new Path().move(current).curve(op.cp1, op.cp2, op.to));
|
||||||
|
@ -703,7 +705,6 @@ Path.prototype.split = function(point) {
|
||||||
|
|
||||||
/** Removes self-intersections (overlap) from the path */
|
/** Removes self-intersections (overlap) from the path */
|
||||||
Path.prototype.trim = function() {
|
Path.prototype.trim = function() {
|
||||||
// Walk the path to find all intersections
|
|
||||||
let chunks = this.divide();
|
let chunks = this.divide();
|
||||||
for (let i in chunks) {
|
for (let i in chunks) {
|
||||||
let chunk = chunks[i];
|
let chunk = chunks[i];
|
||||||
|
@ -716,7 +717,9 @@ Path.prototype.trim = function() {
|
||||||
let trimmedStart = chunks.slice(0, i);
|
let trimmedStart = chunks.slice(0, i);
|
||||||
let trimmedEnd = chunks.slice(parseInt(j) + 1);
|
let trimmedEnd = chunks.slice(parseInt(j) + 1);
|
||||||
let glue = new Path();
|
let glue = new Path();
|
||||||
let ops = chunks[i].ops;
|
let first = true;
|
||||||
|
for (let k of [i, j]) {
|
||||||
|
let ops = chunks[k].ops;
|
||||||
if (ops[1].type === "line") {
|
if (ops[1].type === "line") {
|
||||||
glue.line(intersection);
|
glue.line(intersection);
|
||||||
} else if (ops[1].type === "curve") {
|
} else if (ops[1].type === "curve") {
|
||||||
|
@ -735,43 +738,23 @@ Path.prototype.trim = function() {
|
||||||
intersection
|
intersection
|
||||||
);
|
);
|
||||||
let split = curve.split(t);
|
let split = curve.split(t);
|
||||||
|
let side;
|
||||||
|
if (first) side = split.left;
|
||||||
|
else side = split.right;
|
||||||
glue.curve(
|
glue.curve(
|
||||||
new Point(split.left.points[1].x, split.left.points[1].y),
|
new Point(side.points[1].x, side.points[1].y),
|
||||||
new Point(split.left.points[2].x, split.left.points[2].y),
|
new Point(side.points[2].x, side.points[2].y),
|
||||||
new Point(split.left.points[3].x, split.left.points[3].y)
|
new Point(side.points[3].x, side.points[3].y)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ops = chunks[j].ops;
|
first = false;
|
||||||
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);
|
|
||||||
glue.curve(
|
|
||||||
new Point(split.right.points[1].x, split.right.points[1].y),
|
|
||||||
new Point(split.right.points[2].x, split.right.points[2].y),
|
|
||||||
new Point(split.right.points[3].x, split.right.points[3].y)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
let joint;
|
let joint;
|
||||||
if (trimmedStart.length > 0) joint = joinPaths(trimmedStart).join(glue);
|
if (trimmedStart.length > 0) joint = joinPaths(trimmedStart).join(glue);
|
||||||
else joint = glue;
|
else joint = glue;
|
||||||
if (trimmedEnd.length > 0) joint = joint.join(joinPaths(trimmedEnd));
|
if (trimmedEnd.length > 0) joint = joint.join(joinPaths(trimmedEnd));
|
||||||
|
|
||||||
return joint;
|
return joint.trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,8 @@ it("Should offset a curve where cp1 = start", () => {
|
||||||
.curve(new a.Point(0, 0), new a.Point(123, 34), new a.Point(23, 4));
|
.curve(new a.Point(0, 0), new a.Point(123, 34), new a.Point(23, 4));
|
||||||
a.paths.offset = a.paths.curve.offset(10);
|
a.paths.offset = a.paths.curve.offset(10);
|
||||||
pattern.render();
|
pattern.render();
|
||||||
expect(a.paths.offset.bottomRight.x).to.equal(72.50457052909852);
|
expect(a.paths.offset.bottomRight.x).to.equal(72.6776854668095);
|
||||||
expect(a.paths.offset.bottomRight.y).to.equal(26.44);
|
expect(a.paths.offset.bottomRight.y).to.equal(26.49);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should offset a curve where cp2 = end", () => {
|
it("Should offset a curve where cp2 = end", () => {
|
||||||
|
@ -53,8 +53,8 @@ it("Should offset a curve where cp2 = end", () => {
|
||||||
.close();
|
.close();
|
||||||
a.paths.offset = a.paths.curve.offset(10);
|
a.paths.offset = a.paths.curve.offset(10);
|
||||||
pattern.render();
|
pattern.render();
|
||||||
expect(a.paths.offset.bottomRight.x).to.equal(119.23);
|
expect(a.paths.offset.bottomRight.x).to.equal(119.25);
|
||||||
expect(a.paths.offset.bottomRight.y).to.equal(43.26);
|
expect(a.paths.offset.bottomRight.y).to.equal(43.27);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should throw error when offsetting line that is no line", () => {
|
it("Should throw error when offsetting line that is no line", () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue