0

Given

  1. A set of many points in 3D space
    (each represented as 3 floating-point coordinates (x, y, z))
  2. A set of many infinite lines in 3D space
    (each represented by an arbitary point on the line, and a 3D direction vector)

Is there a way to find out which of the points lie on which of the lines (with a little tolerance to account for floating-point errors), that is more efficient than the trivial O(n²) approach of testing every point against every line in a nested loop?

I'm thinking along the lines of storing one of the two sets in a special data structure that helps with the intersection tests. But what would such a data structure look like?

(Links to relevant academic literature are also appreciated.)

smls
  • 5,478
  • 21
  • 27
  • 1
    You can use a grid or *k*-de tree. This problem is much related to the *ray tracing problem* where one aims to find out where a beam hits an object: http://www.cs.tau.ac.il/~dcor/Graphics/adv-slides/RT_acceleration13.pdf – Willem Van Onsem Oct 13 '19 at 09:08
  • O(n²) is technically wrong unless the numbers of points and line are of the same order. – Yves Daoust Oct 14 '19 at 06:54

2 Answers2

1

This is a complement to Pinhead's answer.

Consider the bounding box of the P points, assumed roughly cubic, and subdivide it in cells. If the spreading of the points is uniform, every cell will contain P/C³ points on average.

Now for every line you will find all the cells it intersects by a process similar to drawing a digital line, and you will intersect on average αC cells, where α is a small constant. Hence the total workload for the search is proportional to L P/C³.

Anyway, you have to account for the initialization time of the grid, proportional to . Hence the total including initialization is of the form C³+ ß L P/C², and is minimized by C~(L P)^(1/5), giving time and space complexity O((L P)^(3/5)), a significant saving over O(L P).


You can also think of a binary tree that contains a hierarchy of bounding spheres, starting from the tolerance radius around each point. You could create the tree in the same way one creates a kD-tree, by recursive subvisions on some dimension.

It is much harder to make precise estimates of the speedup, but you could expect a time complexity like O((L + P) Log(P)).

Yves Daoust
  • 48,767
  • 8
  • 39
  • 84
0

Divide 3d space into cubes of side N, so that a cube can contain more than one point. An infinite line will intersect an infinite amount of cubes, but checking if a cube has a point takes O(1). When a line intersects a cube with more than one point, you only check for the points in that cube, which is going to be smaller than the total size of points if 1) they are evenly distributed 2) you are using amortized constants(Constant Amortized Time). From the perspective of average scenario, you would only check all points at once at O(N^2) if all points are packed inside one cube. You can also have cubes inside the cubes, but that is more bookkeeping.

This idea is inspired by a quadtree: https://en.wikipedia.org/wiki/Quadtree

Ruben Helsloot
  • 10,555
  • 5
  • 17
  • 36