package main import ( "fmt" "os" ) type Camera struct { ImageWidth uint ImageHeight uint Centre Vec3 PDU Vec3 PDV Vec3 Pixel00 Vec3 } func NewCamera(w uint, ar float64) (cam Camera) { cam.ImageWidth = w; cam.ImageHeight = uint(float64(cam.ImageWidth) / ar); if cam.ImageHeight < 1 { cam.ImageHeight = 1; } focal_length := 1.0; viewport_height := 2.0; viewport_width := viewport_height * float64(cam.ImageWidth) / float64(cam.ImageHeight); cam.Centre = Splat(0); viewport_u := Vec3{viewport_width, 0, 0}; viewport_v := Vec3{0, -viewport_height, 0}; cam.PDU = viewport_u.Div(Splat(float64(cam.ImageWidth))); cam.PDV = viewport_v.Div(Splat(float64(cam.ImageHeight))); viewport_upperleft := cam.Centre. Sub(Vec3{0, 0, focal_length}). Sub(viewport_u.Div(Splat(2))). Sub(viewport_v.Div(Splat(2))); cam.Pixel00 = viewport_upperleft. Add(cam.PDU.Add(cam.PDV).Div(Splat(2))); return; } func (cam Camera) Render(world Hittable) { fmt.Printf("P3\n%d %d\n255\n", cam.ImageWidth, cam.ImageHeight); for row := uint(0); row < cam.ImageHeight; row++ { fmt.Fprintf(os.Stderr, "Scanlines remaining: %3d...", (cam.ImageHeight - row)); for col := uint(0); col < cam.ImageWidth; col++ { pixel_centre := cam.Pixel00. Add(cam.PDU.Mul(Splat(float64(col)))). Add(cam.PDV.Mul(Splat(float64(row)))); ray_direction := pixel_centre.Sub(cam.Centre); ray := Ray{cam.Centre, ray_direction} pixel_colour := ray.Colour(world); fmt.Printf("%s ", pixel_colour.ToPPM()); } fmt.Printf("\n"); } }