1
0
Fork 0

Added Path.edge()

This commit is contained in:
Joost De Cock 2018-08-20 17:10:28 +02:00
parent bb597282ee
commit 04bf540a5a
2 changed files with 176 additions and 8 deletions

View file

@ -123,13 +123,26 @@ Path.prototype.boundary = function() {
let current;
let topLeft = new Point(Infinity, Infinity);
let bottomRight = new Point(-Infinity, -Infinity);
let edges = [];
for (let i in this.ops) {
let op = this.ops[i];
if (op.type === "move" || op.type === "line") {
if (op.to.x < topLeft.x) topLeft.x = op.to.x;
if (op.to.y < topLeft.y) topLeft.y = op.to.y;
if (op.to.x > bottomRight.x) bottomRight.x = op.to.x;
if (op.to.y > bottomRight.y) bottomRight.y = op.to.y;
if (op.to.x < topLeft.x) {
topLeft.x = op.to.x;
edges["leftOp"] = i;
}
if (op.to.y < topLeft.y) {
topLeft.y = op.to.y;
edges["topOp"] = i;
}
if (op.to.x > bottomRight.x) {
bottomRight.x = op.to.x;
edges["rightOp"] = i;
}
if (op.to.y > bottomRight.y) {
bottomRight.y = op.to.y;
edges["bottomOp"] = i;
}
} else if (op.type === "curve") {
let bb = new Bezier(
{ x: current.x, y: current.y },
@ -137,10 +150,22 @@ Path.prototype.boundary = function() {
{ x: op.cp2.x, y: op.cp2.y },
{ x: op.to.x, y: op.to.y }
).bbox();
if (bb.x.min < topLeft.x) topLeft.x = bb.x.min;
if (bb.y.min < topLeft.y) topLeft.y = bb.y.min;
if (bb.x.max > bottomRight.x) bottomRight.x = bb.x.max;
if (bb.y.max > bottomRight.y) bottomRight.y = bb.y.max;
if (bb.x.min < topLeft.x) {
topLeft.x = bb.x.min;
edges["leftOp"] = i;
}
if (bb.y.min < topLeft.y) {
topLeft.y = bb.y.min;
edges["topOp"] = i;
}
if (bb.x.max > bottomRight.x) {
bottomRight.x = bb.x.max;
edges["rightOp"] = i;
}
if (bb.y.max > bottomRight.y) {
bottomRight.y = bb.y.max;
edges["bottomOp"] = i;
}
}
if (op.to) current = op.to;
}
@ -148,6 +173,13 @@ Path.prototype.boundary = function() {
this.topLeft = topLeft;
this.bottomRight = bottomRight;
for (let side of ["top", "left", "bottom", "right"]) {
let s = side + "Op";
this[s] = this.ops[edges[s]];
this[s].from =
this[s].type === "move" ? this[s].to : this.ops[edges[s] - 1].to;
}
return this;
};
@ -418,4 +450,74 @@ Path.prototype.reverse = function() {
return rev;
};
/** Returns a reversed version of this */
Path.prototype.edge = function(side) {
this.boundary();
if (side === "topLeft") return this.topLeft;
else if (side === "bottomRight") return this.bottomRight;
else if (side === "topRight")
return new Point(this.bottomRight.x, this.topLeft.y);
else if (side === "bottomLeft")
return new Point(this.topLeft.x, this.bottomRight.y);
else {
let s = side + "Op";
if (this[s].type === "move") return this[s].to;
else if (this[s].type === "line") {
if (side === "top") {
if (this.topOp.to.y < this.topOp.from.y) return this.topOp.to;
else return this.topOp.to;
} else if (side === "left") {
if (this.leftOp.to.x < this.leftOp.from.x) return this.leftOp.to;
else return this.leftOp.to;
} else if (side === "bottom") {
if (this.bottomOp.to.y > this.bottomOp.from.y) return this.bottomOp.to;
else return this.bottomOp.to;
} else if (side === "right") {
if (this.rightOp.to.x > this.rightOp.from.x) return this.rightOp.to;
else return this.rightOp.to;
}
} else if (this[s].type === "curve") {
let line;
if (side === "top")
line = {
p1: { x: this.topLeft.x, y: this.topLeft.y },
p2: { x: this.bottomRight.x, y: this.topLeft.y }
};
else if (side === "left")
line = {
p1: { x: this.topLeft.x, y: this.topLeft.y },
p2: { x: this.topLeft.x, y: this.bottomRight.y }
};
else if (side === "bottom")
line = {
p1: { x: this.topLeft.x, y: this.bottomRight.y },
p2: { x: this.bottomRight.x, y: this.bottomRight.y }
};
else if (side === "right")
line = {
p1: { x: this.bottomRight.x, y: this.topLeft.y },
p2: { x: this.bottomRight.x, y: this.bottomRight.y }
};
let bz = edgeCurveAsBezier(this[s]);
let isect = bz.intersects(line);
let edge = bz.get(isect[0]);
return new Point(edge.x, edge.y);
}
}
};
function edgeCurveAsBezier(op) {
return new Bezier(
{ x: op.from.x, y: op.from.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 }
);
}
///* Returns the edge of a single path operation */
//function opEdge(op, side) {
// if(op.type === 'move' || op.type
//
//}
export default Path;

View file

@ -329,3 +329,69 @@ it("Should reverse a path", () => {
expect(rev.ops[1].type).to.equal("curve");
expect(rev.ops[2].type).to.equal("line");
});
it("Should find the edges of a path", () => {
let pattern = new freesewing.Pattern();
pattern.parts.a = new pattern.Part();
let a = pattern.parts.a;
a.points.A = new a.Point(45, 60);
a.points.B = new a.Point(10, 30);
a.points.BCp2 = new a.Point(40, 20);
a.points.C = new a.Point(90, 30);
a.points.CCp1 = new a.Point(50, -30);
a.points.D = new a.Point(-60, 90);
a.points.E = new a.Point(90, 190);
a.paths.test = new a.Path()
.move(a.points.A)
.line(a.points.B)
.curve(a.points.BCp2, a.points.CCp1, a.points.C)
.curve(a.points.E, a.points.D, a.points.A)
.close();
expect(round(a.paths.test.edge("topLeft").x)).to.equal(7.7);
expect(round(a.paths.test.edge("topLeft").y)).to.equal(0.97);
expect(round(a.paths.test.edge("bottomLeft").x)).to.equal(7.7);
expect(round(a.paths.test.edge("bottomLeft").y)).to.equal(118.46);
expect(round(a.paths.test.edge("bottomRight").x)).to.equal(90);
expect(round(a.paths.test.edge("bottomRight").y)).to.equal(118.46);
expect(round(a.paths.test.edge("topRight").x)).to.equal(90);
expect(round(a.paths.test.edge("topRight").y)).to.equal(0.97);
expect(round(a.paths.test.edge("left").x)).to.equal(7.7);
expect(round(a.paths.test.edge("left").y)).to.equal(91.7);
expect(round(a.paths.test.edge("bottom").x)).to.equal(40.75);
expect(round(a.paths.test.edge("bottom").y)).to.equal(118.46);
expect(round(a.paths.test.edge("right").x)).to.equal(90);
expect(round(a.paths.test.edge("right").y)).to.equal(30);
expect(round(a.paths.test.edge("top").x)).to.equal(55.97);
expect(round(a.paths.test.edge("top").y)).to.equal(0.97);
});
it("Should find the edges of a path for corner cases", () => {
let pattern = new freesewing.Pattern();
pattern.parts.a = new pattern.Part();
let a = pattern.parts.a;
a.points.A = new a.Point(-45, -60);
a.points.B = new a.Point(45, 60);
a.points.C = new a.Point(-90, -160);
a.paths.test = new a.Path().move(a.points.A).line(a.points.B);
expect(round(a.paths.test.edge("top").x)).to.equal(-45);
expect(round(a.paths.test.edge("top").y)).to.equal(-60);
expect(round(a.paths.test.edge("left").x)).to.equal(-45);
expect(round(a.paths.test.edge("left").y)).to.equal(-60);
expect(round(a.paths.test.edge("bottom").x)).to.equal(45);
expect(round(a.paths.test.edge("bottom").y)).to.equal(60);
expect(round(a.paths.test.edge("right").x)).to.equal(45);
expect(round(a.paths.test.edge("right").y)).to.equal(60);
a.paths.test = new a.Path().move(a.points.B).line(a.points.A);
expect(round(a.paths.test.edge("top").x)).to.equal(-45);
expect(round(a.paths.test.edge("top").y)).to.equal(-60);
expect(round(a.paths.test.edge("left").x)).to.equal(-45);
expect(round(a.paths.test.edge("left").y)).to.equal(-60);
expect(round(a.paths.test.edge("bottom").x)).to.equal(45);
expect(round(a.paths.test.edge("bottom").y)).to.equal(60);
expect(round(a.paths.test.edge("right").x)).to.equal(45);
expect(round(a.paths.test.edge("right").y)).to.equal(60);
});
function round(value) {
return Math.round(value * 1e2) / 1e2;
}