From 6552616a5eacf8e374cf433012239b0c48f47eeb Mon Sep 17 00:00:00 2001 From: Bryan Parker Date: Tue, 2 Jul 2024 19:53:40 -0500 Subject: [PATCH] Allows you to maintain length of line when changing endpoints --- src/shapes/primitives/line.ts | 6 ++- test/script_test.ts | 79 ++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/src/shapes/primitives/line.ts b/src/shapes/primitives/line.ts index cccfcef..25ce78d 100644 --- a/src/shapes/primitives/line.ts +++ b/src/shapes/primitives/line.ts @@ -18,6 +18,7 @@ const defaultLineArgs = { class Line extends PointShape { private _lineCap: LineCap; + private _initialLength: number | undefined; constructor(); constructor(from: Locatable, to: Locatable); @@ -57,6 +58,7 @@ class Line extends PointShape { super({ points: Line.fromPoints(_from, _to, length), ...styles }); this._lineCap = lineCap; + this._initialLength = length; } changeColor(color: RGBA): this { @@ -78,8 +80,8 @@ class Line extends PointShape { return this.points()[0][3]!; } - changeEndpoints(from: Locatable, to: Locatable): this { - const length = math.dist(locatableToPoint(from), locatableToPoint(to)); + changeEndpoints(from: Locatable, to: Locatable, maintainLength: boolean = false): this { + const length = maintainLength ? this._initialLength : math.dist(locatableToPoint(from), locatableToPoint(to)); this.changePoints(Line.fromPoints(from, to, length)); return this; diff --git a/test/script_test.ts b/test/script_test.ts index 0429f8c..8ccb95c 100644 --- a/test/script_test.ts +++ b/test/script_test.ts @@ -397,39 +397,80 @@ class TestScene extends Scene { // new Group(a4, p4, ...pointsAndLine(a4, 1, 1.25)).shift(RIGHT(3), DOWN(2)), // ); + // const axes = new Axes({ + // xLength: 10, + // ylength: 6, + // xrange: [0, 1], + // xstep: 0.25, + // yrange: [0, 50], + // ystep: 5, + // xlabel: 'time (h)', + // ylabel: 'distance (miles)' + // }); + + // const p = axes.plot(x => 25 * x * x).changelinecolor(colors.green()); + + // const d1 = new dot({ center: p.pointatx(0.0), color: colors.red() }); + // const d2 = new dot({ center: p.pointatx(0.5), color: colors.red() }); + // const d3 = new dot({ center: p.pointatx(0.5), color: colors.green() }); + // const l = new line(d1, d2).changelinecolor(colors.red()); + + // this.add( + // axes, p, + // d3, + // d1, + // d2, + // l, + // ); + + // this.add(new updater((pctcomplete: number, starting: boolean) => { + // const x1 = math.lerp(0, 0.5, pctcomplete); + // const x2 = math.lerp(0.5, 1, pctcomplete); + + // d1.moveto(p.pointatx(x1)); + // d2.moveto(p.pointatx(x2)); + // l.changeendpoints(d1, d2); + // }, { duration: 3000, easing: easing.linear, repeat: true, yoyo: true, })); + const axes = new Axes({ - xLength: 10, + xLength: 8, yLength: 6, xRange: [0, 1], xStep: 0.25, - yRange: [0, 50], + yRange: [0, 35], yStep: 5, + showLabels: false, + showTicks: false, xLabel: 'time (h)', yLabel: 'distance (miles)' }); - const p = axes.plot(x => 25 * x * x).changeLineColor(Colors.green()); + const fn = x => Math.pow(Math.E, 12 * x * x - 2.5); + const plot = axes.plot(fn).changeLineColor(Colors.green()); + + const p = axes.point([0.5, fn(0.5)]); + const q = axes.point([0.69, fn(0.69)]); + + const pText = new Text({ text: 'P' }).nextTo(p, [-1, 1]); + const qText = new Text({ text: 'Q' }).nextTo(q, LEFT(1.5)); + const qDot = new Dot({ center: q, color: Colors.blue() }); + const secant = new Line({ from: p, to: q, length: 6, lineColor: Colors.blue() }); + + this.add( + axes, plot, - const d1 = new Dot({ center: p.pointAtX(0.0), color: Colors.red() }); - const d2 = new Dot({ center: p.pointAtX(0.5), color: Colors.red() }); - const d3 = new Dot({ center: p.pointAtX(0.5), color: Colors.green() }); - const l = new Line(d1, d2).changeLineColor(Colors.red()); + secant, + new TangentLine({ plot, x: 0.5, length: 4, color: Colors.pink() }), + new Dot({ center: p, color: Colors.pink() }), - this.add( - axes, p, - d3, - d1, - d2, - l, + qDot, + pText, qText ); this.add(new Updater((pctComplete: number, starting: boolean) => { - const x1 = math.lerp(0, 0.5, pctComplete); - const x2 = math.lerp(0.5, 1, pctComplete); - - d1.moveTo(p.pointAtX(x1)); - d2.moveTo(p.pointAtX(x2)); - l.changeEndpoints(d1, d2); + const x = math.lerp(0.5, 0.69, 1 - pctComplete); + qDot.moveTo(plot.pointAtX(x)); + secant.changeEndpoints(p, qDot, true); }, { duration: 3000, easing: Easing.linear, repeat: true, yoyo: true, })); } }