Files
PartikelSim/main.go
T
2026-05-10 20:38:11 +02:00

183 lines
6.5 KiB
Go

package main
import (
"sync"
"time"
rl "github.com/gen2brain/raylib-go/raylib"
)
const MAXPOINTS = 100000
const MAXOBSTACLES = 20
const PI = 3.141592653589793
type quad struct {
lu rl.Vector2
ru rl.Vector2
rd rl.Vector2
ld rl.Vector2
}
func spawnParticlesAsGrid(particleWidth float32, particleHeight float32, particleColumnCount int, particleRowCount int, particleList *[MAXPOINTS]rl.Vector2) {
var particleLeftCornerPos rl.Vector2 = rl.Vector2{500, 200}
for y := 0; y < (particleColumnCount); y++ {
for x := 0; x < particleRowCount; x++ {
newParticle := rl.NewVector2(particleWidth*(float32(x)/float32(particleRowCount))+particleLeftCornerPos.X, particleHeight*(float32(y)/float32(particleColumnCount))+particleLeftCornerPos.Y)
particleList[y*particleRowCount+x] = newParticle
}
}
}
func createRectangle(centerPoint rl.Vector2, width float32, height float32, rotation float32) quad {
rectangle := quad{}
rectangle.lu = rl.Vector2Add(
centerPoint,
rl.Vector2Rotate(rl.Vector2{-0.5 * width, -0.5 * height},
rotation))
rectangle.ru = rl.Vector2Add(
centerPoint,
rl.Vector2Rotate(rl.Vector2{0.5 * width, -0.5 * height},
rotation))
rectangle.rd = rl.Vector2Add(
centerPoint,
rl.Vector2Rotate(rl.Vector2{0.5 * width, 0.5 * height},
rotation))
rectangle.ld = rl.Vector2Add(
centerPoint,
rl.Vector2Rotate(rl.Vector2{-0.5 * width, 0.5 * height},
rotation))
return rectangle
}
func drawRec(rectangle *quad) {
rl.DrawLineV((*rectangle).lu, (*rectangle).ru, rl.Black)
rl.DrawLineV((*rectangle).ru, (*rectangle).rd, rl.Black)
rl.DrawLineV((*rectangle).rd, (*rectangle).ld, rl.Black)
rl.DrawLineV((*rectangle).ld, (*rectangle).lu, rl.Black)
}
func obstacleReflect(particlePos rl.Vector2, particleSpeed *rl.Vector2, obstacles *([MAXOBSTACLES](*quad)), particleRadius *float32, obstacleCount *int) {
for k := 0; k < *obstacleCount; k++ {
if rl.CheckCollisionCircleLine(particlePos, *particleRadius, (*((*obstacles)[k])).lu, (*((*obstacles)[k])).ru) {
var floorVector rl.Vector2 = rl.Vector2Subtract((*((*obstacles)[k])).ru, (*((*obstacles)[k])).lu)
var normalFloor rl.Vector2 = rl.Vector2Normalize(rl.Vector2Rotate(floorVector, -PI/2))
//var collisionAngle float32 = 2 * rl.Vector2Angle(rl.Vector2Negate(particleSpeed[i]), normalFloor)
*particleSpeed = rl.Vector2Reflect(*particleSpeed, normalFloor)
} else if rl.CheckCollisionCircleLine(particlePos, *particleRadius, (*((*obstacles)[k])).ru, (*((*obstacles)[k])).rd) {
var floorVector rl.Vector2 = rl.Vector2Subtract((*((*obstacles)[k])).rd, (*((*obstacles)[k])).ru)
var normalFloor rl.Vector2 = rl.Vector2Normalize(rl.Vector2Rotate(floorVector, -PI/2))
//var collisionAngle float32 = 2 * rl.Vector2Angle(rl.Vector2Negate(particleSpeed[i]), normalFloor)
*particleSpeed = rl.Vector2Reflect(*particleSpeed, normalFloor)
} else if rl.CheckCollisionCircleLine(particlePos, *particleRadius, (*((*obstacles)[k])).rd, (*((*obstacles)[k])).ld) {
var floorVector rl.Vector2 = rl.Vector2Subtract((*((*obstacles)[k])).ld, (*((*obstacles)[k])).rd)
var normalFloor rl.Vector2 = rl.Vector2Normalize(rl.Vector2Rotate(floorVector, -PI/2))
//var collisionAngle float32 = 2 * rl.Vector2Angle(rl.Vector2Negate(particleSpeed[i]), normalFloor)
*particleSpeed = rl.Vector2Reflect(*particleSpeed, normalFloor)
} else if rl.CheckCollisionCircleLine(particlePos, *particleRadius, (*((*obstacles)[k])).ld, (*((*obstacles)[k])).lu) {
var floorVector rl.Vector2 = rl.Vector2Subtract((*((*obstacles)[k])).lu, (*((*obstacles)[k])).ld)
var normalFloor rl.Vector2 = rl.Vector2Normalize(rl.Vector2Rotate(floorVector, -PI/2))
//var collisionAngle float32 = 2 * rl.Vector2Angle(rl.Vector2Negate(particleSpeed[i]), normalFloor)
*particleSpeed = rl.Vector2Reflect(*particleSpeed, normalFloor)
}
}
}
func physics(particleList *[MAXPOINTS]rl.Vector2, particleCount int, particleListKey *sync.Mutex, obstacles *([MAXOBSTACLES](*quad)), particleRadius *float32, obstacleCount *int) {
var particleSpeed = [MAXPOINTS]rl.Vector2{{0, -300}} //pixel pro Sekunde
var timeIncrement float64 = 0.01
var gravity rl.Vector2 = rl.Vector2{0, 300}
for j := float64(0); j < 50; {
var startTime time.Time = time.Now()
(*particleListKey).Lock()
for i := 0; i < particleCount; i++ {
obstacleReflect((*particleList)[i], &(particleSpeed[i]), obstacles, particleRadius, obstacleCount)
particleList[i] =
rl.Vector2Add(
particleList[i],
rl.Vector2Scale(particleSpeed[i], float32(timeIncrement)))
particleSpeed[i] =
rl.Vector2Add(
particleSpeed[i],
rl.Vector2Scale(gravity, float32(timeIncrement)))
}
(*particleListKey).Unlock()
//fmt.Println(particleList)
j += timeIncrement
var endTime time.Time = time.Now()
var elapsed time.Duration = endTime.Sub(startTime)
var waitTime float64 = timeIncrement - elapsed.Seconds()
rl.WaitTime(waitTime)
println((waitTime / timeIncrement))
//rl.ClearBackground(rl.RayWhite)
}
}
func main() {
rl.InitWindow(1200, 800, "raylib [core] example - basic window")
defer rl.CloseWindow()
rl.SetTargetFPS(120)
rl.BeginDrawing()
rl.WaitTime(1)
rl.ClearBackground(rl.RayWhite)
rl.DrawText("Congrats! You created your first window!", 190, 200, 20, rl.LightGray)
rl.EndDrawing()
var particleWidth float32 = 300
var particleHeight float32 = 200
var particleColumnCount int = 20
var particleRowCount int = 20
var particleCount int = particleRowCount * particleColumnCount
var particleRadius float32 = 5
var particleColor rl.Color = rl.Black
var particleListKey sync.Mutex
var obstacleCount int = 0
//var stepSize float32 = 10
var particleList = [MAXPOINTS]rl.Vector2{}
spawnParticlesAsGrid(particleWidth, particleHeight, particleColumnCount, particleRowCount, &particleList)
var floor quad = createRectangle(rl.Vector2{600, 700}, 1200, 100, 0*PI/8)
var obstacles = [MAXOBSTACLES]*quad{}
obstacles[0] = &floor
obstacleCount++
var hillLeft quad = createRectangle(rl.Vector2{500, 700}, 1200, 100, PI/6)
obstacles[1] = &hillLeft
obstacleCount++
var hillRight quad = createRectangle(rl.Vector2{700, 700}, 1200, 100, -PI/6)
obstacles[2] = &hillRight
obstacleCount++
go physics(&particleList, particleCount, &particleListKey, &obstacles, &particleRadius, &obstacleCount)
for !rl.WindowShouldClose() {
rl.ClearBackground(rl.RayWhite)
particleListKey.Lock()
rl.BeginDrawing()
for i := 0; i < particleCount; i++ {
rl.DrawCircleV(particleList[i], particleRadius, particleColor)
}
particleListKey.Unlock()
drawRec(&floor)
drawRec(&hillLeft)
drawRec(&hillRight)
rl.EndDrawing()
}
}