From 68c0fca1249fe9108aec54c7d1c1eacd73a15fde Mon Sep 17 00:00:00 2001 From: Wouter van Wageningen Date: Fri, 28 Apr 2023 16:42:35 +0000 Subject: [PATCH 1/4] Code and tests --- packages/core/src/index.mjs | 2 ++ packages/core/src/utils.mjs | 19 +++++++++++++++ packages/core/tests/utils.test.mjs | 37 ++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/packages/core/src/index.mjs b/packages/core/src/index.mjs index 38657c84c0d..fe75b9f5ad1 100644 --- a/packages/core/src/index.mjs +++ b/packages/core/src/index.mjs @@ -13,6 +13,7 @@ import { beamIntersectsX, beamIntersectsY, beamsIntersect, + beamIntersectsCurve, capitalize, circlesIntersect, curveEdge, @@ -55,6 +56,7 @@ export { beamIntersectsX, beamIntersectsY, beamsIntersect, + beamIntersectsCurve, capitalize, circlesIntersect, curveEdge, diff --git a/packages/core/src/utils.mjs b/packages/core/src/utils.mjs index aea6af3d686..11b49f8b5f8 100644 --- a/packages/core/src/utils.mjs +++ b/packages/core/src/utils.mjs @@ -111,6 +111,25 @@ export function beamsIntersect(a1, a2, b1, b2) { } } +/** + * Find the intersections between an endless line (beam) and a curve + * + * + * @param {Point} start - Start Point of the line + * @param {Point} end - End Point of the line + * @param {Point} from - Start Point of the curve + * @param {Point} cp1 - Control Point at the start of the curve + * @param {Point} cp2 - Control Point at the end of the curve + * @param {Point} to - End Point of the curve + * @return {Array} intersections - An array of Points at the intersections + */ +export function beamIntersectsCurve(start, end, from, cp1, cp2, to) { + let _start = new Point(start.x + (start.x - end.x) * 1000, start.y + (start.y - end.y) * 1000) + let _end = new Point(end.x + (end.x - start.x) * 1000, end.y + (end.y - start.y) * 1000) + console.log({ _start: _start, _end: _end }) + return lineIntersectsCurve(_start, _end, from, cp1, cp2, to) +} + /** * Returns the string you pass with with the first character converted to uppercase * diff --git a/packages/core/tests/utils.test.mjs b/packages/core/tests/utils.test.mjs index bd0817f0ee6..cc5b88a78b7 100644 --- a/packages/core/tests/utils.test.mjs +++ b/packages/core/tests/utils.test.mjs @@ -11,6 +11,7 @@ import { splitCurve, beamIntersectsX, beamIntersectsY, + beamIntersectsCurve, units, lineIntersectsCurve, curveIntersectsX, @@ -70,6 +71,42 @@ describe('Utils', () => { expect(round(X.x)).to.equal(7.14) expect(round(X.y)).to.equal(40) }) + it('Should find no intersections between a curve and a beam', () => { + let A = new Point(10, 10) + let Acp = new Point(10, 30) + let B = new Point(110, 10) + let Bcp = new Point(110, 30) + let E = new Point(10, 40) + let D = new Point(20, 40) + + let hit = beamIntersectsCurve(E, D, A, Acp, Bcp, B) + expect(hit).to.equal(false) + }) + + it('Should find one intersections between a curve and a beam', () => { + let A = new Point(10, 10) + let Acp = new Point(10, 30) + let B = new Point(110, 10) + let Bcp = new Point(110, 30) + let E = new Point(50, 14) + let D = new Point(55, 16) + + let hit = beamIntersectsCurve(E, D, A, Acp, Bcp, B) + expect(round(hit.x)).to.equal(75.79) + expect(round(hit.y)).to.equal(24.31) + }) + + it('Should find two intersections between a curve and a beam', () => { + let A = new Point(10, 10) + let Acp = new Point(10, 30) + let B = new Point(110, 10) + let Bcp = new Point(110, 30) + let E = new Point(0, 14) + let D = new Point(5, 15) + + let hits = beamIntersectsCurve(E, D, A, Acp, Bcp, B) + expect(hits.length).to.equal(2) + }) it("Should return false when two lines don't intersect", () => { let a = new Point(10, 20) From 486fde8b67e0fc30a703cd2cc632d8149935463a Mon Sep 17 00:00:00 2001 From: Wouter van Wageningen Date: Fri, 28 Apr 2023 17:49:19 +0000 Subject: [PATCH 2/4] Documentation --- designs/examples/config/index.js | 1 + designs/examples/src/utils.mjs | 32 ++++++++++ markdown/dev/reference/api/en.md | 1 + .../api/utils/beamintersectscurve/en.md | 62 +++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 markdown/dev/reference/api/utils/beamintersectscurve/en.md diff --git a/designs/examples/config/index.js b/designs/examples/config/index.js index c7219e59e22..fa985ed1100 100644 --- a/designs/examples/config/index.js +++ b/designs/examples/config/index.js @@ -96,6 +96,7 @@ export default { 'utils_beamsintersect', 'utils_beamintersectsx', 'utils_beamintersectsy', + 'utils_beamintersectscurve', 'utils_lineintersectscurve', 'utils_curvesintersect', 'utils_pointonbeam', diff --git a/designs/examples/src/utils.mjs b/designs/examples/src/utils.mjs index 201fa7d40f0..3126b453eba 100644 --- a/designs/examples/src/utils.mjs +++ b/designs/examples/src/utils.mjs @@ -84,6 +84,38 @@ export const utils_beamintersectsy = { }, } +export const utils_beamintersectscurve = { + name: 'examples.utils_beamintersectscurve', + draft: ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { + points.A = new Point(10, 10) + points.Acp = new Point(10, 40) + points.B = new Point(110, 70) + points.Bcp = new Point(110, 40) + points.E = new Point(50, 14) + points.D = new Point(55, 16) + paths.curve = new Path().move(points.A).curve(points.Acp, points.Bcp, points.B) + paths.line = new Path().move(points.E).line(points.D) + + for (let p of utils.beamIntersectsCurve( + points.D, + points.E, + points.A, + points.Acp, + points.Bcp, + points.B + )) { + snippets[getId()] = new Snippet('notch', p) + } + + paths.help = new Path() + .move(new Point(0, 30)) + .line(new Point(50, 30)) + .attr('class', 'note dashed') + + return part + }, +} + export const utils_beamsintersect = { name: 'examples.utils_beamsintersect', draft: ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { diff --git a/markdown/dev/reference/api/en.md b/markdown/dev/reference/api/en.md index 27eb0559bda..22e71c3ee43 100644 --- a/markdown/dev/reference/api/en.md +++ b/markdown/dev/reference/api/en.md @@ -60,6 +60,7 @@ The following named exports are **utility methods**: | Named export | Description | | ------------ | ------------| | `beamIntersectsCircle` | See the [beamIntersectsCircle](/reference/api/utils/beamintersectscircle) documentation | +| `beamIntersectsCurve` | See the [beamIntersectsCurve](/reference/api/utils/beamintersectscurve) documentation | | `beamIntersectsX` | See the [beamIntersectsX](/reference/api/utils/beamintersectsx) documentation | | `beamIntersectsY` | See the [beamIntersectsY](/reference/api/utils//beamintersectsy) documentation | | `beamsIntersect` | See the [beamsIntersect](/reference/api/utils/beamsintersect) documentation | diff --git a/markdown/dev/reference/api/utils/beamintersectscurve/en.md b/markdown/dev/reference/api/utils/beamintersectscurve/en.md new file mode 100644 index 00000000000..8b4b66459e8 --- /dev/null +++ b/markdown/dev/reference/api/utils/beamintersectscurve/en.md @@ -0,0 +1,62 @@ +--- +title: utils.beamIntersectsCurve() +--- + +The `utils.beamIntersectsCurve()` function finds the intersection between an endless +line and a curve described by points +`start`, `cp1`, `cp2, and `end\`. + + + +This function can sometimes fail to find intersections in some curves +due to a limitation in an underlying Bézier library. +Please see [Bug #3367](https://github.com/freesewing/freesewing/issues/3367) +for more information. + + + +## Signature + +```js +array | false utils.beamIntersectsCurve( + Point from, + Point to, + Point start, + Point cp1, + Point cp2, + Point end +) +``` + +## Example + + +```js +({ Point, points, Path, paths, Snippet, snippets, getId, utils, part }) => { + + points.A = new Point(10, 10) + points.Acp = new Point(10, 40) + points.B = new Point(110, 70) + points.Bcp = new Point(110, 40) + points.E = new Point(50, 14) + points.D = new Point(55, 16) + paths.curve = new Path() + .move(points.A) + .curve(points.Acp, points.Bcp, points.B) + paths.line = new Path().move(points.E).line(points.D) + + for (let p of utils.beamIntersectsCurve( + points.D, + points.E, + points.A, + points.Acp, + points.Bcp, + points.B + )) { + snippets[getId()] = new Snippet("notch", p) + } + + return part +} +``` + From a5f141a586fe20cffb776f29494cb82e6599ce64 Mon Sep 17 00:00:00 2001 From: Wouter van Wageningen Date: Fri, 28 Apr 2023 18:26:55 +0000 Subject: [PATCH 3/4] Docs and code cleanup --- designs/examples/src/utils.mjs | 6 +++--- .../dev/reference/api/utils/beamintersectscurve/en.md | 8 ++++---- packages/core/src/utils.mjs | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/designs/examples/src/utils.mjs b/designs/examples/src/utils.mjs index 3126b453eba..ccc1eb42b6b 100644 --- a/designs/examples/src/utils.mjs +++ b/designs/examples/src/utils.mjs @@ -89,10 +89,10 @@ export const utils_beamintersectscurve = { draft: ({ Point, points, Path, paths, Snippet, snippets, utils, part }) => { points.A = new Point(10, 10) points.Acp = new Point(10, 40) - points.B = new Point(110, 70) + points.B = new Point(110, 10) points.Bcp = new Point(110, 40) - points.E = new Point(50, 14) - points.D = new Point(55, 16) + points.E = new Point(45, 25) + points.D = new Point(65, 25) paths.curve = new Path().move(points.A).curve(points.Acp, points.Bcp, points.B) paths.line = new Path().move(points.E).line(points.D) diff --git a/markdown/dev/reference/api/utils/beamintersectscurve/en.md b/markdown/dev/reference/api/utils/beamintersectscurve/en.md index 8b4b66459e8..16d4d102319 100644 --- a/markdown/dev/reference/api/utils/beamintersectscurve/en.md +++ b/markdown/dev/reference/api/utils/beamintersectscurve/en.md @@ -36,15 +36,15 @@ array | false utils.beamIntersectsCurve( points.A = new Point(10, 10) points.Acp = new Point(10, 40) - points.B = new Point(110, 70) + points.B = new Point(110, 10) points.Bcp = new Point(110, 40) - points.E = new Point(50, 14) - points.D = new Point(55, 16) + points.E = new Point(45, 25) + points.D = new Point(65, 25) paths.curve = new Path() .move(points.A) .curve(points.Acp, points.Bcp, points.B) paths.line = new Path().move(points.E).line(points.D) - + for (let p of utils.beamIntersectsCurve( points.D, points.E, diff --git a/packages/core/src/utils.mjs b/packages/core/src/utils.mjs index 11b49f8b5f8..c3bdf013599 100644 --- a/packages/core/src/utils.mjs +++ b/packages/core/src/utils.mjs @@ -126,7 +126,6 @@ export function beamsIntersect(a1, a2, b1, b2) { export function beamIntersectsCurve(start, end, from, cp1, cp2, to) { let _start = new Point(start.x + (start.x - end.x) * 1000, start.y + (start.y - end.y) * 1000) let _end = new Point(end.x + (end.x - start.x) * 1000, end.y + (end.y - start.y) * 1000) - console.log({ _start: _start, _end: _end }) return lineIntersectsCurve(_start, _end, from, cp1, cp2, to) } From 860116f22a64288ea8140bcd365ca7247de65551 Mon Sep 17 00:00:00 2001 From: Wouter van Wageningen Date: Fri, 28 Apr 2023 18:35:01 +0000 Subject: [PATCH 4/4] lint... --- designs/examples/src/utils.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designs/examples/src/utils.mjs b/designs/examples/src/utils.mjs index ccc1eb42b6b..e75dd50834f 100644 --- a/designs/examples/src/utils.mjs +++ b/designs/examples/src/utils.mjs @@ -104,7 +104,7 @@ export const utils_beamintersectscurve = { points.Bcp, points.B )) { - snippets[getId()] = new Snippet('notch', p) + snippets[part.getId()] = new Snippet('notch', p) } paths.help = new Path()