This commit is contained in:
silva guimaraes 2023-08-18 01:19:22 -03:00
parent f88f7f9d12
commit 110141ae44

152
main.go
View file

@ -17,12 +17,70 @@ import (
) )
type quadnode struct {
topleft, bottomright rl.Vector2
magnet *magnet
parent *quadnode
nodes []*quadnode
}
func newQuadTree() *quadnode {
return &quadnode{
topleft: rl.NewVector2(0, 0),
bottomright: rl.NewVector2(windowWidth, windowHeight),
nodes: nil,
}
}
func (q *quadnode) subdivide() {
halfX := q.bottomright.X/2
halfY := q.bottomright.X/2
q.nodes = []*quadnode{
{
topleft: q.topleft,
bottomright: rl.Vector2{X: halfX, Y: halfY},
parent: q,
},
{
topleft: rl.Vector2{X: halfX, Y: q.topleft.Y},
bottomright: rl.Vector2{X: q.bottomright.X, Y: halfY},
parent: q,
},
{
topleft: rl.Vector2{X: q.topleft.X, Y: halfY},
bottomright: rl.Vector2{X: halfX, Y: q.bottomright.Y},
parent: q,
},
{
topleft: rl.Vector2{X: halfX, Y: halfY},
bottomright: q.bottomright,
parent: q,
},
}
}
func (q *quadnode) drawBoundaries() {
if q.nodes == nil {
return
}
for _, node := range q.nodes {
node.drawBoundaries()
size := rl.Vector2Subtract(node.bottomright, node.topleft)
rl.DrawRectangleLines(
int32(node.topleft.X), int32(node.topleft.Y),
int32(size.X), int32(size.Y),
rl.Green,
)
}
}
type magnet struct { type magnet struct {
pos rl.Vector2 pos rl.Vector2
speed rl.Vector2 speed rl.Vector2
color rl.Color color rl.Color
// force float32 mass float32
// radius float32 radius float32
} }
// type ball struct { // type ball struct {
@ -34,15 +92,40 @@ type magnet struct {
// } // }
// parâmetros // parâmetros
const initalMagnetCount = 100 const initalMagnetCount = 10
const windowWidth = 700 const windowWidth = 700
const windowHeight = 700 const windowHeight = 700
const magnetRadius = 5 const magnetRadius = 5
const gravConst float32 = 10 const gravConst float32 = 10
// func insideArea(pos rl.Vector2) (bool, bool) { func tick(magnets []*magnet) {
// return pos.X > 0 && pos.X < windowWidth, pos.Y > 0 && pos.Y < windowHeight
// } for _, a := range magnets {
for _, b := range magnets {
if a == b { continue }
// não creio que isso esteja certo porem isso quaqueja que nem um pato
direction := rl.Vector2Normalize(rl.Vector2Subtract(a.pos, b.pos))
distance := rl.Vector2Distance(a.pos, b.pos)
distanceSquared := math.Pow(float64(distance), 2)
force := gravConst / float32(distanceSquared)
acceleration := rl.Vector2Scale(direction, force)
if distance < magnetRadius*2 {
continue
}
// f = m * a
forceA := rl.Vector2Scale(acceleration, a.mass)
forceB := rl.Vector2Scale(acceleration, b.mass)
a.speed = rl.Vector2Add(a.speed, rl.Vector2Negate(forceB))
b.speed = rl.Vector2Add(b.speed, forceA)
}
}
for _, magnet := range magnets {
magnet.pos = rl.Vector2Add(magnet.pos, magnet.speed)
}
}
func (m *magnet) update(magnets []*magnet) { func (m *magnet) update(magnets []*magnet) {
magnetsPull := rl.Vector2{} magnetsPull := rl.Vector2{}
@ -52,9 +135,9 @@ func (m *magnet) update(magnets []*magnet) {
direction := rl.Vector2Normalize(rl.Vector2Subtract(m.pos, magnet.pos)) direction := rl.Vector2Normalize(rl.Vector2Subtract(m.pos, magnet.pos))
distance := rl.Vector2Distance(magnet.pos, m.pos) distance := rl.Vector2Distance(magnet.pos, m.pos)
if (distance < magnetRadius*2) { if (distance < magnetRadius*2 + 10) {
// direction = rl.Vector2Negate(direction) direction = rl.Vector2Negate(direction)
continue // continue
} }
distanceSquared := math.Pow(float64(distance), 2) distanceSquared := math.Pow(float64(distance), 2)
force := gravConst / float32(distanceSquared) force := gravConst / float32(distanceSquared)
@ -74,28 +157,30 @@ func (m *magnet) update(magnets []*magnet) {
m.pos = newPos m.pos = newPos
} }
func randomMagnet() *magnet { func newMagnet(x, y, mass float32) *magnet {
newMagnet := magnet{ newMagnet := magnet{
pos: rl.Vector2{ pos: rl.Vector2{X: x, Y: y},
X: float32(rand.Intn(windowWidth - 100) + 50),
Y: float32(rand.Intn(windowHeight - 100) + 50),
},
color: rl.NewColor( color: rl.NewColor(
uint8(rand.Int()), uint8(rand.Int()),
uint8(rand.Int()), uint8(rand.Int()),
uint8(rand.Int()), uint8(rand.Int()),
255, 255,
), ),
mass: mass,
radius: mass,
} }
return &newMagnet return &newMagnet
} }
func createMagnets(n int) []*magnet { func randomMagnets(n int) []*magnet {
var magnets []*magnet var magnets []*magnet
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
magnets = append(magnets, randomMagnet()) x := float32(rand.Intn(windowWidth - 100) + 50)
y := float32(rand.Intn(windowHeight - 100) + 50)
magnets = append(magnets, newMagnet(x, y, 1))
} }
return magnets return magnets
} }
@ -107,29 +192,48 @@ func main() {
defer rl.CloseWindow() defer rl.CloseWindow()
rl.SetTargetFPS(60) rl.SetTargetFPS(60)
magnets := createMagnets(initalMagnetCount) magnets := randomMagnets(initalMagnetCount)
quadtree := newQuadTree()
quadtree.subdivide()
pause := true
for !rl.WindowShouldClose() { for !rl.WindowShouldClose() {
rl.BeginDrawing() rl.BeginDrawing()
rl.ClearBackground(rl.Black) rl.ClearBackground(rl.Black)
rl.DrawFPS(0, 0) rl.DrawFPS(0, 0)
// func rl.DrawText(text string, posX int32, posY int32, fontSize int32, col color.RGBA)
rl.DrawText(strconv.Itoa(len(magnets)), 0, 20, 20, rl.White) rl.DrawText(strconv.Itoa(len(magnets)), 0, 20, 20, rl.White)
if pause {
rl.DrawText("pausado (E)", 0, 40, 20, rl.White)
}
{ {
if rl.IsKeyPressed(rl.KeyR) { if rl.IsKeyPressed(rl.KeyR) {
magnets = createMagnets(len(magnets)) magnets = randomMagnets(initalMagnetCount)
} }
if rl.IsKeyPressed(rl.KeyW) { if rl.IsKeyPressed(rl.KeyW) {
magnets = append(magnets, createMagnets(100)...) magnets = append(magnets, randomMagnets(100)...)
}
if rl.IsKeyPressed(rl.KeyE) {
pause = !pause
}
if rl.IsKeyPressed(rl.KeySpace) {
mouse := rl.GetMousePosition()
magnets = append(magnets, newMagnet(mouse.X, mouse.Y, 50))
} }
} }
if !pause {
tick(magnets)
}
quadtree.drawBoundaries()
for _, magnet := range magnets { for _, magnet := range magnets {
magnet.update(magnets) rl.DrawCircleV(magnet.pos, magnet.radius+1, rl.White)
rl.DrawCircleV(magnet.pos, magnetRadius+1, rl.White) rl.DrawCircleV(magnet.pos, magnet.radius, magnet.color)
rl.DrawCircleV(magnet.pos, magnetRadius, magnet.color)
} }
rl.EndDrawing() rl.EndDrawing()