Skip to content

Instantly share code, notes, and snippets.

@quackduck
Last active May 2, 2023 16:21
Show Gist options
  • Save quackduck/e8847cee1fd78314aa5764870e037a71 to your computer and use it in GitHub Desktop.
Save quackduck/e8847cee1fd78314aa5764870e037a71 to your computer and use it in GitHub Desktop.
package main
import (
"errors"
"fmt"
"image"
"image/color"
"image/png"
"math"
"os"
)
func main() {
writeTo, err := os.Create("/Users/ishan/Downloads/sinebow.png")
if err != nil {
panic(err)
}
width := 500
height := 500
img := image.NewNRGBA(image.Rect(0, 0, width, height))
fmt.Println(invHue(255, 0, 0))
return
for i := 0.0; i <= 1; i+=0.01 {
r, g, b := hueFloat(i)
//r, g, b = math.Round(r), math.Round(g), math.Round(b)
fmt.Println(r, g, b)
h, err := invHue(r, g, b)
if err != nil {
panic(err)
}
if math.Abs(h-i) > 0.000000001 {
panic(fmt.Sprintf("h != i: %f %f", h, i))
}
fmt.Println(h)
}
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
distFromCenter := math.Sqrt(math.Pow(float64(x-width/2), 2) + math.Pow(float64(y-height/2), 2))
if distFromCenter > float64(width)/2 {//|| distFromCenter < float64(width)/3{
img.Set(x, y, color.NRGBA{
R: 0,
G: 0,
B: 0,
A: 0,
})
continue
}
angle := math.Atan2(float64(y-height/2), float64(x-width/2))
if angle/(2*math.Pi) + 0.5 < 0.0 {
fmt.Println("angle < 0.0: ", angle, x, y)
}
//r, g, b := hue(1 - float64(x)/float64(width))
r, g, b := hueFloat(angle/(2*math.Pi) + 0.5)
//fmt.Println(r, g, b)
img.Set(x, y, color.NRGBA{
R: uint8(r+0.5),
G: uint8(g+0.5),
B: uint8(b+0.5),
A: 255,
})
}
}
err = png.Encode(writeTo, img)
if err != nil {
panic(err)
}
err = writeTo.Close()
if err != nil {
panic(err)
}
}
// outputs in range [0, 255]
func hueFloat(h float64) (r, g, b float64) {
//r, g, b = colorful.HSLuv(h*360.0, 1, 0.6).RGB255()
//h = 1 - h
pi := math.Pi
r = 255.0 * (0.5 + 0.5*math.Sin(2*pi*h+pi/2))
g = 255.0 * (0.5 + 0.5*math.Sin(2*pi*h+pi/2+2*pi/3))
b = 255.0 * (0.5 + 0.5*math.Sin(2*pi*h+pi/2+4*pi/3))
//h = 1 - h
//pi := math.Pi
//r = uint8(math.Round(255.0 * (1/pi*math.Acos(math.Sin(2*pi*h-pi/2)))))
//g = uint8(math.Round(255.0 * (1/pi*math.Acos(math.Sin(2*pi*h-pi/2+2*pi/3)))))
//b = uint8(math.Round(255.0 * (1/pi*math.Acos(math.Sin(2*pi*h-pi/2+4*pi/3)))))
//r, g, b, _ = colorconv.HSVToRGB(math.Abs(h*360.0),1, 1)
//if r == g && g == b && b == 0 {
// r, g, b = 255, 0, 0
//}
return
}
//func hue(h float64) (r, g, b uint8) {
// rf, gf, bf := hueFloat(h)
// r, g, b = uint8(rf + 0.5), uint8(gf + 0.5), uint8(bf + 0.5)
// return
//}
// https://www.desmos.com/calculator/1blvi1yxtd
func invHue(r, g, b float64) (float64, error) {
pi := math.Pi
//minusFrom1IfNegative := func (v float64) float64 {
// if v < 0.0 {
// return 1-v
// }
// return v
//}
// base equation for red: \left(\arcsin\left(2x-1\right)-\frac{\pi}{2}\right)\left(\frac{1}{2\pi}\right)+1
//r1 := func(v float64) float64 {
// return (math.Asin(2*v-1)-pi/2)/(2*pi)+1
//}
r1 := (math.Asin(2*(r/255)-1)-pi/2)/(2*pi)+1
if b > g { // hard to explain why this works without seeing the graph. this is basically how we know which part of the graph we're in.
r1 = 1-r1
}
//r2 := 1-r1
//fmt.Println("r1, r2", r1, r2)
// it's one of these two. try and see which one works.
// possibilities 1 and 2
pr, pg, pb := hueFloat(r1)
//p2r, p2g, p2b := hueFloat(r2)
// sum differences
//d := math.Abs(r-pr) + math.Abs(g-pg) + math.Abs(b-pb)
////d2 := math.Abs(r-p2r) + math.Abs(g-p2g) + math.Abs(b-p2b)
//fmt.Println(d1, d2)
if math.Abs(r-pr) >= 1 || math.Abs(g-pg) >= 1 || math.Abs(b-pb) >= 1 {
return 0, errors.New("unrepresentable color")
}
//if d1 <= d2 {
//if d1 != 0 {
// panic(fmt.Sprint("d1 != 0 ", d1, d2, r1, r2))
//}
return r1, nil
//} else {
// //if d2 != 0 {
// // panic(fmt.Sprint("d2 != 0 ", d1, d2, r1, r2))
// //}
// return r2, nil
//}
//r2 := func(v float64) float64 {return 1-r1(v)}
//g1 := func(v float64) float64 {return r1(v)-1/3}
//g2 := func(v float64) float64 {return 2/3 - r1(v)}
//b1 := func(v float64) float64 {return r1(v)-2/3}
//b2 := func(v float64) float64 {return 4/3 - r1(v)}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment