Re-arrange function ordering
This commit is contained in:
parent
4ec1823f2c
commit
9384d8f12e
@ -1,4 +1,4 @@
|
|||||||
FROM deadbeef.codes:5000/raspberrypi3-alpine:3.7
|
FROM deadbeef.codes:5000/raspberrypi3-alpine:3.7
|
||||||
COPY mandelmapper /usr/bin
|
COPY mandelmapper /usr/bin
|
||||||
EXPOSE 6161:6161
|
EXPOSE 6161:6161
|
||||||
CMD mandelmapper
|
CMD mandelmapper
|
||||||
|
220
render.go
220
render.go
@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"image/png"
|
"image/png"
|
||||||
@ -24,22 +23,9 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
colors []color.RGBA
|
colors []color.RGBA
|
||||||
|
queue = make(chan pixel)
|
||||||
)
|
)
|
||||||
|
|
||||||
func mandelbrot(c complex128) uint16 {
|
|
||||||
|
|
||||||
var z complex128
|
|
||||||
|
|
||||||
for i := 0; i < Iterations; i++ {
|
|
||||||
z = z*z + c
|
|
||||||
if cmplx.IsNaN(z) {
|
|
||||||
return uint16(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Iterations
|
|
||||||
}
|
|
||||||
|
|
||||||
type pixel struct {
|
type pixel struct {
|
||||||
out *image.RGBA
|
out *image.RGBA
|
||||||
x, y int
|
x, y int
|
||||||
@ -48,7 +34,22 @@ type pixel struct {
|
|||||||
wg *sync.WaitGroup
|
wg *sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
var queue = make(chan pixel)
|
func init() {
|
||||||
|
http.HandleFunc("/mandelbrot/", renderTile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
|
|
||||||
|
for i := 0; i < runtime.GOMAXPROCS(0); i++ {
|
||||||
|
go computeThread()
|
||||||
|
}
|
||||||
|
|
||||||
|
colorStep := float64(Iterations)
|
||||||
|
colors = interpolateColors("Plan9", colorStep)
|
||||||
|
|
||||||
|
log.Fatal(http.ListenAndServe(":6161", nil))
|
||||||
|
}
|
||||||
|
|
||||||
func computeThread() {
|
func computeThread() {
|
||||||
for p := range queue {
|
for p := range queue {
|
||||||
@ -63,18 +64,70 @@ func computeThread() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
//interpolateColors accepts a color palette and number of desired colors and builds a slice of colors by interpolating the gaps
|
||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
func interpolateColors(paletteCode string, numberOfColors float64) []color.RGBA {
|
||||||
|
var factor float64
|
||||||
for i := 0; i < runtime.GOMAXPROCS(0); i++ {
|
steps := []float64{}
|
||||||
go computeThread()
|
cols := []uint32{}
|
||||||
|
interpolated := []uint32{}
|
||||||
|
interpolatedColors := []color.RGBA{}
|
||||||
|
for _, v := range palette.ColorPalettes {
|
||||||
|
factor = 1.0 / numberOfColors
|
||||||
|
switch v.Keyword {
|
||||||
|
case paletteCode:
|
||||||
|
if paletteCode != "" {
|
||||||
|
for index, col := range v.Colors {
|
||||||
|
if col.Step == 0.0 && index != 0 {
|
||||||
|
stepRatio := float64(index+1) / float64(len(v.Colors))
|
||||||
|
step := float64(int(stepRatio*100)) / 100 // truncate to 2 decimal precision
|
||||||
|
steps = append(steps, step)
|
||||||
|
} else {
|
||||||
|
steps = append(steps, col.Step)
|
||||||
}
|
}
|
||||||
|
r, g, b, a := col.Color.RGBA()
|
||||||
|
r /= 0xff
|
||||||
|
g /= 0xff
|
||||||
|
b /= 0xff
|
||||||
|
a /= 0xff
|
||||||
|
uintColor := uint32(r)<<24 | uint32(g)<<16 | uint32(b)<<8 | uint32(a)
|
||||||
|
cols = append(cols, uintColor)
|
||||||
|
}
|
||||||
|
var min, max, minColor, maxColor float64
|
||||||
|
if len(v.Colors) == len(steps) && len(v.Colors) == len(cols) {
|
||||||
|
for i := 0.0; i <= 1; i += factor {
|
||||||
|
for j := 0; j < len(v.Colors)-1; j++ {
|
||||||
|
if i >= steps[j] && i < steps[j+1] {
|
||||||
|
min = steps[j]
|
||||||
|
max = steps[j+1]
|
||||||
|
minColor = float64(cols[j])
|
||||||
|
maxColor = float64(cols[j+1])
|
||||||
|
uintColor := cosineInterpolation(maxColor, minColor, (i-min)/(max-min))
|
||||||
|
interpolated = append(interpolated, uint32(uintColor))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, pixelValue := range interpolated {
|
||||||
|
r := pixelValue >> 24 & 0xff
|
||||||
|
g := pixelValue >> 16 & 0xff
|
||||||
|
b := pixelValue >> 8 & 0xff
|
||||||
|
a := 0xff
|
||||||
|
|
||||||
colorStep := float64(Iterations)
|
interpolatedColors = append(interpolatedColors, color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)})
|
||||||
colors = interpolateColors("Plan9", colorStep)
|
}
|
||||||
fmt.Println(len(colors))
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return interpolatedColors
|
||||||
|
}
|
||||||
|
|
||||||
log.Fatal(http.ListenAndServe(":6161", nil))
|
func cosineInterpolation(c1, c2, mu float64) float64 {
|
||||||
|
mu2 := (1 - math.Cos(mu*math.Pi)) / 2.0
|
||||||
|
return c1*(1-mu2) + c2*mu2
|
||||||
|
}
|
||||||
|
|
||||||
|
func linearInterpolation(c1, c2, mu uint32) uint32 {
|
||||||
|
return c1*(1-mu) + c2*mu
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderTile(w http.ResponseWriter, r *http.Request) {
|
func renderTile(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -103,9 +156,7 @@ func renderTile(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
wg.Add(Size * Size)
|
wg.Add(Size * Size)
|
||||||
|
|
||||||
img := image.NewRGBA(image.Rect(0, 0, Size, Size))
|
img := image.NewRGBA(image.Rect(0, 0, Size, Size))
|
||||||
|
|
||||||
for x := 0; x < Size; x++ {
|
for x := 0; x < Size; x++ {
|
||||||
@ -116,114 +167,17 @@ func renderTile(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
/*
|
|
||||||
ip := GetOutboundIP()
|
|
||||||
addLabel(img, 20, 30, fmt.Sprintf("rendered by \n%s", ip.String()))
|
|
||||||
addLabel(img, 20, 30, fmt.Sprintf("%s/%s/%s.png", components[1], components[2], components[3]))
|
|
||||||
*/
|
|
||||||
w.Header().Set("Content-Type", "image/png")
|
w.Header().Set("Content-Type", "image/png")
|
||||||
png.Encode(w, img)
|
png.Encode(w, img)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func mandelbrot(c complex128) uint16 {
|
||||||
http.HandleFunc("/mandelbrot/", renderTile)
|
var z complex128
|
||||||
|
for i := 0; i < Iterations; i++ {
|
||||||
|
z = z*z + c
|
||||||
|
if cmplx.IsNaN(z) {
|
||||||
|
return uint16(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Iterations
|
||||||
}
|
}
|
||||||
|
|
||||||
func interpolateColors(paletteCode string, numberOfColors float64) []color.RGBA {
|
|
||||||
var factor float64
|
|
||||||
steps := []float64{}
|
|
||||||
cols := []uint32{}
|
|
||||||
interpolated := []uint32{}
|
|
||||||
interpolatedColors := []color.RGBA{}
|
|
||||||
|
|
||||||
for _, v := range palette.ColorPalettes {
|
|
||||||
factor = 1.0 / numberOfColors
|
|
||||||
switch v.Keyword {
|
|
||||||
case paletteCode:
|
|
||||||
if paletteCode != "" {
|
|
||||||
for index, col := range v.Colors {
|
|
||||||
if col.Step == 0.0 && index != 0 {
|
|
||||||
stepRatio := float64(index+1) / float64(len(v.Colors))
|
|
||||||
step := float64(int(stepRatio*100)) / 100 // truncate to 2 decimal precision
|
|
||||||
steps = append(steps, step)
|
|
||||||
} else {
|
|
||||||
steps = append(steps, col.Step)
|
|
||||||
}
|
|
||||||
r, g, b, a := col.Color.RGBA()
|
|
||||||
r /= 0xff
|
|
||||||
g /= 0xff
|
|
||||||
b /= 0xff
|
|
||||||
a /= 0xff
|
|
||||||
uintColor := uint32(r)<<24 | uint32(g)<<16 | uint32(b)<<8 | uint32(a)
|
|
||||||
cols = append(cols, uintColor)
|
|
||||||
}
|
|
||||||
|
|
||||||
var min, max, minColor, maxColor float64
|
|
||||||
if len(v.Colors) == len(steps) && len(v.Colors) == len(cols) {
|
|
||||||
for i := 0.0; i <= 1; i += factor {
|
|
||||||
for j := 0; j < len(v.Colors)-1; j++ {
|
|
||||||
if i >= steps[j] && i < steps[j+1] {
|
|
||||||
min = steps[j]
|
|
||||||
max = steps[j+1]
|
|
||||||
minColor = float64(cols[j])
|
|
||||||
maxColor = float64(cols[j+1])
|
|
||||||
uintColor := cosineInterpolation(maxColor, minColor, (i-min)/(max-min))
|
|
||||||
interpolated = append(interpolated, uint32(uintColor))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, pixelValue := range interpolated {
|
|
||||||
r := pixelValue >> 24 & 0xff
|
|
||||||
g := pixelValue >> 16 & 0xff
|
|
||||||
b := pixelValue >> 8 & 0xff
|
|
||||||
a := 0xff
|
|
||||||
|
|
||||||
interpolatedColors = append(interpolatedColors, color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return interpolatedColors
|
|
||||||
}
|
|
||||||
|
|
||||||
func cosineInterpolation(c1, c2, mu float64) float64 {
|
|
||||||
mu2 := (1 - math.Cos(mu*math.Pi)) / 2.0
|
|
||||||
return c1*(1-mu2) + c2*mu2
|
|
||||||
}
|
|
||||||
|
|
||||||
func linearInterpolation(c1, c2, mu uint32) uint32 {
|
|
||||||
return c1*(1-mu) + c2*mu
|
|
||||||
}
|
|
||||||
|
|
||||||
//Adds a text label to an image
|
|
||||||
/*
|
|
||||||
func addLabel(img *image.RGBA, x, y int, label string) {
|
|
||||||
col := color.RGBA{255, 255, 255, 255}
|
|
||||||
point := fixed.Point26_6{fixed.Int26_6(x * 64), fixed.Int26_6(y * 64)}
|
|
||||||
|
|
||||||
d := &font.Drawer{
|
|
||||||
Dst: img,
|
|
||||||
Src: image.NewUniform(col),
|
|
||||||
Face: basicfont.Face7x13,
|
|
||||||
Dot: point,
|
|
||||||
}
|
|
||||||
d.DrawString(label)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func GetOutboundIP() net.IP {
|
|
||||||
conn, err := net.Dial("udp", "8.8.8.8:80")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
localAddr := conn.LocalAddr().(*net.UDPAddr)
|
|
||||||
|
|
||||||
return localAddr.IP
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
Loading…
Reference in New Issue
Block a user