0

I'm trying to determine if a line given by two endpoints start = (x, y, z, ...), end = (x, y, z, ...) intersects an n-dimensional cube or rectangle, which I am storing as opposite endpoints bottom_most = (x, y, z, ...), top_most= (x, y, z, ...).

I've found solutions in 3D, but not one that generalizes for n dimensions.

My current solution is:

dimensions = 3


def check_intersects(start, end, cube):
    num_intersections = 0
    for dim in range(dimensions):
        if cube[dim] <= start[dim] <= cube[self.dimensions + dim] or start[dim] <= cube[dim] <= end[dim]:
            num_intersections += 1

    if num_intersections >= dimensions:
        return True

    return False


start, end = (0, 0, 0), (30, 30, 30)
cube = (10, 10, 10, 20, 20, 20)
print(check_intersects(start, end, cube))
start, end = (0, 0, 0), (0, 10, 20)
print(check_intersects(start, end, cube))

but this appears to break down in some cases where the lines come in from certain angles.

Are there any better solutions, or libraries that can do this for me?

Teknophilia
  • 758
  • 10
  • 23

1 Answers1

1

If you think about an axis-aligned 3d cube:

consider the x axis, say (for example) the cube runs from x = 2 to x = 4. So you can think of a "slice" of space bounded by the parallel planes at x = 2 and x = 4;

then consider the y axis, with a "slice" from (say) y = 3 to y = 5; and a slice in z; and (if you are extending this to higher dimensions) a slice in each corresponding dimension;

then you can think of the cube as the intersection of those slices - all points which simultaneously belong to all slices.

If you define any point of the line as

pt = start + k * (end - start)

then for each dimension you can find min_k and max_k where the line enters and leaves that dimension's slice,

but to pass through the (hyper)cube there must be some value of k which simultaneously belongs to all the slices, ie

max(min_k_x, min_k_y, min_k_z, ...) <= min(max_k_x, max_k_y, max_k_z, ...)
Hugh Bothwell
  • 55,315
  • 8
  • 84
  • 99
  • It looks like my issue stems from the direction of the lines. Some of the lines can go "backwards", from right to left, or top to bottom, so some of the axis comparisons won't work. – Teknophilia Jun 10 '17 at 17:06
  • Resolved this by using the corresponding min/max of the start and end. – Teknophilia Jun 10 '17 at 17:25