Files
sumi/main.go
2025-12-22 16:36:33 -06:00

198 lines
4.4 KiB
Go

package main
import (
"fmt"
"log"
"math/rand"
"os"
"time"
"github.com/gen2brain/raylib-go/raylib"
"github.com/ojrac/opensimplex-go"
)
const (
targetWidth = 1000
targetHeight = 1000
sourceScale = 2
snapshotsDir = "snapshots"
)
func main() {
sourceWidth := int32(sourceScale * targetWidth)
sourceHeight := int32(sourceScale * targetHeight)
os.MkdirAll(snapshotsDir, 0755)
log := log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile)
storage, err := NewStorage(snapshotsDir)
if err != nil {
log.Printf("Error loading storage: %v\n", err)
os.Exit(1)
}
rl.SetConfigFlags(rl.FlagMsaa4xHint)
rl.InitWindow(targetWidth, targetHeight, "sumi sierpinski arrow")
rl.SetTargetFPS(60)
t0 := time.Now()
/*
*/
imageField := NewImageField("/home/d/Dropbox/art/passage/data/david.png")
field :=
TranslateField{
x: -float32(sourceWidth / 2.0),
y: -float32(sourceHeight / 2.0),
field: &ScaleField{
scale: 1.0,
field: &imageField,
},
}
rng := rand.New(rand.NewSource(0))
sketch := NewSketch(sourceWidth, sourceHeight)
contourLayer := NewContourLayer(&sketch, rng, &field)
//sketch.CreateLayer("testPattern", &TestPattern{}, int32(sourceWidth), int32(sourceHeight))
//sketch.CreateLayer("actors", &contourLayer, int32(sourceWidth), int32(sourceHeight))
//sketch.CreateLayer("field", &FieldLayer{field: &field, dirty: true}, int32(sourceWidth), int32(sourceHeight))
sketch.CreateLayer("contours", &contourLayer)
ports := MakePorts()
ports["sierpinskiArrowAngle"] = Sine {
Amp: 120,
Bias: 100,
Freq: 0.1,
}
for !rl.WindowShouldClose() {
// begin drawing
t := time.Since(t0).Seconds()
// set up RenderCtx
renderCtx := &RenderCtx{
TargetWidth: int32(targetWidth),
TargetHeight: int32(targetHeight),
SourceWidth: int32(sourceWidth),
SourceHeight: int32(sourceHeight),
Time: t,
Ports: ports.Eval(t),
}
sketch.Update(renderCtx)
/**
* MAIN DRAWING
*/
rl.BeginDrawing()
rl.ClearBackground(rl.Blank)
sketch.Draw(renderCtx)
rl.DrawText("Mouse right button drag to move, mouse wheel to zoom", 10, 10, 20, rl.White)
rl.EndDrawing()
if rl.IsKeyDown(rl.KeySpace) {
capture := sketch.Capture()
if _, err := storage.Save(capture); err != nil {
log.Printf("Error saving snapshot: %v\n", err)
}
}
for ch := rl.GetCharPressed(); ch != 0; ch = rl.GetCharPressed() {
c := rune(ch)
if c == 'c' {
sketch.ResetCamera()
} else if c >= '1' && c <= '9' {
zoom := 1 << int(ch-'0')
sketch.cam.Zoom = float32(zoom)
}
}
//rl.EndMode2D()
// HUD
}
rl.CloseWindow()
}
type FieldLayer struct {
field Field
dirty bool
}
func (s *FieldLayer) Update(ctx *RenderCtx) {
;
}
func (s *FieldLayer) Draw(ctx *RenderCtx) {
for x := range ctx.SourceWidth {
for y := range ctx.SourceHeight {
v := s.field.Get(float32(x), float32(y))
clr := GrayCurve(v, 1.0)
rl.DrawPixel(x, y, clr)
}
}
s.dirty = false
}
func (s *FieldLayer) IsDirty() bool {
return s.dirty
}
type SierpinskiArrow struct{}
func (s *SierpinskiArrow) Draw(ctx *RenderCtx) {
sierpinskiArrow(ctx, int(ctx.Ports["sierpinskiArrowDepth"]), ctx.Ports["sierpinskiArrowLength"])
}
func sierpinskiArrow(ctx *RenderCtx, order int, length float64) {
if order == 0 {
curve(ctx, order, length, ctx.Ports["sierpinskiArrowAngle"])
} else {
rl.Rotatef(float32(ctx.Ports["sierpinskiArrowAngle"]), 0, 0, 1)
curve(ctx, order, length, -ctx.Ports["sierpinskiArrowAngle"])
}
}
func curve(ctx *RenderCtx, order int, length float64, angle float64) {
if order == 0 {
len := int32(length)
rl.DrawLine(0, 0, len, 0, rl.Black)
rl.Translatef(float32(length), 0, 0)
} else {
curve(ctx, order-1, length/2, -angle)
rl.Rotatef(float32(angle), 0, 0, 1)
curve(ctx, order-1, length/2, angle)
rl.Rotatef(float32(angle), 0, 0, 1)
curve(ctx, order-1, length/2, -angle)
}
}
func main2() {
angles := make([]float32, 1000)
noise := opensimplex.NewNormalized(0)
for i := range len(angles) {
angles[i] = float32(noise.Eval2(float64(i)*0.05, 0.00))*0.1 - 0.05
}
frameNum := 0
for !rl.WindowShouldClose() {
frameNum++
// initial transform by halfway again through angle array
angleIndex := (frameNum / 10) % len(angles)
angle := angles[angleIndex]
initAngle := angles[(angleIndex+len(angles)/2)%len(angles)]
rl.Rotatef(2500*initAngle, 0, 0, 1)
rl.Translatef(100*initAngle, 100*initAngle, 0)
fmt.Printf("%.3f", angle)
rl.EndMode2D()
}
}