Added colors to web
This commit is contained in:
		@@ -1,16 +1,20 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"image"
 | 
			
		||||
	"image/color"
 | 
			
		||||
	"image/png"
 | 
			
		||||
	"log"
 | 
			
		||||
	"math"
 | 
			
		||||
	"math/cmplx"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"deadbeef.codes/steven/mandelbrot/palette"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
@@ -19,6 +23,10 @@ const (
 | 
			
		||||
	Brighten   = 1024
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	colors []color.RGBA
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func mandelbrot(c complex128) uint16 {
 | 
			
		||||
	var z complex128
 | 
			
		||||
 | 
			
		||||
@@ -33,7 +41,7 @@ func mandelbrot(c complex128) uint16 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type pixel struct {
 | 
			
		||||
	out          *image.Gray16
 | 
			
		||||
	out          *image.RGBA
 | 
			
		||||
	x, y         int
 | 
			
		||||
	tileX, tileY int64
 | 
			
		||||
	tileZoom     uint8
 | 
			
		||||
@@ -50,8 +58,8 @@ func computeThread() {
 | 
			
		||||
				(float64(p.y)/Size+float64(p.tileY))/float64(uint(1<<p.tileZoom)),
 | 
			
		||||
			),
 | 
			
		||||
		)
 | 
			
		||||
		p.out.SetGray16(p.x, p.y, color.Gray16{val * Brighten})
 | 
			
		||||
 | 
			
		||||
		p.out.SetRGBA(p.x, p.y, colors[val])
 | 
			
		||||
		p.wg.Done()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -63,6 +71,10 @@ func main() {
 | 
			
		||||
		go computeThread()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	colorStep := float64(256)
 | 
			
		||||
	colors = interpolateColors("Plan9", colorStep)
 | 
			
		||||
	fmt.Println(len(colors))
 | 
			
		||||
 | 
			
		||||
	log.Fatal(http.ListenAndServe(":6161", nil))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -95,7 +107,7 @@ func renderTile(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
 | 
			
		||||
	wg.Add(Size * Size)
 | 
			
		||||
 | 
			
		||||
	img := image.NewGray16(image.Rect(0, 0, Size, Size))
 | 
			
		||||
	img := image.NewRGBA(image.Rect(0, 0, Size, Size))
 | 
			
		||||
 | 
			
		||||
	for x := 0; x < Size; x++ {
 | 
			
		||||
		for y := 0; y < Size; y++ {
 | 
			
		||||
@@ -112,3 +124,72 @@ func renderTile(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
func init() {
 | 
			
		||||
	http.HandleFunc("/mandelbrot/", renderTile)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ func init() {
 | 
			
		||||
		fmt.Fprintf(w, `<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
<title>Mandelbrot Map</title>
 | 
			
		||||
<title>MandelMapper</title>
 | 
			
		||||
<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
 | 
			
		||||
<script>
 | 
			
		||||
var mandelbrotTypeOptions = {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user