Depth protection on quadtree.

This commit is contained in:
2025-11-30 07:14:00 -05:00
parent f6fead2ddd
commit ba2c798b2e
2 changed files with 21 additions and 14 deletions

View File

@@ -19,7 +19,7 @@ const (
GameHeight = 360
GameParticleCount = 2000
GameGravity = 2
GameParticleRadius = 5
GameParticleRadius = 2.5
GameDamping = .7
GameDeltaTimeStep = 0.5
GameInfluenceRadius = 30
@@ -59,7 +59,7 @@ func NewGame() *Game {
Position: gamedata.Vector{X: GameWidth / 2, Y: GameHeight / 2},
Dimensions: gamedata.Vector{X: GameWidth, Y: GameHeight},
}
g.quadtree = quadtree.New(quad)
g.quadtree = quadtree.New(quad, 0)
vector.FillCircle(g.particlebuff, GameParticleRadius, GameParticleRadius, GameParticleRadius, color.White, true)
@@ -123,8 +123,8 @@ func (g *Game) RenderParticles(img *ebiten.Image) {
for _, particle := range g.particles {
x0 := particle.Position.X - GameParticleRadius
y0 := particle.Position.Y - GameParticleRadius
x0 := particle.Position.X - particle.Radius
y0 := particle.Position.Y - particle.Radius
//redness := float32(particle.Position.Y / g.particlebox.Y)
//blueness := 1 - redness
@@ -344,7 +344,7 @@ func (g *Game) ResolveCollisionsA(particle *elements.Particle) {
//find list of possible maybe collisions, we inspect those in more detail
maybes := g.quadtree.FindAll(quadrant)
sqdist := float64(GameParticleRadius*GameParticleRadius) * 4
sqdist := float64(particle.Radius*particle.Radius) * 4
for _, p := range maybes {
if p == particle {
@@ -368,7 +368,7 @@ func (g *Game) ResolveCollisionsA(particle *elements.Particle) {
if dist2 < sqdist {
d := math.Sqrt(dist2)
nx, ny := delta.X/d, delta.Y/d
overlap := GameParticleRadius*2 - d
overlap := particle.Radius*2 - d
pos.X += nx * overlap
pos.Y += ny * overlap
@@ -394,7 +394,7 @@ func (g *Game) ResolveCollisionsB(particle *elements.Particle) {
//find list of possible maybe collisions, we inspect those in more detail
maybes := g.quadtree.FindAll(quadrant)
sqdist := float64(GameParticleRadius*GameParticleRadius) * 4
sqdist := float64(particle.Radius*particle.Radius) * 4
for _, p := range maybes {
if p == particle {
@@ -411,7 +411,7 @@ func (g *Game) ResolveCollisionsB(particle *elements.Particle) {
if dist2 < sqdist {
d := math.Sqrt(dist2)
overlap := GameParticleRadius*2 - d
overlap := particle.Radius*2 - d
theta := math.Atan2(delta.Y, delta.X)
pos.X += overlap * math.Cos(theta)
pos.Y += overlap * math.Sin(theta)

View File

@@ -6,6 +6,7 @@ import (
)
const (
QuadtreeMaxDepth = 20
QuadtreeMaxColliders = 40
)
@@ -18,11 +19,13 @@ type Quadtree struct {
quadrant Quadrant
children []*Quadtree
colliders []colliders.Collider
depth int
}
func New(quadrant Quadrant) *Quadtree {
func New(quadrant Quadrant, depth int) *Quadtree {
qt := &Quadtree{
quadrant: quadrant,
depth: depth,
}
return qt
}
@@ -101,12 +104,16 @@ func (q *Quadtree) SubdivideAndInsert(obj colliders.Collider) bool {
var result bool = false
//initialize up children
if q.depth+1 > QuadtreeMaxDepth {
return result
}
//initialize children
q.children = q.children[:0]
q.children = append(q.children, New(Quadrant{Position: gamedata.Vector{X: q.quadrant.Position.X - q.quadrant.Dimensions.X/4, Y: q.quadrant.Position.Y - q.quadrant.Dimensions.Y/4}, Dimensions: gamedata.Vector{X: q.quadrant.Dimensions.X / 2, Y: q.quadrant.Dimensions.Y / 2}}))
q.children = append(q.children, New(Quadrant{Position: gamedata.Vector{X: q.quadrant.Position.X + q.quadrant.Dimensions.X/4, Y: q.quadrant.Position.Y - q.quadrant.Dimensions.Y/4}, Dimensions: gamedata.Vector{X: q.quadrant.Dimensions.X / 2, Y: q.quadrant.Dimensions.Y / 2}}))
q.children = append(q.children, New(Quadrant{Position: gamedata.Vector{X: q.quadrant.Position.X - q.quadrant.Dimensions.X/4, Y: q.quadrant.Position.Y + q.quadrant.Dimensions.Y/4}, Dimensions: gamedata.Vector{X: q.quadrant.Dimensions.X / 2, Y: q.quadrant.Dimensions.Y / 2}}))
q.children = append(q.children, New(Quadrant{Position: gamedata.Vector{X: q.quadrant.Position.X + q.quadrant.Dimensions.X/4, Y: q.quadrant.Position.Y + q.quadrant.Dimensions.Y/4}, Dimensions: gamedata.Vector{X: q.quadrant.Dimensions.X / 2, Y: q.quadrant.Dimensions.Y / 2}}))
q.children = append(q.children, New(Quadrant{Position: gamedata.Vector{X: q.quadrant.Position.X - q.quadrant.Dimensions.X/4, Y: q.quadrant.Position.Y - q.quadrant.Dimensions.Y/4}, Dimensions: gamedata.Vector{X: q.quadrant.Dimensions.X / 2, Y: q.quadrant.Dimensions.Y / 2}}, q.depth+1))
q.children = append(q.children, New(Quadrant{Position: gamedata.Vector{X: q.quadrant.Position.X + q.quadrant.Dimensions.X/4, Y: q.quadrant.Position.Y - q.quadrant.Dimensions.Y/4}, Dimensions: gamedata.Vector{X: q.quadrant.Dimensions.X / 2, Y: q.quadrant.Dimensions.Y / 2}}, q.depth+1))
q.children = append(q.children, New(Quadrant{Position: gamedata.Vector{X: q.quadrant.Position.X - q.quadrant.Dimensions.X/4, Y: q.quadrant.Position.Y + q.quadrant.Dimensions.Y/4}, Dimensions: gamedata.Vector{X: q.quadrant.Dimensions.X / 2, Y: q.quadrant.Dimensions.Y / 2}}, q.depth+1))
q.children = append(q.children, New(Quadrant{Position: gamedata.Vector{X: q.quadrant.Position.X + q.quadrant.Dimensions.X/4, Y: q.quadrant.Position.Y + q.quadrant.Dimensions.Y/4}, Dimensions: gamedata.Vector{X: q.quadrant.Dimensions.X / 2, Y: q.quadrant.Dimensions.Y / 2}}, q.depth+1))
//move colliders into child nodes
var failed bool = false