2024-01-25 19:41:11 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import "fmt"
|
|
|
|
import "os" //for handling the logging output
|
2024-01-28 13:32:04 +00:00
|
|
|
import "math"
|
2024-01-25 19:41:11 +00:00
|
|
|
|
2024-01-28 13:32:04 +00:00
|
|
|
// ================ VEC3 CLASS =====================
|
|
|
|
|
|
|
|
type Vec3 struct {
|
|
|
|
E [3]float32
|
|
|
|
}
|
|
|
|
|
|
|
|
//Basic vector functions
|
|
|
|
|
|
|
|
func NewVec3(e0, e1, e2 float32) Vec3 {
|
|
|
|
return Vec3{E: [3]float32{e0, e1, e2}}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v Vec3) X() float32 {
|
|
|
|
return v.E[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
// can be executed as v.X() in main
|
|
|
|
|
|
|
|
func (v Vec3) Y() float32 {
|
|
|
|
return v.E[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v Vec3) Z() float32 {
|
|
|
|
return v.E[2]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v Vec3) Neg() Vec3 {
|
|
|
|
return NewVec3(-v.E[0], -v.E[1], -v.E[2])
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v Vec3) Get(i int) float32 {
|
|
|
|
return v.E[i]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Vec3) Set(i int, val float32) {
|
|
|
|
v.E[i] = val
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Vec3) Add(v2 Vec3) {
|
|
|
|
v.E[0] += v2.E[0]
|
|
|
|
v.E[1] += v2.E[1]
|
|
|
|
v.E[2] += v2.E[2]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Vec3) Mult(t float32) {
|
|
|
|
v.E[0] *= t
|
|
|
|
v.E[1] *= t
|
|
|
|
v.E[2] *= t
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Vec3) Div(t float32) {
|
|
|
|
if t != 0 {
|
|
|
|
v.E[0] /= t
|
|
|
|
v.E[1] /= t
|
|
|
|
v.E[2] /= t
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v Vec3) Length() float32 {
|
|
|
|
return float32(math.Sqrt(float64(v.E[0]*v.E[0] + v.E[1]*v.E[1] + v.E[2]*v.E[2])))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Vector utility functions
|
|
|
|
|
|
|
|
func (v Vec3) String() string {
|
|
|
|
return fmt.Sprintf("%v %v %v", v.E[0], v.E[1], v.E[2])
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Vec3) Sub(v2 Vec3) {
|
|
|
|
v.E[0] -= v2.E[0]
|
|
|
|
v.E[1] -= v2.E[1]
|
|
|
|
v.E[2] -= v2.E[2]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Vec3) MultVec(v2 Vec3) {
|
|
|
|
v.E[0] *= v2.E[0]
|
|
|
|
v.E[1] *= v2.E[1]
|
|
|
|
v.E[2] *= v2.E[2]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Vec3) DivVec(v2 Vec3) {
|
|
|
|
v.E[0] /= v2.E[0]
|
|
|
|
v.E[1] /= v2.E[1]
|
|
|
|
v.E[2] /= v2.E[2]
|
|
|
|
}
|
|
|
|
|
|
|
|
func Dot(v1 Vec3, v2 Vec3) float32 {
|
|
|
|
return (v1.E[0]*v2.E[0] + v1.E[1]*v2.E[1] + v1.E[2]*v2.E[2])
|
|
|
|
}
|
|
|
|
|
|
|
|
func Cross(v1 Vec3, v2 Vec3) Vec3 {
|
|
|
|
return NewVec3(v1.E[1]*v2.E[2] - v1.E[2]*v2.E[1],
|
|
|
|
v1.E[2]*v2.E[0] - v1.E[0]*v2.E[2],
|
|
|
|
v1.E[0]*v2.E[1] - v1.E[1]*v2.E[0])
|
|
|
|
}
|
|
|
|
|
|
|
|
func Unit_vector(v Vec3) Vec3 {
|
|
|
|
v.Div(v.Length())
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
|
|
|
// ============== COLOUR CLASS ==============
|
|
|
|
|
|
|
|
func Write_color(v Vec3) {
|
|
|
|
fmt.Println(int(255.999*v.E[0]), int(255.999*v.E[1]), int(255.999*v.E[2]))
|
|
|
|
}
|
|
|
|
|
|
|
|
// =============== MAIN =====================
|
2024-01-25 19:41:11 +00:00
|
|
|
func main() {
|
|
|
|
|
|
|
|
// Image
|
|
|
|
var image_width int = 256
|
|
|
|
var image_height int = 256
|
|
|
|
|
|
|
|
// Rendering
|
|
|
|
fmt.Println("P3")
|
|
|
|
fmt.Println(image_width, " ", image_height, "\n255")
|
|
|
|
for j := 0; j < image_height; j++ {
|
|
|
|
fmt.Fprintf(os.Stderr, "\rScanlines remaining: %d ", image_height-j)
|
|
|
|
for i := 0; i < image_width; i++ {
|
2024-01-28 13:32:04 +00:00
|
|
|
// r := float32(i) / float32(image_width - 1)
|
|
|
|
// g := float32(j) / float32(image_height-1)
|
|
|
|
// b := 0
|
|
|
|
|
|
|
|
// ir := int(r * 256)
|
|
|
|
// ig := int(g * 256)
|
|
|
|
// ib := int(b * 256)
|
|
|
|
// fmt.Println(ir, " ", ig, " ", ib)
|
|
|
|
|
|
|
|
pixel_colour := NewVec3(float32(i) / float32(image_width - 1), float32(j) / float32(image_height-1), 0)
|
|
|
|
Write_color(pixel_colour)
|
2024-01-25 19:41:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// INFO: The pixels are written out in rows.
|
|
|
|
// Image file can be created with
|
2024-01-28 13:32:04 +00:00
|
|
|
// go run main.go > image.ppm
|
2024-01-25 19:41:11 +00:00
|
|
|
}
|