Intersection of a line by an Axis-Aligned Bounding Box.

line_AABB(orig, end, AABB_min, AABB_max)

Arguments

orig

A data.table with the describing *XYZ* coordinates of the the start path of a line.

end

A data.table with the describing *XYZ* coordinates of the the end path of a line.

AABB_min

A numeric vector with the minimum *XYZ* coordinates of the AABB

AABB_max

A numeric vector with the maximum *XYZ* coordinates of the AABB.

Value

An numeric vector of length two, describing if the line was intercepted or not, and the length of the intercepted line within in the AABB. See details.

Details

The interaction of a line with a AABB may result in five scenarios: i) the line is not intercepted by a AAABB (0), ii) the origin and end of the line falls within the AABB (1), iii) the origin point of the line falls within the AABB both not the end point (2), iv) the end point of the line falls within the AABB both not the origin point (3), and v) the line is intercepted by the AABB (4).

Author

J. Antonio Guzmán Q.

Examples


#Create origins and end paths
orig <- data.table(X = c(0, 0, 0, 0, 0),
                   Y = c(-0.45, -0.25, 0, 0.25, 0.45),
                   Z = c(-1, -0.25, 0, -1, -1))

end <- data.table(X = c(0, 0, 0, 0, 0),
                  Y = c(-0.45, -0.25, 0, 0.25, 0.45),
                  Z = c(-0.75, 0.25, 1, 0, 1))

#Create the AABB
AABB <- matrix(c(0, 0, 0), ncol = 3)
edge_length <- c(1, 1, 1)

AABB_min <- c(AABB[1, 1] - edge_length[1]/2,
              AABB[1, 2] - edge_length[2]/2,
              AABB[1, 3] - edge_length[3]/2)

AABB_max <- c(AABB[1, 1] + edge_length[1]/2,
              AABB[1, 2] + edge_length[2]/2,
              AABB[1, 3] + edge_length[3]/2)

#Plot
cube <- rgl::cube3d()
cube <- rgl::scale3d(cube, edge_length[1]/2,
                           edge_length[2]/2,
                           edge_length[3]/2)
box <- rgl::translate3d(cube, AABB[1, 1], AABB[1, 2], AABB[1, 3])
rgl::shade3d(box, col= "green", alpha = 0.6)
rgl::points3d(orig, size = 4, col = "black")
rgl::points3d(end, size = 4, col = "red")

#Line no intercepted
rgl::lines3d(c(orig[1, 1], end[1, 1]),
             c(orig[1, 2], end[1, 2]),
             c(orig[1, 3], end[1, 3]), col = "grey")

line_AABB(orig[1,], end[1,], AABB_min, AABB_max)
#>   code length 
#>      0      0 

#Both ends falls inside
rgl::lines3d(c(orig[2, 1], end[2, 1]),
             c(orig[2, 2], end[2, 2]),
             c(orig[2, 3], end[2, 3]), col = "red")

line_AABB(orig[2,], end[2,], AABB_min, AABB_max)
#>   code length 
#>    1.0    0.5 

#Oring falls inside, but not the end.
rgl::lines3d(c(orig[3, 1], end[3, 1]),
             c(orig[3, 2], end[3, 2]),
             c(orig[3, 3], end[3, 3]), col = "blue")

line_AABB(orig[3,], end[3,], AABB_min, AABB_max)
#>   code length 
#>    2.0    0.5 

#End falls inside, but not the orig
rgl::lines3d(c(orig[4, 1], end[4, 1]),
             c(orig[4, 2], end[4, 2]),
             c(orig[4, 3], end[4, 3]), col = "green")

line_AABB(orig[4,], end[4,], AABB_min, AABB_max)
#>   code length 
#>    3.0    0.5 

#Some segments of the line are intercepted
rgl::lines3d(c(orig[5, 1], end[5, 1]),
             c(orig[5, 2], end[5, 2]),
             c(orig[5, 3], end[5, 3]), col = "black")
line_AABB(orig[5,], end[5,], AABB_min, AABB_max) #> code length #> 4 1