Add image, Support writing PPM P3 image, Additional checks
This commit is contained in:
parent
32d9ef18eb
commit
4e0801eb9b
5 changed files with 80 additions and 27 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/humanshader
|
||||
*.ppm
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# Human Shader Validator
|
||||
|
||||
Validator for [Human Shader](https://humanshader.com/)
|
||||
|
||||
![Final image of Human Shader](humanshader.png)
|
82
hsv.go
82
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()
|
||||
}
|
||||
|
|
BIN
humanshader.png
Normal file
BIN
humanshader.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -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)
|
||||
}
|
||||
|
|
Reference in a new issue