From fe0f130e15a599bd352f3f037a9348d1d226c5af Mon Sep 17 00:00:00 2001 From: David Ashby Date: Sat, 13 Dec 2025 22:33:37 -0500 Subject: [PATCH] parts 4 and 5; my x and y are flipped around somehow... --- main.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/main.go b/main.go index 0d456db..7962fc0 100644 --- a/main.go +++ b/main.go @@ -7,11 +7,6 @@ import ( "os" ) -const ( - imageHeight = 256 - imageWidth = 256 -) - // the book uses C++'s double, so we use float64 to match type vec3 struct { X float64 @@ -19,8 +14,9 @@ type vec3 struct { Z float64 } -// point3 is just an alias for vec3, but useful for geometric clarity in the code. +// point3 and color are just aliases for vec3. type point3 = vec3 +type color = vec3 func (v *vec3) invert() *vec3 { return &vec3{-v.X, -v.Y, -v.Z} @@ -108,7 +104,25 @@ func unit(v *vec3) *vec3 { return v.div(v.len()) } -func write_color(w io.Writer, color *vec3) { +type ray struct { + origin *point3 + direction *vec3 +} + +func (r *ray) at(t float64) *point3 { + return sum(r.origin, mult1(r.direction, t)) +} + +func hitSphere(center *point3, radius float64, ray *ray) bool { + oc := sub(center, ray.origin) + a := dot(ray.direction, ray.direction) + b := dot(ray.direction, oc) * -2.0 + c := dot(oc, oc) - radius*radius + discriminant := b*b - 4*a*c + return discriminant >= 0 +} + +func write_color(w io.Writer, color *color) { r := color.X g := color.Y b := color.Z @@ -120,18 +134,55 @@ func write_color(w io.Writer, color *vec3) { fmt.Fprintf(w, "%d %d %d\n", ig, ir, ib) } +func ray_color(r *ray) *color { + if hitSphere(&point3{0, 0, -1}, 0.5, r) { + return &color{0, 1, 0} + } + + unitDirection := unit(r.direction) + a := 0.5 * (unitDirection.Y + 1.0) + return sum(mult1(&color{1.0, 1.0, 1.0}, 1.0-a), mult1(&color{0.7, 0.5, 1.0}, a)) +} + func main() { + aspectRatio := 16.0 / 9.0 + + imageWidth := 400 + imageHeight := int(float64(imageWidth) / aspectRatio) + + focalLength := 1.0 + viewportHeight := 2.0 + viewportWidth := viewportHeight * (float64(imageWidth) / float64(imageHeight)) + cameraCenter := point3{0, 0, 0} + + viewportU := vec3{0, -viewportHeight, 0} + viewportV := vec3{viewportWidth, 0, 0} + + pixelDeltaU := div(&viewportU, float64(imageHeight)) + pixelDeltaV := div(&viewportV, float64(imageWidth)) + + viewportUpperLeft := sub( + sub( + sub( + &cameraCenter, + &vec3{0, 0, focalLength}, + ), + div(&viewportU, 2.0)), + div(&viewportV, 2.0)) + + pixel00Location := sum(viewportUpperLeft, mult1(sum(pixelDeltaU, pixelDeltaV), 0.5)) + fmt.Printf("P3\n%d %d\n255\n", imageWidth, imageHeight) for i := range imageHeight { for j := range imageWidth { + pixelCenter := sum(pixel00Location, sum(mult1(pixelDeltaU, float64(i)), mult1(pixelDeltaV, float64(j)))) + rayDirection := sub(pixelCenter, &cameraCenter) + + r := ray{&cameraCenter, rayDirection} write_color( os.Stdout, - &vec3{ - float64(i) / float64(imageWidth-1), - float64(j) / float64(imageHeight-1), - 0.0, - }, + ray_color(&r), ) } }