-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathline_circle_overlap.go
More file actions
37 lines (32 loc) · 1.11 KB
/
line_circle_overlap.go
File metadata and controls
37 lines (32 loc) · 1.11 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
package coll
import (
"math"
)
// LineCircleOverlap checks if the infinite line defined by the given raySeg intersects with a circle.
// Return true if the infinite line passes through the circle
// This function treats 'raySeg' as a line extending infinitely in both directions
//
// Parameters:
// - raySeg: Defines the trajectory (slope and position) of the infinite line.
// - c: The Circle struct to test against.
// - result: If non-nil and an intersection occurs, this is populated with the
// two intersection points along the infinite line.
func LineCircleOverlap(raySeg *Segment, c *Circle, result *Segment) bool {
dp := raySeg.B.Sub(raySeg.A)
dAPos := raySeg.A.Sub(c.Pos)
a := dp.MagSq()
b := 2 * dp.Dot(dAPos)
cr := dAPos.MagSq() - c.Radius*c.Radius
bb4ac := b*b - 4*a*cr
if math.Abs(a) < Epsilon || bb4ac < 0 {
return false
}
if result != nil {
sqrtBB4AC := math.Sqrt(bb4ac)
invA2 := 1.0 / (2 * a)
negB := -b
result.A = raySeg.A.Add(raySeg.B.Sub(raySeg.A).Scale((negB + sqrtBB4AC) * invA2))
result.B = raySeg.A.Add(raySeg.B.Sub(raySeg.A).Scale((negB - sqrtBB4AC) * invA2))
}
return true
}