Add image, Support writing PPM P3 image, Additional checks

This commit is contained in:
Manuel 2023-07-19 23:00:00 +02:00
parent 32d9ef18eb
commit 4e0801eb9b
Signed by: SunRed
GPG Key ID: 4085037435E1F07A
5 changed files with 80 additions and 27 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
/humanshader
/humanshader
*.ppm

View File

@ -1,3 +1,5 @@
# Human Shader Validator
Validator for [Human Shader](https://humanshader.com/)
Validator for [Human Shader](https://humanshader.com/)
![Final image of Human Shader](humanshader.png)

82
hsv.go
View File

@ -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()
}

BIN
humanshader.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -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)
}