190 lines
4.1 KiB
Go
190 lines
4.1 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"github.com/gen2brain/raylib-go/raylib"
|
|
"github.com/ojrac/opensimplex-go"
|
|
"math"
|
|
)
|
|
|
|
func clamp01(v float64) float64 {
|
|
if v < 0 {
|
|
return 0
|
|
}
|
|
if v > 1 {
|
|
return 1
|
|
}
|
|
return v
|
|
}
|
|
|
|
func GrayCurve(v, k float64) rl.Color {
|
|
v = math.Pow(clamp01(v), k) // k < 1 boosts highlights, k > 1 boosts shadows
|
|
c := uint8(v * 255)
|
|
return rl.Color{R: c, G: c, B: c, A: 255}
|
|
}
|
|
|
|
func sierpinskiArrow(order int, length float64) {
|
|
rl.Scalef(1, -1, 1)
|
|
//rl.Rotatef(180, 0, 0, 1)
|
|
if order == 0 {
|
|
curve(order, length, 60)
|
|
} else {
|
|
rl.Rotatef(60, 0, 0, 1)
|
|
curve(order, length, -60)
|
|
}
|
|
}
|
|
|
|
func curve(order int, length float64, angle float64) {
|
|
if order == 0 {
|
|
len := int32(length)
|
|
rl.DrawLine(0, 0, len, 0, rl.Black)
|
|
rl.Translatef(float32(len), 0, 0)
|
|
} else {
|
|
curve(order-1, length/2, -angle)
|
|
rl.Rotatef(float32(angle), 0, 0, 1)
|
|
curve(order-1, length/2, angle)
|
|
rl.Rotatef(float32(angle), 0, 0, 1)
|
|
curve(order-1, length/2, -angle)
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
|
|
const (
|
|
screenWidth = 1200
|
|
screenHeight = 700
|
|
snapshotsDir = "snapshots"
|
|
)
|
|
|
|
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.InitWindow(screenWidth, screenHeight, "sumi sierpinski arrow")
|
|
|
|
var camera = rl.Camera2D{
|
|
Target: rl.Vector2{X: 0, Y: 0},
|
|
Offset: rl.Vector2{X: float32(screenWidth) / 2, Y: float32(screenHeight) / 2},
|
|
Rotation: 0,
|
|
Zoom: 1.0,
|
|
}
|
|
|
|
rl.SetTargetFPS(60)
|
|
|
|
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++
|
|
|
|
if rl.IsMouseButtonDown(rl.MouseRightButton) {
|
|
delta := rl.GetMouseDelta()
|
|
delta = rl.Vector2Scale(delta, -1.0/camera.Zoom)
|
|
camera.Target = rl.Vector2Add(camera.Target, delta)
|
|
}
|
|
|
|
// Zoom based on mouse wheel
|
|
wheel := rl.GetMouseWheelMove()
|
|
if wheel != 0 {
|
|
// Get the world point that is under the mouse
|
|
mouseWorldPos := rl.GetScreenToWorld2D(rl.GetMousePosition(), camera)
|
|
|
|
// Set the offset to where the mouse is
|
|
camera.Offset = rl.GetMousePosition()
|
|
|
|
// Set the target to match, so that the camera maps the world space point
|
|
// under the cursor to the screen space point under the cursor at any zoom
|
|
camera.Target = mouseWorldPos
|
|
|
|
// Zoom increment
|
|
const zoomIncrement float32 = 0.125
|
|
|
|
camera.Zoom += (wheel * zoomIncrement)
|
|
if camera.Zoom < zoomIncrement {
|
|
camera.Zoom = zoomIncrement
|
|
}
|
|
}
|
|
|
|
rl.BeginDrawing()
|
|
rl.ClearBackground(rl.RayWhite)
|
|
|
|
rl.BeginMode2D(camera)
|
|
|
|
rl.PushMatrix()
|
|
|
|
/**
|
|
for x := range screenWidth {
|
|
for y := range screenHeight {
|
|
sp := rl.Vector2 { X: float32(x), Y: float32(y) };
|
|
wp := rl.GetScreenToWorld2D(sp, camera);
|
|
normVal := noise.Eval2(float64(wp.X), float64(wp.Y))
|
|
rl.DrawPixelV(wp, GrayCurve(normVal, 0.8));
|
|
}
|
|
}
|
|
**/
|
|
|
|
// initial transform by halfway again through angle array
|
|
|
|
angleIndex := frameNum % 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)
|
|
|
|
stepSize := int32(1)
|
|
for range 1000 {
|
|
rl.DrawLine(0, 0, stepSize, 0, rl.Black)
|
|
rl.Translatef(float32(stepSize), 0, 0)
|
|
rl.Rotatef(angle, 0, 0, 1)
|
|
angleIndex++
|
|
angleIndex = angleIndex % len(angles)
|
|
angle += angles[angleIndex]
|
|
}
|
|
rl.PopMatrix()
|
|
|
|
rl.PushMatrix()
|
|
|
|
//rl.Translatef(-screenWidth/2, screenHeight/2, 0)
|
|
|
|
sierpinskiArrow(9, 800)
|
|
|
|
rl.PopMatrix()
|
|
|
|
/*
|
|
rl.PushMatrix()
|
|
rl.Translatef(0, 25*50, 0)
|
|
rl.Rotatef(90, 1, 0, 0)
|
|
rl.DrawGrid(100, 50)
|
|
rl.PopMatrix()
|
|
*/
|
|
|
|
rl.EndMode2D()
|
|
|
|
if rl.IsKeyDown(rl.KeySpace) {
|
|
if _, err := storage.Save(); err != nil {
|
|
log.Printf("Error saving snapshot: %v\n", err)
|
|
}
|
|
}
|
|
|
|
rl.DrawText("Mouse right button drag to move, mouse wheel to zoom", 10, 10, 20, rl.White)
|
|
|
|
rl.EndDrawing()
|
|
}
|
|
|
|
rl.CloseWindow()
|
|
}
|