///|
using @lib {type Tuple}
///|
let canvas = @lib.canvas
///|
let color = @lib.color
///|
let point = @lib.point
///|
let vector = @lib.vector
///|
struct Projectile {
position : Tuple
velocity : Tuple
}
///|
fn projectile(position : Tuple, velocity : Tuple) -> Projectile {
{ position, velocity }
}
///|
struct Environment {
gravity : Tuple
wind : Tuple
}
///|
fn environment(gravity : Tuple, wind : Tuple) -> Environment {
{ gravity, wind }
}
///|
async fn main {
// projectile starts one unit above the origin.
// velocity is normalized to 1 unit/tick.
let mut p = projectile(
point(0, 1, 0),
vector(1, 1.8, 0).normalize().mul_scalar(11.25),
)
// gravity is 0.1 unit/tick, and wind is -0.01 unit/tick.
let e = environment(vector(0, -0.1, 0), vector(-0.01, 0, 0))
let mut t = 0
//
let max_height = 550
let c = canvas(900, max_height + 1)
let red = color(1, 0, 0)
println("t=\{t}: pos=(\{p.position.x},\{p.position.y},\{p.position.z})")
while p.position.y > 0 {
let x = @math.round(p.position.x).to_int()
let y = max_height - @math.round(p.position.y).to_int()
c.write_pixel(x, y, red)
c.write_pixel(x + 1, y, red)
c.write_pixel(x + 1, y + 1, red)
c.write_pixel(x, y + 1, red)
p = tick(e, p)
t += 1
println("t=\{t}: pos=(\{p.position.x},\{p.position.y},\{p.position.z})")
}
//
try {
@fs.write_file("ch2.ppm", c.to_ppm(), permission=0o644)
@fs.write_file("ch2.png", c.to_png(), permission=0o644)
} catch {
e => println("error writing files: \{e}")
}
}
///|
fn tick(env : Environment, proj : Projectile) -> Projectile {
let position = proj.position + proj.velocity
let velocity = proj.velocity + env.gravity + env.wind
projectile(position, velocity)
}