Where the ray (origin, unit dir) meets the sphere of center and
radius: the distances along the ray of where it enters and leaves
(near <= far; near < 0 if the origin is inside). False if it
misses, or the sphere is behind.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | origin(3) |
the ray (dir: a unit vector) |
||
| real(kind=wp), | intent(in) | :: | dir(3) |
the ray (dir: a unit vector) |
||
| real(kind=wp), | intent(in) | :: | center(3) |
the sphere's center |
||
| real(kind=wp), | intent(in) | :: | radius |
its radius (> 0) |
||
| real(kind=wp), | intent(out) | :: | near |
distances along the ray (huge() if missed) |
||
| real(kind=wp), | intent(out) | :: | far |
distances along the ray (huge() if missed) |
logical function ray_sphere(origin, dir, center, radius, near, far) result(hit) real(wp), intent(in) :: origin(3), dir(3) !! the ray (dir: a unit vector) real(wp), intent(in) :: center(3) !! the sphere's center real(wp), intent(in) :: radius !! its radius (> 0) real(wp), intent(out) :: near, far !! distances along the ray (huge() if missed) real(wp) :: o(3), b, c, disc hit = .false. near = huge(1.0_wp) far = huge(1.0_wp) if (radius <= 0.0_wp) return o = origin - center b = dot_product(o, dir) c = dot_product(o, o) - radius * radius disc = b * b - c if (disc < 0.0_wp) return if (-b + sqrt(disc) < 0.0_wp) return near = -b - sqrt(disc) far = -b + sqrt(disc) hit = .true. end function ray_sphere