From 2d0f48bfc6eef2974447ab1a7cf1de744194d18a Mon Sep 17 00:00:00 2001 From: Joost De Cock Date: Mon, 3 Sep 2018 12:07:02 +0200 Subject: [PATCH] :sparkles: Switch to curve.edge for finding path edge --- src/path.js | 28 +++------------------------- src/utils.js | 22 ++++++++++++++++++++++ tests/path.test.js | 25 ++++++++++++++++++++----- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/path.js b/src/path.js index 4f05eb88253..a98d42fe423 100644 --- a/src/path.js +++ b/src/path.js @@ -7,6 +7,7 @@ import { curvesIntersect, pointOnLine, pointOnCurve, + curveEdge, round } from "./utils"; @@ -484,31 +485,8 @@ Path.prototype.edge = function(side) { else return this.rightOp.from; } } 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); + let curve = edgeCurveAsBezier(this[s]); + return curveEdge(curve, side); } } }; diff --git a/src/utils.js b/src/utils.js index 40730c392df..01478e50a9a 100644 --- a/src/utils.js +++ b/src/utils.js @@ -259,6 +259,28 @@ export function lineIntersectsCircle(c, r, p1, p2, sort = "x") { } } +export function curveEdge(curve, edge, steps = 500) { + let x = Infinity; + let y = Infinity; + let p; + if (edge === "bottom") y = -Infinity; + if (edge === "right") x = -Infinity; + for (let i = 0; i < steps; i++) { + p = curve.get(i / steps); + if ( + (edge === "top" && p.y < y) || + (edge === "bottom" && p.y > y) || + (edge === "right" && p.x > x) || + (edge === "left" && p.x < x) + ) { + x = p.x; + y = p.y; + } + } + + return new Point(x, y); +} + /** * Calculates scale factor based on stretch factor * diff --git a/tests/path.test.js b/tests/path.test.js index 4ccafd4373b..4b9c8b6665a 100644 --- a/tests/path.test.js +++ b/tests/path.test.js @@ -357,12 +357,12 @@ it("Should find the edges of a path", () => { 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("left").y)).to.equal(91.8); + expect(round(a.paths.test.edge("bottom").x)).to.equal(40.63); 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("right").x)).to.equal(89.76); + expect(round(a.paths.test.edge("right").y)).to.equal(29.64); + expect(round(a.paths.test.edge("top").x)).to.equal(55.98); expect(round(a.paths.test.edge("top").y)).to.equal(0.97); }); @@ -393,6 +393,21 @@ it("Should find the edges of a path for corner cases", () => { expect(round(a.paths.test.edge("right").y)).to.equal(60); }); +it("Should find the edge of a path for this edge-case", () => { + let pattern = new freesewing.Pattern(); + pattern.parts.a = new pattern.Part(); + let a = pattern.parts.a; + a.points.A = new a.Point(-109.7, 77, 12); + a.points.B = new a.Point(-27.33, 99.19); + a.points.C = new a.Point(-39.45, 137.4); + a.points.D = new a.Point(-61.52, 219.77); + a.paths.test = new a.Path() + .move(a.points.A) + .curve(a.points.B, a.points.C, a.points.D); + expect(round(a.paths.test.edge("right").x)).to.equal(-45.22); + expect(round(a.paths.test.edge("right").y)).to.equal(139.4); +}); + it("Should find where a path intersects with an X value", () => { let pattern = new freesewing.Pattern(); pattern.parts.a = new pattern.Part();