metto questo abbozzo di codice perche', nonostante non funzionante, puo' essere interessante
Ai tempi di Fractint su Dos c'e un algoritmo che divideva il piano di quadrati, se i punti estremi del quadrato avevano lo stesso valore allora tutto il quadrato assumeva lo stesso colore dell'insieme di Mandelbrot, in caso contrario il quadrato veniva a sua volta diviso in 4 quadrati e si reiterava
In questo caso ho cercato di fare lo stesso usando le goroutine ed la ricorsione
package main
import (
"fmt"
"math"
"math/cmplx"
"reflect"
"strconv"
"sync"
"github.com/fogleman/gg"
)
var wg sync.WaitGroup
// ATTENZION E il nome delle variabili deve essere in uppercase
// per poter esportare la variabile e
type punto struct {
Min_x float64
Max_x float64
Min_y float64
Max_y float64
Itera int64
}
var punti []punto // slice di struct
var transi punto
var mu sync.Mutex
func calcola(a float64, b float64) int {
var k int
c := complex(a, b)
k = 0
x := complex(0.0, 0.0)
for k = 0; k < 25; k++ {
x_a := (x * x)
x_a = x_a + c
x = x_a
if cmplx.Abs(x) > 2 {
return k
}
}
return k
}
func dividi(min_x float64, max_x float64, min_y float64, max_y float64) {
defer wg.Done()
x1 := calcola(min_x, min_y)
x2 := calcola(max_x, max_y)
if (x1 != x2) && (max_x-min_x > 0.005) {
mezzo_x := (max_x - min_x) / 2
mezzo_y := (max_y - min_y) / 2
wg.Add(4)
go dividi(min_x, min_x+mezzo_x, min_y, min_y+mezzo_y)
go dividi(min_x+mezzo_x, max_x, min_y, min_y+mezzo_y)
go dividi(min_x, min_x+mezzo_x, min_y+mezzo_y, max_y)
go dividi(min_x+mezzo_x, max_x, min_y+mezzo_y, max_y)
} else {
fmt.Println(strconv.FormatFloat(min_x, 'f', 6, 32) + ";" + strconv.FormatFloat(min_y, 'f', 6, 32) + ";" + strconv.Itoa(x1))
s := reflect.ValueOf(&transi).Elem()
s.Field(0).SetFloat(min_x)
s.Field(1).SetFloat(max_x)
s.Field(2).SetFloat(min_y)
s.Field(3).SetFloat(max_y)
s.Field(4).SetInt(int64(x1))
mu.Lock()
punti = append(punti, transi)
mu.Unlock()
}
}
func grafica() {
dc := gg.NewContext(400, 400)
dx := 3.0 / 400
dy := 2.0 / 400
for _, value := range punti {
fmt.Printf("%d\n", value)
min_x := math.Round(value.Min_x*dx) + 200
max_x := math.Round(value.Max_x*dx) + 200
min_y := math.Round((value.Min_y * dy)) + 200
max_y := math.Round((value.Max_y * dy)) + 200
dc.DrawRectangle(min_x, max_x, min_y, max_y)
dc.SetRGB255(value.Itera, 0, 0)
dc.Fill()
}
dc.SavePNG("mandelbrot.png")
}
func main() {
wg.Add(1)
go dividi(-2.0, 1.0, -1.0, 1.0)
wg.Wait()
grafica()
}
Nessun commento:
Posta un commento