Files
old-9heroja/collision/types.go
2023-12-28 14:42:20 +01:00

89 lines
1.8 KiB
Go

package collision
type Point struct {
X float64
Y float64
}
type Polygon struct {
Points []Point
}
type ObjectType int
const (
Hero ObjectType = 1 << iota
Zombie
Bullet
)
type Collidable interface {
CollisionShape() Polygon
HandleCollisionEvent(other Collidable)
CollisionObjectType() ObjectType
}
// Helper function to calculate the dot product of two points
func dot(p1, p2 Point) float64 {
return p1.X*p2.X + p1.Y*p2.Y
}
// Helper function to get the normal of the edge between two points
func edgeNormal(p1, p2 Point) Point {
return Point{X: p2.Y - p1.Y, Y: p1.X - p2.X}
}
// Project a polygon onto an axis and return the min and max projections
func projectPolygon(axis Point, polygon Polygon) (float64, float64) {
min := dot(axis, polygon.Points[0])
max := min
for _, p := range polygon.Points[1:] {
projection := dot(axis, p)
if projection < min {
min = projection
}
if projection > max {
max = projection
}
}
return min, max
}
// Check if two projections on an axis overlap
func overlap(minA, maxA, minB, maxB float64) bool {
if minA > maxB || minB > maxA {
return false
}
return true
}
// Overlaps checks if two polygons overlap using the Separating Axis Theorem
func (p Polygon) Overlaps(p2 Polygon) bool {
if len(p.Points) == 0 || len(p2.Points) == 0 {
return false
}
for i := 0; i < len(p.Points); i++ {
next := (i + 1) % len(p.Points)
axis := edgeNormal(p.Points[i], p.Points[next])
minA, maxA := projectPolygon(axis, p)
minB, maxB := projectPolygon(axis, p2)
if !overlap(minA, maxA, minB, maxB) {
return false
}
}
for i := 0; i < len(p2.Points); i++ {
next := (i + 1) % len(p2.Points)
axis := edgeNormal(p2.Points[i], p2.Points[next])
minA, maxA := projectPolygon(axis, p)
minB, maxB := projectPolygon(axis, p2)
if !overlap(minA, maxA, minB, maxB) {
return false
}
}
return true
}