From 25d45113825379991867ff15d30fab098cbac4c3 Mon Sep 17 00:00:00 2001 From: Ladd Hoffman Date: Mon, 24 Jun 2024 16:45:27 -0500 Subject: [PATCH] projectile tweaks --- draw.js | 10 ++++ test.md | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 176 insertions(+), 6 deletions(-) diff --git a/draw.js b/draw.js index 20bdb70..c8105ea 100644 --- a/draw.js +++ b/draw.js @@ -324,6 +324,16 @@ class Drawing { this.ctx.stroke(); }) } + + text(p, text, opts) { + this.sequence.push(() => { + const [x, y] = this.pixel(this.getPoint(p)); + this.ctx.font = "12pt sans-serif"; + this.ctx.textAlign = opts?.align ?? 'left'; + this.ctx.textBaseline = opts?.baseline ?? 'bottom'; + this.ctx.fillText(text, x, y); + }); + } static fromText(node) { const div = document.createElement('div'); diff --git a/test.md b/test.md index f99ec99..345f6c1 100644 --- a/test.md +++ b/test.md @@ -70,21 +70,44 @@ func Math.sin(x + 2*Math.PI*_.t / 1000) start ``` + --- -## Slide 5 +## Slide 4 ```drawing +title Sine * Cosine +caption `y = sin(x) * cos(x)` +scale 64 +frame 0 -1 2*Math.PI 1 +stroke black 4 +eval _.line([0, -1], [0, 1]) +eval _.line([0, 0], [2*Math.PI, 0]) +stroke red 1 +func Math.sin(x) +stroke blue 1 +func Math.cos(x) +stroke purple 2 +func Math.sin(x) * Math.cos(x) +start +``` + +--- + +```drawing +scale 2 title Projectile caption `x = v_(0x) t`
`y = v_(0y) t - g t^2` -scale 2 -frame 0 -50 300 100 +frame -10 -50 300 80 stroke black 4 eval _.polyline([0, 100], [0, 0], [300, 0]); value v0 50 -value angle Math.PI / 4 +value angle Math.PI / 180 * 45; +fill green +eval _.text([10, 0], '45°') value v0x _.getValue('v0') * Math.cos(_.getValue('angle')) value v0y _.getValue('v0') * Math.sin(_.getValue('angle')) +eval _.text([_.getValue('v0x') / 2, _.getValue('v0y') / 2], `${_.getValue('v0')} m/s`, {align: 'right'}); point p1 (function() { const t = _.t / 1000; const v0x = _.getValue('v0x'); @@ -107,6 +130,7 @@ point p1 (function() { _.arrow([x, y], [x + v0x, y + vy]); _.stop(); _.t = 0; + _.text([x, y + 10], `x = ${Math.ceil(x)} m`); return [0, 0]; } return [x, y]; @@ -124,10 +148,146 @@ point p2 (function() { const p2 = r.add(v); return p2.array; })() -stroke green 2 -eval _.arrow([0, 0], [_.getValue('v0x'), _.getValue('v0y')]) stroke orange 2 eval _.arrow('p1', 'p2'); +stroke green 2 +eval _.arrow([0, 0], [_.getValue('v0x'), _.getValue('v0y')]) +fill blue +eval const projectile = d.circle('p1', {trace: {age: -1}}); + d.onStart(() => { + if (d.t == 0) { + projectile.reset(); + } + }) +start +``` + +--- + +### 45° ± 15° + +```drawing +scale 2 +frame -10 -50 300 80 +stroke black 4 +eval _.polyline([0, 100], [0, 0], [300, 0]); +value v0 50 +value angle Math.PI / 180 * 30; +fill green +eval _.text([20, 0], '30°') +value v0x _.getValue('v0') * Math.cos(_.getValue('angle')) +value v0y _.getValue('v0') * Math.sin(_.getValue('angle')) +eval _.text([_.getValue('v0x') / 2, _.getValue('v0y') / 2], `${_.getValue('v0')} m/s`, {align: 'right'}); +point p1 (function() { + const t = _.t / 1000; + const v0x = _.getValue('v0x'); + const v0y = _.getValue('v0y'); + const g = 9.81; + const x = v0x * t; + const y = v0y * t - g * t**2 / 2; + const vy = v0y - g * t; + const vyp = v0y - g * (t - _.dt/1000); + if (vy < 0 && vyp >= 0) { + _.setFill('red'); + _.circle([x, y]); + _.setStroke('green', 2); + _.arrow([x, y], [x + v0x, y + vy]); + } + if (t > 0 && (y <= 0 || x >= _.frame[1][0])) { + _.setFill('red'); + _.circle([x, y]); + _.setStroke('green', 2); + _.arrow([x, y], [x + v0x, y + vy]); + _.stop(); + _.t = 0; + _.text([x, y + 10], `x = ${Math.ceil(x)} m`); + return [0, 0]; + } + return [x, y]; + })() +point p2 (function() { + const t = _.t / 1000; + const v0x = _.getValue('v0x'); + const v0y = _.getValue('v0y'); + const g = 9.81; + const x = v0x * t; + const y = v0y * t - g * t**2 / 2; + const vy = v0y - g * t; + const v = new Vector([v0x, vy]); + const r = new Vector([x, y]); + const p2 = r.add(v); + return p2.array; + })() +stroke orange 2 +eval _.arrow('p1', 'p2'); +stroke green 2 +eval _.arrow([0, 0], [_.getValue('v0x'), _.getValue('v0y')]) +fill blue +eval const projectile = d.circle('p1', {trace: {age: -1}}); + d.onStart(() => { + if (d.t == 0) { + projectile.reset(); + } + }) +start +``` + +```drawing +scale 2 +frame -10 -50 300 100 +stroke black 4 +eval _.polyline([0, 100], [0, 0], [300, 0]); +value v0 50 +value angle Math.PI / 180 * 60; +fill green +eval _.text([10, 0], '60°') +value v0x _.getValue('v0') * Math.cos(_.getValue('angle')) +value v0y _.getValue('v0') * Math.sin(_.getValue('angle')) +eval _.text([_.getValue('v0x') / 2, _.getValue('v0y') / 2], `${_.getValue('v0')} m/s`, {align: 'right'}); +point p1 (function() { + const t = _.t / 1000; + const v0x = _.getValue('v0x'); + const v0y = _.getValue('v0y'); + const g = 9.81; + const x = v0x * t; + const y = v0y * t - g * t**2 / 2; + const vy = v0y - g * t; + const vyp = v0y - g * (t - _.dt/1000); + if (vy < 0 && vyp >= 0) { + _.setFill('red'); + _.circle([x, y]); + _.setStroke('green', 2); + _.arrow([x, y], [x + v0x, y + vy]); + } + if (t > 0 && (y <= 0 || x >= _.frame[1][0])) { + _.setFill('red'); + _.circle([x, y]); + _.setStroke('green', 2); + _.arrow([x, y], [x + v0x, y + vy]); + _.stop(); + _.t = 0; + _.text([x, y + 10], `x = ${Math.ceil(x)} m`); + return [0, 0]; + } + return [x, y]; + })() +point p2 (function() { + const t = _.t / 1000; + const v0x = _.getValue('v0x'); + const v0y = _.getValue('v0y'); + const g = 9.81; + const x = v0x * t; + const y = v0y * t - g * t**2 / 2; + const vy = v0y - g * t; + const v = new Vector([v0x, vy]); + const r = new Vector([x, y]); + const p2 = r.add(v); + return p2.array; + })() +stroke orange 2 +eval _.arrow('p1', 'p2'); +stroke green 2 +eval _.arrow([0, 0], [_.getValue('v0x'), _.getValue('v0y')]) fill blue eval const projectile = d.circle('p1', {trace: {age: -1}}); d.onStart(() => {