You can take the bounding box from the polygon (min-max x, y coordinates) and build a grid inside the box. Then for each cell, remember all the lines that intersect the cell.
Find such an intuition:
- Find out which cell the ray hits (O (1))
- Use the grid traversal algorithm to “draw” a ray through the grid. When you click on a non-empty cell, check all its rows, check if the intersection is inside the cell and select the nearest intersection. If all intersections are outside the cell, continue (this is O (grid length)).
You can also make the grid hierarchical (i.e. quadtree is the tree you requested) and go through it using the same algorithm. This is done in raytracing in 3D , and the time complexity is O (sqrt (N)).
Or, use the approach I did in my raytracer:
- Create a quadtree containing strings (building a quadtree is described in the article) - you separate nodes (= areas) if they contain too many objects on 4 sub-nodes (sub-areas)
Collect all the leaf quadrant nodes that fall on the beam:
Calculate the rectangular intersection of the rectangle (not difficult) for the root. If the root hits the beam, continue it recursively.
The great thing is that when the node tree didn’t hit, you skipped processing the entire subtree (a potentially large rectangular area).
In the end, this is equivalent to crossing the grid - you collect the smallest cells in the path of the beam, and then check all the objects in them for intersection. You just need to check everything and choose the nearest intersection (so that you explore all the lines in the path of the beam).
This is O (sqrt (N)).
When traversing the grid, when you find the intersection, you can stop the search. To achieve this by using the quadrant traversal, you will need to find the children in the correct order - either collect 4 direct intersections by distance, or deftly walk along a 4-element grid (we will return to the traversal).
This is just another approach, relatively difficult to implement, I think, and works well (I tested it on real data - O (sqrt (N))). Again, you would benefit from this approach, if you have at least a couple of lines, when the polygon has 10 edges, the advantage compared to just testing all of them will be small, I think.
source share