The point of the line through point along axis closest to the ray
(origin, unit dir): its parameter s (the point is point + s * axis,
axis normalized) and the point. False if the ray and the line are
parallel (within 1e-6 of it, as a sine squared), or the closest point
of the ray is behind its origin.
| 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) | :: | point(3) |
the line (axis: any length but 0) |
||
| real(kind=wp), | intent(in) | :: | axis(3) |
the line (axis: any length but 0) |
||
| real(kind=wp), | intent(out) | :: | s |
along the line (scene units, from |
||
| real(kind=wp), | intent(out) | :: | line_point(3) |
the point of the line |
logical function ray_line(origin, dir, point, axis, s, line_point) result(hit) real(wp), intent(in) :: origin(3), dir(3) !! the ray (dir: a unit vector) real(wp), intent(in) :: point(3), axis(3) !! the line (axis: any length but 0) real(wp), intent(out) :: s !! along the line (scene units, from `point`) real(wp), intent(out) :: line_point(3) !! the point of the line real(wp) :: u(3), w(3), b, d, e, denom hit = .false. s = 0.0_wp line_point = point if (norm2(axis) <= 0.0_wp) return u = axis / norm2(axis) w = point - origin b = dot_product(u, dir) d = dot_product(u, w) e = dot_product(dir, w) denom = 1.0_wp - b * b if (denom < 1.0e-6_wp) return s = (b * e - d) / denom if ((e + b * s) < 0.0_wp) return ! (the ray's closest point: origin + (e + b s) dir) line_point = point + s * u hit = .true. end function ray_line