[First commit]
This commit is contained in:
commit
885373889b
|
@ -0,0 +1 @@
|
|||
img/*
|
|
@ -0,0 +1,13 @@
|
|||
package main
|
||||
|
||||
const (
|
||||
screenWidth int = 500
|
||||
screenHeight int = 500
|
||||
windowWidth int = 1000
|
||||
windowHeight int = 1000
|
||||
layerCount int = 3
|
||||
)
|
||||
|
||||
var (
|
||||
function Function = &X1{}
|
||||
)
|
|
@ -0,0 +1,19 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
type X1 struct{}
|
||||
|
||||
func (x *X1) Func(f float64) uint16 {
|
||||
v := (65535 / 2) * (float64(screenHeight+screenWidth) / 2) / f
|
||||
return ToUint16(v)
|
||||
}
|
||||
|
||||
type X2 struct{}
|
||||
|
||||
func (x *X2) Func(f float64) uint16 {
|
||||
v := (math.Sin((float64(screenWidth)*float64(screenHeight))/f) + 1) / 2 * 65535
|
||||
return ToUint16(v)
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
module git.ctdo.de/xoy/xvisuals
|
||||
|
||||
go 1.23.2
|
||||
|
||||
require github.com/hajimehoshi/ebiten/v2 v2.8.1
|
||||
|
||||
require (
|
||||
github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325 // indirect
|
||||
github.com/ebitengine/hideconsole v1.0.0 // indirect
|
||||
github.com/ebitengine/purego v0.8.0 // indirect
|
||||
github.com/jezek/xgb v1.1.1 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325 h1:Gk1XUEttOk0/hb6Tq3WkmutWa0ZLhNn/6fc6XZpM7tM=
|
||||
github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325/go.mod h1:ulhSQcbPioQrallSuIzF8l1NKQoD7xmMZc5NxzibUMY=
|
||||
github.com/ebitengine/hideconsole v1.0.0 h1:5J4U0kXF+pv/DhiXt5/lTz0eO5ogJ1iXb8Yj1yReDqE=
|
||||
github.com/ebitengine/hideconsole v1.0.0/go.mod h1:hTTBTvVYWKBuxPr7peweneWdkUwEuHuB3C1R/ielR1A=
|
||||
github.com/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE=
|
||||
github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.8.1 h1:6n6ZXnbeSCZccdqrH7s9Ut+dll9TEostUqbc72Tis/g=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.8.1/go.mod h1:SXx/whkvpfsavGo6lvZykprerakl+8Uo1X8d2U5aAnA=
|
||||
github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4=
|
||||
github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
||||
golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw=
|
||||
golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
@ -0,0 +1,133 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
"image/png"
|
||||
"log"
|
||||
"math"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
type Game struct {
|
||||
points []*Position
|
||||
preScreens []*ColorArray
|
||||
screen *ebiten.Image
|
||||
pressCountEnter int
|
||||
pressCountSpace int
|
||||
}
|
||||
|
||||
func (g *Game) NewImage() {
|
||||
image := NewColorArray()
|
||||
for i := 0; i < 3; i++ {
|
||||
x, y := rand.Intn(screenHeight), rand.Intn(screenWidth)
|
||||
g.points[i] = &Position{x, y}
|
||||
}
|
||||
for x := 0; x < screenWidth; x++ {
|
||||
for y := 0; y < screenHeight; y++ {
|
||||
c := make([]uint16, 3)
|
||||
for i := 0; i < 3; i++ {
|
||||
p := g.points[i]
|
||||
if p.X != x || p.Y != y {
|
||||
v := math.Abs(p.Dist(&Position{x, y}))
|
||||
c[i] = function.Func(v)
|
||||
} else {
|
||||
c[0] = 65535
|
||||
c[1] = 65535
|
||||
c[2] = 65535
|
||||
break
|
||||
}
|
||||
}
|
||||
image.Set(x, y, color.RGBA64{c[0], c[1], c[2], 255})
|
||||
}
|
||||
}
|
||||
g.preScreens = append(g.preScreens, image)
|
||||
}
|
||||
|
||||
func (gm *Game) Init() {
|
||||
for i := 0; i < layerCount; i++ {
|
||||
gm.NewImage()
|
||||
}
|
||||
|
||||
for x := 0; x < screenWidth; x++ {
|
||||
for y := 0; y < screenHeight; y++ {
|
||||
var r, g, b int64 = 0, 0, 0
|
||||
for i := 0; i < layerCount; i++ {
|
||||
R, G, B, _ := gm.preScreens[i].At(x, y).RGBA()
|
||||
r += int64(R)
|
||||
g += int64(G)
|
||||
b += int64(B)
|
||||
}
|
||||
r /= int64(layerCount)
|
||||
g /= int64(layerCount)
|
||||
b /= int64(layerCount)
|
||||
gm.screen.Set(x, y, color.RGBA64{uint16(r), uint16(g), uint16(b), 65535})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) ReInit() {
|
||||
g.points = make([]*Position, 3)
|
||||
g.preScreens = make([]*ColorArray, 0)
|
||||
g.screen = ebiten.NewImage(screenWidth, screenHeight)
|
||||
g.Init()
|
||||
}
|
||||
|
||||
func NewGame() *Game {
|
||||
gm := &Game{
|
||||
make([]*Position, 3),
|
||||
make([]*ColorArray, 0),
|
||||
ebiten.NewImage(screenWidth, screenHeight),
|
||||
0,
|
||||
0,
|
||||
}
|
||||
gm.Init()
|
||||
return gm
|
||||
}
|
||||
|
||||
func (g *Game) Update() error {
|
||||
if ebiten.IsKeyPressed(ebiten.KeyEnter) && g.pressCountEnter == 0 {
|
||||
file, err := os.Create(strconv.FormatInt(time.Now().Unix(), 10) + ".png")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
err = png.Encode(file, g.screen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
g.pressCountEnter++
|
||||
} else if !ebiten.IsKeyPressed(ebiten.KeyEnter) && g.pressCountEnter > 0 {
|
||||
g.pressCountEnter = 0
|
||||
}
|
||||
|
||||
if ebiten.IsKeyPressed(ebiten.KeySpace) && g.pressCountSpace == 0 {
|
||||
g.ReInit()
|
||||
g.pressCountSpace++
|
||||
} else if !ebiten.IsKeyPressed(ebiten.KeySpace) && g.pressCountSpace > 0 {
|
||||
g.pressCountSpace = 0
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Game) Draw(screen *ebiten.Image) {
|
||||
screen.DrawImage(g.screen, nil)
|
||||
}
|
||||
|
||||
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
||||
return screenWidth, screenHeight
|
||||
}
|
||||
|
||||
func main() {
|
||||
g := NewGame()
|
||||
ebiten.SetWindowSize(windowWidth, windowHeight)
|
||||
ebiten.SetWindowTitle("XVisuals")
|
||||
if err := ebiten.RunGame(g); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
# XVisuals
|
||||
|
||||
Visualization of mathematical formulas.
|
||||
|
||||
## Controls
|
||||
|
||||
| Key | Action |
|
||||
| ----- | ------------------ |
|
||||
| Space | Generate new image |
|
||||
| Enter | Save current image |
|
|
@ -0,0 +1,55 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
"math"
|
||||
)
|
||||
|
||||
type Function interface {
|
||||
Func(float64) uint16
|
||||
}
|
||||
|
||||
type ColorArray struct {
|
||||
img []color.Color
|
||||
}
|
||||
|
||||
func NewColorArray() *ColorArray {
|
||||
ca := &ColorArray{make([]color.Color, screenWidth*screenHeight)}
|
||||
ca.Clear(color.Black)
|
||||
return ca
|
||||
}
|
||||
|
||||
func (ca *ColorArray) Clear(c color.Color) {
|
||||
for i := 0; i < len(ca.img); i++ {
|
||||
ca.img[i] = c
|
||||
}
|
||||
}
|
||||
|
||||
func (ca *ColorArray) At(x, y int) color.Color {
|
||||
position := x + (y * screenHeight)
|
||||
if position > len(ca.img) || position < 0 {
|
||||
return color.Black
|
||||
} else {
|
||||
return ca.img[position]
|
||||
}
|
||||
}
|
||||
|
||||
func (ca *ColorArray) Set(x, y int, c color.Color) {
|
||||
position := x + (y * screenHeight)
|
||||
if position < len(ca.img) && position >= 0 {
|
||||
ca.img[position] = c
|
||||
}
|
||||
}
|
||||
|
||||
type Position struct {
|
||||
X int
|
||||
Y int
|
||||
}
|
||||
|
||||
func (p *Position) Length() float64 {
|
||||
return math.Sqrt(float64(p.X)*float64(p.X) + float64(p.Y)*float64(p.Y))
|
||||
}
|
||||
|
||||
func (p *Position) Dist(P *Position) float64 {
|
||||
return (&Position{p.X - P.X, p.Y - P.Y}).Length()
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
func ToUint16(f float64) uint16 {
|
||||
if f > 65535 {
|
||||
return uint16(math.Mod(f, 65535))
|
||||
} else {
|
||||
return uint16(f)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue