-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathseg_circle_overlap.go
More file actions
41 lines (33 loc) · 923 Bytes
/
Copy pathseg_circle_overlap.go
File metadata and controls
41 lines (33 loc) · 923 Bytes
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
package coll
import (
"math"
"github.com/setanarut/v"
)
// SegmentCircleOverlap returns the intersection points of a Segment and a Circle.
//
// If the returned slice is nil, there is no intersection.
//
// The length can be 1 or 2. It can be queried with the len() method.
func SegmentCircleOverlap(s *Segment, c *Circle) []v.Vec {
dp := s.B.Sub(s.A)
dAPos := s.A.Sub(c.Pos)
a := dp.MagSq()
b := 2 * dp.Dot(dAPos)
bb4ac := b*b - 4*a*(dAPos.MagSq()-c.Radius*c.Radius)
if math.Abs(a) < Epsilon || bb4ac < 0 {
return nil
}
hitPoints := make([]v.Vec, 0, 2)
sqrtBB4AC := math.Sqrt(bb4ac)
invA2 := 1.0 / (2 * a)
negB := -b
mu1 := (negB + sqrtBB4AC) * invA2
mu2 := (negB - sqrtBB4AC) * invA2
if mu1 >= 0 && mu1 <= 1 {
hitPoints = append(hitPoints, s.A.Add(s.B.Sub(s.A).Scale(mu1)))
}
if mu2 >= 0 && mu2 <= 1 {
hitPoints = append(hitPoints, s.A.Add(s.B.Sub(s.A).Scale(mu2)))
}
return hitPoints
}