@freesewing/core
Advanced tools
+1
-1
| { | ||
| "id": "core", | ||
| "description": "A library for creating made-to-measure sewing patterns", | ||
| "version": "4.4.0" | ||
| "version": "4.4.1" | ||
| } |
+2
-2
| { | ||
| "name": "@freesewing/core", | ||
| "version": "4.4.0", | ||
| "version": "4.4.1", | ||
| "description": "A library for creating made-to-measure sewing patterns", | ||
@@ -45,3 +45,3 @@ "author": "Joost De Cock <joost@joost.at> (https://codeberg.org/joostdecock)", | ||
| "dependencies": { | ||
| "@freesewing/core-plugins": "4.4.0", | ||
| "@freesewing/core-plugins": "4.4.1", | ||
| "bezier-js": "6.1.4", | ||
@@ -48,0 +48,0 @@ "hooks": "0.3.2", |
+110
-0
@@ -17,2 +17,4 @@ import { Attributes } from './attributes.mjs' | ||
| beamIntersectsLine, | ||
| projectPointOntoLine, | ||
| projectPointOntoCurve, | ||
| } from './utils.mjs' | ||
@@ -393,2 +395,110 @@ | ||
| /** | ||
| * Finds and returns the point on this path that is closest to the given point. If multiple points have the same distance, | ||
| * which of these nearest points is chosen is not defined. | ||
| * | ||
| * Note: The line between the given point and the returned point will always be either perpendicular to this path | ||
| * or a corner or endpoint. | ||
| * | ||
| * @param {Point} p The point to project onto the path | ||
| * @return {Point} the closest point on the Path (will always exist assuming `this` is a valid, non-empty path) | ||
| */ | ||
| Path.prototype.projectPoint = function (p) { | ||
| if (!(p instanceof Point)) { | ||
| this.log.error('Called `Path.projectPoint(p)` but `p` is not a `Point` object') | ||
| return null | ||
| } | ||
| let closest = this.start() | ||
| let minDist = Infinity | ||
| let current = closest, | ||
| start = closest | ||
| for (let i in this.ops) { | ||
| let op = this.ops[i] | ||
| if (op.type === 'move') { | ||
| start = op.to | ||
| } else if (op.type === 'line') { | ||
| let proj = projectPointOntoLine(p, current, op.to) | ||
| let dist = proj.dist(p) | ||
| if (dist < minDist) { | ||
| minDist = dist | ||
| closest = proj | ||
| } | ||
| } else if (op.type === 'curve') { | ||
| let proj = projectPointOntoCurve(p, current, op.cp1, op.cp2, op.to) | ||
| let dist = proj.dist(p) | ||
| if (dist < minDist) { | ||
| minDist = dist | ||
| closest = proj | ||
| } | ||
| } else if (op.type === 'close') { | ||
| let proj = projectPointOntoLine(p, current, start) | ||
| let dist = proj.dist(p) | ||
| if (dist < minDist) { | ||
| minDist = dist | ||
| closest = proj | ||
| } | ||
| } | ||
| if (op.to) current = op.to | ||
| } | ||
| return closest | ||
| } | ||
| /** | ||
| * Returns the offset of the given point on this path, as if you measured along this path until | ||
| * you've reached the given point. | ||
| * | ||
| * Note: This method returns (approximately) the same value as `this.split(p)[0].length()` would. | ||
| * | ||
| * However, this method is likely faster and you need less handling of special cases. E.g., if the | ||
| * given point is identical to the start of this path, then this method would simply return `0`, | ||
| * whereas `this.split(p)[0]` would be `null`, requiring you to handle that edge case. | ||
| * | ||
| * This returns `null` if the given point doesn't lie on this path. | ||
| * | ||
| * @param {Point} p target point to measure until | ||
| * @return {number|null} length on the path until the target point, or null if the point is not on the path | ||
| */ | ||
| Path.prototype.measureAlong = function (p) { | ||
| if (!(p instanceof Point)) { | ||
| this.log.error('Called `Path.measureAlong(p)` but `p` is not a `Point` object') | ||
| return null | ||
| } | ||
| let offset = 0 | ||
| let current = this.start() | ||
| let start = current | ||
| for (let i in this.ops) { | ||
| let op = this.ops[i] | ||
| if (op.type === 'move') { | ||
| start = op.to | ||
| } else if (op.type === 'line') { | ||
| if (pointOnLine(current, op.to, p)) { | ||
| offset += current.dist(p) | ||
| return offset | ||
| } | ||
| offset += current.dist(op.to) | ||
| } 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 } | ||
| ) | ||
| const result = bezier.project({ x: p.x, y: p.y }) | ||
| if (result.d < 1) { | ||
| offset += bezier.split(result.t).left.length() | ||
| return offset | ||
| } | ||
| offset += bezier.length() | ||
| } else if (op.type === 'close') { | ||
| if (pointOnLine(current, start, p)) { | ||
| offset += current.dist(p) | ||
| return offset | ||
| } | ||
| offset += current.dist(start) | ||
| } | ||
| if (op.to) current = op.to | ||
| } | ||
| return null | ||
| } | ||
| /** | ||
| * Returns the point at an edge of this Path | ||
@@ -395,0 +505,0 @@ * |
+43
-0
@@ -1070,1 +1070,44 @@ import { Bezier } from './bezier.mjs' | ||
| } | ||
| /** | ||
| * Finds the closest point to p on the line between from and to | ||
| * @param {Point} p test point | ||
| * @param {Point} from start point of the line | ||
| * @param {Point} to end point of the line | ||
| * @return {Point} closest point on the line compared to `p`, will always exist | ||
| */ | ||
| export function projectPointOntoLine(p, from, to) { | ||
| // Vector from l1 to l2 | ||
| const dx = to.x - from.x | ||
| const dy = to.y - from.y | ||
| const lenSq = dx * dx + dy * dy | ||
| if (lenSq === 0) return from.copy() // l1 and l2 are the same point | ||
| // Vector from l1 to p | ||
| const t = ((p.x - from.x) * dx + (p.y - from.y) * dy) / lenSq | ||
| // Clamp t to [0, 1] to stay between the endpoints of the line | ||
| const tClamped = Math.max(0, Math.min(1, t)) | ||
| return new Point(from.x + tClamped * dx, from.y + tClamped * dy) | ||
| } | ||
| /** | ||
| * Finds the closest point to `p` on the Bézier curve given by `from`, `to` and both control points | ||
| * @param {Point} p test point | ||
| * @param {Point} from start point of the Bézier curve | ||
| * @param {Point} cp1 first control point of the Bézier curve | ||
| * @param {Point} cp2 second control point of the Bézier curve | ||
| * @param {Point} to end point of the Bézier curve | ||
| * @return {Point} closest point on the curve compared to `p`, will always exist | ||
| */ | ||
| export function projectPointOntoCurve(p, from, cp1, cp2, to) { | ||
| let curve = 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 } | ||
| ) | ||
| const result = curve.project({ x: p.x, y: p.y }) | ||
| return new Point(result.x, result.y) | ||
| } |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
228235
2.3%6548
2.28%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed