Skip to content

ray_box_intersect

ray_box_intersect(origin, dir, center, width)

Find if and where a straight line intersects an axis-aligned box

Parameters:

Name Type Description Default
origin (dim,) numpy double array

Ray origin position coordinates

required
dir (dim,) numpy double array

Ray origin direction coordinates

required
center (dim,) numpy double array

Box center coordinates

required
width (dim,) numpy double array

Box widths in each dimension

required

Returns:

Name Type Description
is_hit bool

Whether the ray ever hits the box

hit_coord (dim,) numpy double array

Intersection coordinates (one of them, there may be many). Some entries of this vector will be infinite if is_hit is False.

See Also

ray_polyline_intersect, ray_mesh_intersect.

Notes

Uses the algorithm described in "Graphics Gems" by Eric Haines. Note that this will check intersections through the whole straight line, e.g., for positive and negative time values.

Examples:

from gpytoolbox import ray_box_intersect
center = np.array([0,0])
width = np.array([1,1])
position = np.array([-1,0])
dir = np.array([1.0,0.1])
is_hit,where_hit = gpytoolbox.ray_box_intersect(position,dir,center,width)
Source code in src/gpytoolbox/ray_box_intersect.py
 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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
def ray_box_intersect(origin,dir,center,width):
    """Find if and where a straight line intersects an axis-aligned box

    Parameters
    ----------
    origin : (dim,) numpy double array
        Ray origin position coordinates
    dir : (dim,) numpy double array
        Ray origin direction coordinates
    center : (dim,) numpy double array
        Box center coordinates
    width : (dim,) numpy double array
        Box widths in each dimension

    Returns
    -------
    is_hit : bool
        Whether the ray ever hits the box
    hit_coord : (dim,) numpy double array
        Intersection coordinates (one of them, there may be many). Some entries of this vector will be infinite if is_hit is False.

    See Also
    --------
    ray_polyline_intersect, ray_mesh_intersect.

    Notes
    -----
    Uses the algorithm described in "Graphics Gems" by Eric Haines. Note that this will check intersections through the whole straight line, e.g., for positive and negative time values.

    Examples
    --------
    ```python
    from gpytoolbox import ray_box_intersect
    center = np.array([0,0])
    width = np.array([1,1])
    position = np.array([-1,0])
    dir = np.array([1.0,0.1])
    is_hit,where_hit = gpytoolbox.ray_box_intersect(position,dir,center,width)
    ```
    """
    assert(np.ndim(origin)==1)
    dim = origin.shape[0]
    inside = True
    quadrant = -np.ones(dim)
    maxT = -np.ones(dim)
    candidatePlane = -np.ones(dim)
    whichPlane = 0
    minB = center - 0.5*width
    maxB = center + 0.5*width
    hit_coord = np.inf*np.ones(dim)

    for i in range(dim):
        if (origin[i]<minB[i]):
            quadrant[i] = 1
            candidatePlane[i] = minB[i]
            inside = False
        elif (origin[i]>maxB[i]):
            quadrant[i] = 0
            candidatePlane[i] = maxB[i]
            inside = False
        else:
            quadrant[i] = 2


    if inside:
        hit_coord = origin
        return True, hit_coord

    for i in range(dim):
        if ( (quadrant[i]!=2) and  (dir[i]!=0.) ):
            maxT[i] = (candidatePlane[i]-origin[i]) / dir[i]
        else:
            maxT[i] = -1.

    whichPlane = 0
    for i in range(dim):
        if (maxT[whichPlane] < maxT[i]):
            whichPlane = i

    if (maxT[whichPlane] < 0.):
        return False, hit_coord

    for i in range(dim):
        if (whichPlane != i):
            hit_coord[i] = origin[i] + maxT[whichPlane]*dir[i]
            if ( (hit_coord[i] < minB[i]) or (hit_coord[i] > maxB[i])):
                return False, hit_coord
        else:
            hit_coord[i] = candidatePlane[i]

    return True, hit_coord