1
0
Fork 0

Add documentation and rename method

This commit is contained in:
Jonathan Haas 2024-04-18 10:52:52 +02:00
parent 789ff3f8ca
commit ed608b52a0
No known key found for this signature in database
GPG key ID: 0E7873037C5924E8
4 changed files with 144 additions and 8 deletions

View file

@ -0,0 +1,54 @@
---
title: Path.angleAt()
---
The `Path.angleAt()` method returns the (tangent) angle of a path at a specific point.
If the given point is a sharp corner, this method prefers returning the angle directly before the corner.
If the given point does not lie (approximately) on the path, this method returns `false`.
## Signature
```js
number|false path.angleAt(Point point)
```
## Example
<Example caption="Example of the Path.angleAt() method">
```js
({ Point, points, Path, paths, snippets, Snippet, part }) => {
points.A = new Point(45, 60)
points.B = new Point(10, 30)
points.BCp2 = new Point(40, 20)
points.C = new Point(90, 30)
points.CCp1 = new Point(50, -30)
points.D = new Point(50, 80)
points.DCp1 = new Point(70, 30)
paths.demo = new Path()
.move(points.D)
.curve(points.DCp1, points.DCp1, points.C)
.curve(points.CCp1, points.BCp2, points.B)
.line(points.A)
points.testPoint = paths.demo.shiftFractionAlong(0.55)
snippets.point = new Snippet("notch", points.testPoint)
let angle = paths.demo.angleAt(points.testPoint)
//draw a tangent path
paths.tangent = new Path()
.move(points.testPoint.shift(angle, -30))
.line(points.testPoint.shift(angle, 30))
.attr("class", "lining dashed")
return part
}
```
</Example>
## Notes
Keep in mind that calculations with Bézier curves are often approximations.

View file

@ -0,0 +1,77 @@
---
title: utils.curveParameterFromPoint()
---
The `utils.curveParameterFromPoint()` function calculates where the point `check` lies on a
curve described by points `start`, `cp1`, `cp2`, and `end`.
For example a return value of 0 indicates that the given point is the start of the curve, a return value
of 1 indicated that the given point is identical to the end of the curve.
A return value of 0.5 indicates that the start point and the first control point had the same influence
as the end point and the second control point, to create the checked point, but this doesn't necessarily mean
that the point lies exactly half-way on the curve.
This method returns `false` if the point isn't (approximately) located on the curve.
## Signature
```js
number|false utils.curveParameterFromPoint(
Point start,
Point cp1,
Point cp2,
Point end,
Point check
)
```
## Example
<Example caption="A Utils.curveParameterFromPoint() example">
```js
({ Point, points, Path, paths, Snippet, snippets, getId, utils, part }) => {
points.start = new Point(10, 10)
points.cp1 = new Point(90, 30)
points.cp2 = new Point(10, 40)
points.end = new Point(90, 60)
const scatter = []
for (let i = 1; i < 19; i++) {
for (let j = 1; j < 14; j++) {
scatter.push(new Point(i * 10, j * 10))
}
}
let snippet
for (let point of scatter) {
let t = utils.curveParameterFromPoint(
points.start,
points.cp1,
points.cp2,
points.end,
point
)
if(t !== false) {
points[getId()] = point.addText(` ${Math.round(t * 100) / 100}`, 'text-sm')
snippets[getId()] = new Snippet('notch', point)
}
}
paths.curve = new Path()
.move(points.start)
.curve(points.cp1, points.cp2, points.end)
.addClass("fabric stroke-lg")
return part
}
```
</Example>
## Notes
Keep in mind that calculations with Bézier curves are often approximations.
This method is mostly used as internal building block for methods like
`utils.pointOnCurve()`, `Path.split()` or `Path.angleAt()` and probably is not very relevant
for direct usage from pattern code.

View file

@ -6,8 +6,7 @@ import {
lineIntersectsCurve,
curvesIntersect,
pointOnLine,
pointOnCurve,
relativeOffsetOnCurve,
curveParameterFromPoint,
curveEdge,
round,
__addNonEnumProp,
@ -903,7 +902,7 @@ Path.prototype.split = function (point) {
break
}
} else if (path.ops[1].type === 'curve') {
let t = relativeOffsetOnCurve(
let t = curveParameterFromPoint(
path.ops[0].to,
path.ops[1].cp1,
path.ops[1].cp2,
@ -973,7 +972,7 @@ Path.prototype.angleAt = function (point) {
return path.ops[0].to.angle(path.ops[1].to)
}
} else if (path.ops[1].type === 'curve') {
let t = relativeOffsetOnCurve(
let t = curveParameterFromPoint(
path.ops[0].to,
path.ops[1].cp1,
path.ops[1].cp2,
@ -1065,7 +1064,7 @@ Path.prototype.trim = function () {
{ x: ops[1].cp2.x, y: ops[1].cp2.y },
{ x: ops[1].to.x, y: ops[1].to.y }
)
let t = relativeOffsetOnCurve(
let t = curveParameterFromPoint(
ops[0].to,
ops[1].cp1,
ops[1].cp2,

View file

@ -549,11 +549,17 @@ export function pointOnBeam(from, to, check, precision = 1e6) {
* @return {boolean} result - True of the Point is on the curve, false when not
*/
export function pointOnCurve(start, cp1, cp2, end, check) {
return relativeOffsetOnCurve(start, cp1, cp2, end, check) !== false
return curveParameterFromPoint(start, cp1, cp2, end, check) !== false
}
/**
* Finds where a Point lies on a (cubic) Bezier curve
* Finds where a Point lies on a (cubic) Bezier curve and returns the curve parameter t of this position.
* For example a return value of 0 indicates that the given point is the start of the curve, a return value
* of 1 indicated that the given point is identical to the end of the curve.
*
* A return value of 0.5 indicates that the start point and the first control point had the same influence
* as the end point and the second control point, to create the point, but this doesn't necessarily mean
* that the point lies exactly half-way on the curve.
*
* @param {Point} start - Start of the curve
* @param {Point} cp1 - Control point at the start of the curve
@ -562,7 +568,7 @@ export function pointOnCurve(start, cp1, cp2, end, check) {
* @param {Point} check - Point to check
* @return {false|number} result - relative position on the curve (value between 0 and 1), false when not on curve
*/
export function relativeOffsetOnCurve(start, cp1, cp2, end, check) {
export function curveParameterFromPoint(start, cp1, cp2, end, check) {
if (start.sitsOn(check)) return 0
if (end.sitsOn(check)) return 1
let curve = new Bezier(