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