diff --git a/draw.js b/draw.js index a9286ab..20bdb70 100644 --- a/draw.js +++ b/draw.js @@ -206,10 +206,27 @@ class Drawing { } arrow(p1, p2) { + const headLength = 10; + const headWidth = 10; this.sequence.push(() => { + const start = new Vector(this.getPoint(p1)); + const end = new Vector(this.getPoint(p2)); + const r = end.sub(start); + const b = end.sub(r.mult(headLength / r.length)); + const c1 = b.add(r.rot90().mult(0.5 * headWidth / r.length)); + const c2 = b.sub(r.rot90().mult(0.5 * headWidth / r.length)); + + // Arrow shaft this.ctx.beginPath(); - this.ctx.moveTo(...this.pixel(this.getPoint(p1))); - this.ctx.lineTo(...this.pixel(this.getPoint(p2))); + this.ctx.moveTo(...this.pixel(start.array)); + this.ctx.lineTo(...this.pixel(end.array)); + this.ctx.stroke(); + + // Arrow head + this.ctx.beginPath(); + this.ctx.moveTo(...this.pixel(c1.array)); + this.ctx.lineTo(...this.pixel(end.array)); + this.ctx.lineTo(...this.pixel(c2.array)); this.ctx.stroke(); }); } diff --git a/reveal.html b/reveal.html index 58e1a59..de56d14 100644 --- a/reveal.html +++ b/reveal.html @@ -17,7 +17,10 @@ + + +
diff --git a/test.md b/test.md index fc133e8..f99ec99 100644 --- a/test.md +++ b/test.md @@ -76,27 +76,58 @@ start ```drawing title Projectile -caption `y = v_(0y) * t - g * t^2`
`x = v_(0x) * t` +caption `x = v_(0x) t`
`y = v_(0y) t - g t^2` scale 2 -frame 0 0 300 100 +frame 0 -50 300 100 stroke black 4 eval _.polyline([0, 100], [0, 0], [300, 0]); -value v0 75 +value v0 50 value angle Math.PI / 4 value v0x _.getValue('v0') * Math.cos(_.getValue('angle')) value v0y _.getValue('v0') * Math.sin(_.getValue('angle')) point p1 (function() { const t = _.t / 1000; - const x = _.getValue('v0x') * t; - const y = _.getValue('v0y') * t - 9.81 * t**2; + 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; + return [0, 0]; } return [x, y]; })() -stroke green 1 -eval _.line([0, 0], [_.getValue('v0x'), _.getValue('v0y')]) +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 green 2 +eval _.arrow([0, 0], [_.getValue('v0x'), _.getValue('v0y')]) +stroke orange 2 +eval _.arrow('p1', 'p2'); fill blue eval const projectile = d.circle('p1', {trace: {age: -1}}); d.onStart(() => { diff --git a/vector.js b/vector.js new file mode 100644 index 0000000..d895f97 --- /dev/null +++ b/vector.js @@ -0,0 +1,48 @@ +class Vector { + constructor([x, y]) { + this.x = x; + this.y = y; + } + + get length() { + return Math.sqrt(this.x**2 + this.y**2); + } + + mult(s) { + return new Vector([ + this.x * s, + this.y * s, + ]); + } + + add(v) { + if (!(v instanceof Vector)) { + v = new Vector(v); + } + return new Vector([ + this.x + v.x, + this.y + v.y, + ]); + } + + sub(v) { + if (!(v instanceof Vector)) { + v = new Vector(v); + } + return new Vector([ + this.x - v.x, + this.y - v.y, + ]); + } + + rot90() { + return new Vector([ + -this.y, + this.x + ]); + } + + get array() { + return [this.x, this.y]; + } +} \ No newline at end of file