-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcircle_circle_sweep2.go
More file actions
49 lines (45 loc) · 1.15 KB
/
circle_circle_sweep2.go
File metadata and controls
49 lines (45 loc) · 1.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package coll
import (
"math"
"github.com/setanarut/v"
)
// CircleCircleSweep2 checks for collision between two moving circles to prevent tunneling.
//
// Returns true if collision occurs during movement or if they are already overlapping.
//
// If h is not nil and a collision is detected, it will be populated with:
// - Normal: Collision surface normal for c2
// - Data: Normalized time of impact (0.0 to 1.0) along the movement path
func CircleCircleSweep2(c1, c2 *Circle, deltaC1, deltaC2 v.Vec, h *Hit) bool {
rSum := c1.Radius + c2.Radius
rSumSq := rSum * rSum
pDiff := c2.Pos.Sub(c1.Pos)
if pDiff.MagSq() <= rSumSq {
if h != nil {
h.Data = 0.0
h.Normal = pDiff.Unit().Neg()
}
return true
}
relDelta := deltaC2.Sub(deltaC1)
a := relDelta.MagSq()
if a < Epsilon {
return false
}
b := 2.0 * pDiff.Dot(relDelta)
c := pDiff.MagSq() - rSumSq
discriminant := b*b - 4.0*a*c
if discriminant < 0.0 {
return false
}
sqrtDisc := math.Sqrt(discriminant)
t1 := (-b - sqrtDisc) / (2.0 * a)
if t1 >= 0.0 && t1 <= 1.0 {
if h != nil {
h.Data = t1
h.Normal = pDiff.Add(relDelta.Scale(t1)).Unit().Neg()
}
return true
}
return false
}