diff --git a/.gitignore b/.gitignore index 3f643a0..24ee698 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -/humanshader \ No newline at end of file +/humanshader +*.ppm diff --git a/README.md b/README.md index 70a1d25..9c3dfc7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # Human Shader Validator -Validator for [Human Shader](https://humanshader.com/) \ No newline at end of file +Validator for [Human Shader](https://humanshader.com/) + +![Final image of Human Shader](humanshader.png) \ No newline at end of file diff --git a/hsv.go b/hsv.go index 6658283..aeeb926 100644 --- a/hsv.go +++ b/hsv.go @@ -10,24 +10,68 @@ import ( func main() { args := os.Args[1:] - var pxX int - var pxY int - if len(args) == 2 { - pxX, _ = strconv.Atoi(args[0]) - pxY, _ = strconv.Atoi(args[1]) - } else { - fmt.Print("Pixel x coordinate: ") - input := bufio.NewScanner(os.Stdin) - input.Scan() - pxX, _ = strconv.Atoi(input.Text()) - fmt.Print("Pixel y coordinate: ") - input = bufio.NewScanner(os.Stdin) - input.Scan() - pxY, _ = strconv.Atoi(input.Text()) - } - val := hsv.NewValidator(true) - val.Calculate(pxX, pxY) - r, g, b := val.GetColor() - fmt.Printf("R: %d\nG: %d\nB: %d\nHEX: #%02X%02X%02X\n", r, g, b, r, g, b) + // TODO: Better argument parsing + if len(args) == 1 || len(args) == 3 || len(args) == 5 { + fmt.Printf("Writing PPM image to %s.\n", args[0]) + if len(args) == 3 || len(args) == 5 { + width, _ := strconv.Atoi(args[1]) + height, _ := strconv.Atoi(args[2]) + if len(args) == 5 { + startx, _ := strconv.Atoi(args[3]) + starty, _ := strconv.Atoi(args[4]) + writePPM(args[0], width, height, startx, starty) + } else { + writePPM(args[0], width, height, 0, 0) + } + } else { + writePPM(args[0], 71, 40, 0, 0) + } + fmt.Println("Done") + } else if len(args) == 2 { + pxX, _ := strconv.Atoi(args[0]) + pxY, _ := strconv.Atoi(args[1]) + fmt.Println() + printPixel(pxX, pxY) + } else { + input := bufio.NewScanner(os.Stdin) + fmt.Print("Pixel x coordinate: ") + input.Scan() + pxX, _ := strconv.Atoi(input.Text()) + fmt.Print("Pixel y coordinate: ") + input.Scan() + pxY, _ := strconv.Atoi(input.Text()) + fmt.Println() + printPixel(pxX, pxY) + } +} + +func printPixel(x int, y int) { + val := hsv.NewValidator(true) + val.Calculate(x, y) + r, g, b := val.GetColor() + fmt.Printf("\nR: %d\nG: %d\nB: %d\nHEX: #%02X%02X%02X\n", r, g, b, r, g, b) +} + +func writePPM(path string, width int, height int, startx int, starty int) { + f, err := os.Create(path) + if err != nil { + panic(err) + } + defer f.Close() + + bw := bufio.NewWriter(f) + bw.WriteString("P3\n") + bw.WriteString(fmt.Sprintf("%d %d\n", width, height)) + bw.WriteString("255\n") + for y := startx; y < startx+height; y++ { + for x := starty; x < starty+width; x++ { + v := hsv.NewValidator(false) + v.Calculate(x, y) + r, g, b := v.GetColor() + bw.WriteString(fmt.Sprintf("%d %d %d ", r, g, b)) + } + bw.WriteString("\n") + } + bw.Flush() } diff --git a/humanshader.png b/humanshader.png new file mode 100644 index 0000000..9c4bbc3 Binary files /dev/null and b/humanshader.png differ diff --git a/validator/validator.go b/validator/validator.go index f55b00c..fd55acb 100644 --- a/validator/validator.go +++ b/validator/validator.go @@ -26,22 +26,20 @@ func (val *Validator) Calculate(x int, y int) { val.print("h = %d² + %d² = %d + %d = %d", u, v, u*u, v*v, h) if h < 200 { val.print("⇒ h < 200 → %d < 200", h) - val.print("=> Continuing to section B") val.sectionB(u, v, h) } else if v < 0 { val.print("⇒ h < 200 → %d ≮ 200", h) val.print("⇒ v < 0 → %d < 0", v) - val.print("=> Continuing to section C") val.sectionC(u, v, h) } else { val.print("⇒ h < 200 → %d ≮ 200", h) val.print("⇒ v < 0 → %d ≮ 0", v) - val.print("=> Continuing to section D") val.sectionD(x, y) } } func (val *Validator) sectionB(u int, v int, h int) { + val.print("=> Continuing to section B") val.r = 420 val.print("R = %d", val.r) val.b = 520 @@ -77,11 +75,11 @@ func (val *Validator) sectionB(u int, v int, h int) { val.b = val.b + w val.print(" B → B + %d ⇒ B = %d", w, val.b) } - val.print("=> Continuing to section E") val.sectionE() } func (val *Validator) sectionC(u int, v int, h int) { + val.print("=> Continuing to section C") val.r = 150 + 2*v val.print("R = 150 + 2 ⋅ %d = 150 + %d = %d", v, 2*v, val.r) val.b = 50 @@ -112,30 +110,38 @@ func (val *Validator) sectionC(u int, v int, h int) { val.r = val.r + d val.print(" R → R + %d ⇒ R = %d", d, val.r) } - val.print("=> Continuing to section E") val.sectionE() } func (val *Validator) sectionD(x int, y int) { + val.print("=> Continuing to section D") var c int = x + 4*y val.print("c = %d + 4 ⋅ %d", x, y) val.r = 132 + c val.print("R = 132 + %d = %d", c, val.r) val.b = 192 + c val.print("R = 192 + %d = %d", c, val.b) - val.print("=> Continuing to section E") val.sectionE() } func (val *Validator) sectionE() { + val.print("=> Continuing to section E") if val.r > 255 { val.r = 255 val.print("⇒ R > 255 → R = %d", val.r) } + if val.r < 0 { + val.r = 0 + val.print("⇒ R < 0 → R = %d", val.r) + } if val.b > 255 { val.b = 255 val.print("⇒ B > 255 → B = %d", val.b) } + if val.b < 0 { + val.b = 0 + val.print("⇒ B < 0 → B = %d", val.b) + } val.g = val.mod(7*val.r+3*val.b, 1) val.print("G = (7 + %d + 3 ⋅ %d) | 1 = (%d + %d) | 1 = %d | 1 = %d", val.r, val.b, 7+val.r, 3*val.b, 7*val.r+3*val.b, val.g) }