Add documentation and rename method
This commit is contained in:
parent
789ff3f8ca
commit
ed608b52a0
4 changed files with 144 additions and 8 deletions
54
markdown/dev/reference/api/path/angleat/en.md
Normal file
54
markdown/dev/reference/api/path/angleat/en.md
Normal 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.
|
|
@ -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.
|
|
@ -6,8 +6,7 @@ import {
|
||||||
lineIntersectsCurve,
|
lineIntersectsCurve,
|
||||||
curvesIntersect,
|
curvesIntersect,
|
||||||
pointOnLine,
|
pointOnLine,
|
||||||
pointOnCurve,
|
curveParameterFromPoint,
|
||||||
relativeOffsetOnCurve,
|
|
||||||
curveEdge,
|
curveEdge,
|
||||||
round,
|
round,
|
||||||
__addNonEnumProp,
|
__addNonEnumProp,
|
||||||
|
@ -903,7 +902,7 @@ Path.prototype.split = function (point) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else if (path.ops[1].type === 'curve') {
|
} else if (path.ops[1].type === 'curve') {
|
||||||
let t = relativeOffsetOnCurve(
|
let t = curveParameterFromPoint(
|
||||||
path.ops[0].to,
|
path.ops[0].to,
|
||||||
path.ops[1].cp1,
|
path.ops[1].cp1,
|
||||||
path.ops[1].cp2,
|
path.ops[1].cp2,
|
||||||
|
@ -973,7 +972,7 @@ Path.prototype.angleAt = function (point) {
|
||||||
return path.ops[0].to.angle(path.ops[1].to)
|
return path.ops[0].to.angle(path.ops[1].to)
|
||||||
}
|
}
|
||||||
} else if (path.ops[1].type === 'curve') {
|
} else if (path.ops[1].type === 'curve') {
|
||||||
let t = relativeOffsetOnCurve(
|
let t = curveParameterFromPoint(
|
||||||
path.ops[0].to,
|
path.ops[0].to,
|
||||||
path.ops[1].cp1,
|
path.ops[1].cp1,
|
||||||
path.ops[1].cp2,
|
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].cp2.x, y: ops[1].cp2.y },
|
||||||
{ x: ops[1].to.x, y: ops[1].to.y }
|
{ x: ops[1].to.x, y: ops[1].to.y }
|
||||||
)
|
)
|
||||||
let t = relativeOffsetOnCurve(
|
let t = curveParameterFromPoint(
|
||||||
ops[0].to,
|
ops[0].to,
|
||||||
ops[1].cp1,
|
ops[1].cp1,
|
||||||
ops[1].cp2,
|
ops[1].cp2,
|
||||||
|
|
|
@ -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
|
* @return {boolean} result - True of the Point is on the curve, false when not
|
||||||
*/
|
*/
|
||||||
export function pointOnCurve(start, cp1, cp2, end, check) {
|
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} start - Start of the curve
|
||||||
* @param {Point} cp1 - Control point at the 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
|
* @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
|
* @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 (start.sitsOn(check)) return 0
|
||||||
if (end.sitsOn(check)) return 1
|
if (end.sitsOn(check)) return 1
|
||||||
let curve = new Bezier(
|
let curve = new Bezier(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue