instructions
The intersection of a line and a sphere can be solved not only geometrically but also algebraically, that is, by solving a quadratic equation of one variable.
equation
The solution of the quadratic equation is relatively simple, and the formula can be directly applied to solve the problem:So, the final point of intersection is actually 0P + t * d
. Whether t exists, that is, whether it intersects, needs to be judged according to the discriminant of the root formula of the quadratic equation of one variable:If the discriminant is greater than 0, there are two points of intersection; Equals 0, an intersection (tangent); Less than 0, no intersection.
Algebraic methods, which essentially replace vector normalization with squares, are theoretically more accurate.
code
static func isIntersection(line:Line.sphere:Sphere) -> Bool {
let vector = line.position - sphere.position
let a = length_squared(line.direction)
let b = dot(line.direction, vector)
let c = length_squared(vector) - sphere.radius * sphere.radius
let discriminant = b * b - 4 * a * c
return discriminant > = 0
}
static func intersectionPoint(line:Line.sphere:Sphere) -> (simd_float3, simd_float3)? {
let vector = line.position - sphere.position
let a = length_squared(line.direction)
let b = dot(line.direction, vector)
let c = length_squared(vector) - sphere.radius * sphere.radius
let discriminant = b * b - 4 * a * c
if discriminant < 0 {
return nil
}
let x = sqrtf(discriminant)
let t1 = (-b + x)/(2*a)
let t2 = (-b - x)/(2*a)
let point1 = line.position + t1 * line.direction
let point2 = line.position + t2 * line.direction
return (point1, point2)
}
Copy the code