halfmonty 2021-03-13 19:10:17 -06:00 zatwierdzone przez GitHub
rodzic 3ec3f9763e
commit 215be81cb5
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
1 zmienionych plików z 207 dodań i 0 usunięć

207
main.go 100644
Wyświetl plik

@ -0,0 +1,207 @@
package main
import (
"fmt"
"math"
"image"
"image/jpeg"
"github.com/antha-lang/antha/antha/anthalib/num"
"os"
"io"
"time"
"strconv"
"syscall/js"
)
//**********************//
// Structs //
//**********************//
type Coord struct {
X float64
Y float64
}
const PINS = 300
const MIN_DISTANCE = 30
const MAX_LINES = 4000
const LINE_WEIGHT = 8
var IMG_SIZE = 500
var IMG_SIZE_FL = float64(500)
var IMG_SIZE_SQ = 250000
var Pin_coords = []Coord{}
var SourceImage = []float64{}
var Line_cache_y = [][]float64{}
var Line_cache_x = [][]float64{}
//**********************//
// Main //
//**********************//
func init(){
image.RegisterFormat("jpeg", "jpeg", jpeg.Decode, jpeg.DecodeConfig)
}
func main() {
SourceImage = importPictureAndGetPixelArray()
fmt.Println("Hello, world.")
startTime := time.Now()
calculatePinCoords()
precalculateAllPotentialLines()
calculateLines()
endTime := time.Now()
diff := endTime.Sub(startTime)
fmt.Println(" precalculateAllPotentialLines Taken, " + strconv.FormatFloat(diff.Seconds(), 'f', 6, 64))
fmt.Println("End")
}
func generateStringArt()
func importPictureAndGetPixelArray() []float64 {
imgfile, _ := os.Open("./ae300.jpg")
defer imgfile.Close()
pixels, _ := getPixels(imgfile)
return pixels
}
func getPixels(file io.Reader) ([]float64, error) {
img, _, err := image.Decode(file)
if err != nil {
return nil, err
}
bounds := img.Bounds()
width, height := bounds.Max.X, bounds.Max.Y
IMG_SIZE = width
IMG_SIZE_FL = float64(IMG_SIZE)
IMG_SIZE_SQ = IMG_SIZE * IMG_SIZE
var pixels []float64
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
pixels = append(pixels, rgbaToPixel(img.At(x, y).RGBA()))
}
}
return pixels, nil
}
func rgbaToPixel(r uint32, g uint32, b uint32, a uint32) float64 {
return float64(r / 257)
}
func calculatePinCoords() {
pin_coords := [PINS]Coord{}
center := float64(IMG_SIZE / 2)
radius := float64(IMG_SIZE/2 - 1)
for i:=0;i<PINS;i++ {
angle := 2 * math.Pi * float64(i) / float64(PINS)
pin_coords[i] = Coord{X : math.Floor(center + radius*math.Cos(angle)), Y : math.Floor(center + radius*math.Sin(angle))}
}
Pin_coords = pin_coords[:]
}
func precalculateAllPotentialLines() {
line_cache_y := [PINS * PINS][]float64{}
line_cache_x := [PINS * PINS][]float64{}
for i := 0; i < PINS; i++ {
for j := i + MIN_DISTANCE; j < PINS; j++ {
x0 := Pin_coords[i].X
y0 := Pin_coords[i].Y
x1 := Pin_coords[j].X
y1 := Pin_coords[j].Y
d := math.Floor(math.Sqrt(float64((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0))))
xs := roundUpFloatArrayToInt(num.Linspace(float64(x0), float64(x1), int(d)))
ys := roundUpFloatArrayToInt(num.Linspace(float64(y0), float64(y1), int(d)))
line_cache_y[j*PINS+i] = ys
line_cache_y[i*PINS+j] = ys
line_cache_x[j*PINS+i] = xs
line_cache_x[i*PINS+j] = xs
}
}
Line_cache_y = line_cache_y[:][:]
Line_cache_x = line_cache_x[:][:]
}
func roundUpFloatArrayToInt(arr []float64) []float64 {
for i:= range arr {
arr[i] = float64(int(arr[i]))
}
return arr
}
func calculateLines() {
fmt.Println("Drawing Lines....")
error := num.Sub(num.MulByConst(num.Ones(IMG_SIZE_SQ), float64(255)), SourceImage)
line_sequence := make([]int, 1, 4096)
current_pin := 0
last_pins := make([]int, 20, 24)
best_pin := -1
line_err := float64(0)
max_err := float64(0)
index := 0
inner_index := 0
for i := 0; i < MAX_LINES; i++ {
best_pin = -1
line_err = float64(0)
max_err = float64(0)
for offset := MIN_DISTANCE; offset < PINS - MIN_DISTANCE; offset++ {
test_pin := (current_pin + offset) % PINS
if(contains(last_pins, test_pin)){
continue;
} else {
inner_index = test_pin * PINS + current_pin
line_err = getLineErr(error, Line_cache_y[inner_index], Line_cache_x[inner_index])
if( line_err > max_err){
max_err = line_err
best_pin = test_pin
index = inner_index
}
}
}
line_sequence = append(line_sequence, best_pin)
coords1:=Line_cache_y[index]
coords2:=Line_cache_x[index]
for i := range coords1 {
v := int((coords1[i] * IMG_SIZE_FL) + coords2[i])
error[v] = error[v] - LINE_WEIGHT
}
last_pins = append(last_pins, best_pin)
last_pins = last_pins[1:]
current_pin = best_pin
}
fmt.Println(line_sequence)
}
func getLineErr(err, coords1, coords2 []float64) float64 {
sum := float64(0)
for i:=0;i<len(coords1);i++{
sum = sum + err[int((coords1[i] * IMG_SIZE_FL) + coords2[i])]
}
return sum
}
func contains(arr []int, num int) bool {
for i := range arr {
if arr[i] == num {
return true
}
}
return false
}