Detect collinear points in a 3d points cloud
Show older comments
Lets say we have a random matrix M with N rows and 3 columns (M = randn(N,3)).
I need to detect all the points that are collinear and save the different groups of collinear points
For now here's my idea:
1.I take two points i and i+1 and I browse in the matrix to find the points that are collinear with them
2. If I find collinear points I save their coordinates in a matrix
3. Then I move to the two next set of points i and i+2 and repeat the same idea
It's super slow espeacilly when I use matrix with over 100000 rows. Does anyone have a more optimized approach? Thanks
6 Comments
Bjorn Gustavsson
on 14 Jul 2020
Well, the only thing I can come up with right away is that you should make sure that you only do the necessary tests. That is if you've tested all points for colinearity with point 1 and point 2 you shouldn't do it with point 2 and 1, etc, further if you've found that point l is colinear with points i and j you shouldn't need to do any further tests with points l and i nor with points l and j. There might be additional clever conditions to figure out...
Sleh Eddine Brika
on 14 Jul 2020
John D'Errico
on 14 Jul 2020
ANY two points are collinear. That is, it is meaningless to ask if TWO points are collinear. 3 points are the minimum.
Therefore, if you want to identify sets of three points as collinear, then you would need to check every combination of 3 points, from a set that is roughly 100000 points. So...
nchoosek(100000,3)
ans =
166661666700000
I think I counted the digits there. 166 trillion combinations or so?
If your computer can process 1 million sets of three points per second, that leaves
nchoosek(100000,3)/1e6/60/60/24/365
ans =
5.2848067827245
So around 5 years of CPU time to finish. And, you are surprised this takes a long time? Even if your computer is 10 or 100 times as fast, that is still a BIG problem.
Could you be more efficient? For example, you might decide to loop over over distinct pair of points. There are only
nchoosek(100000,2)
ans =
4999950000
such pairs. So 5 billion pairs. Determine the line that passes though those points. Now, test to see if any of the other points fall on that line. If you are efficient about this, you can avoid testing a triple when it could have already been seen before. But even so, this is still a big problem, because projecting 100000 points onto a line to see if they fall on the line in question will not be that fast, even if vectorized. You won't be doing this millions of times per second.
You could read what Loren wrote here:
But nothing in that blog mentions the problem of how to search through trillions of triples at a time.
Sleh Eddine Brika
on 14 Jul 2020
Edited: Sleh Eddine Brika
on 14 Jul 2020
Bjorn Gustavsson
on 15 Jul 2020
@John: I was thinking in the line of if one have found a set of points that are co-linear with point i and point j then no pair of points from that set have to be used to search for co-linearity with the rest of the ~1e5 points, that's already done. Then if the point-set contains of some number of line-segments with a reasonable number of points on each one would reduce the number of possible lines to test for - possibly by very much.
@Sleh: Maybe you can find efficient methods for this type of analysis if you look for data-analysis-methods for CERN - as far as I understand they do a lot of particle trajectory calculations from point-detections. They also use a lot of computing power to do this.
Sleh Eddine Brika
on 15 Jul 2020
Accepted Answer
More Answers (1)
Jeff Miller
on 15 Jul 2020
0 votes
This is going to be a pretty fuzzy suggestion: Maybe you can speed things up by temporarily throwing away precision. The idea is to reduce precision so that you can group points and have fewer to check.
To have a concrete example, imagine that all of your numbers are in the range 0-1. In a first pass, round all the numbers to the nearest 0.1. Now you will have at most 11^3 distinct rows--way less than 100000. Check these distinct rows and keep track of which triples are collinear at this level of precision. This will tell narrow down the triples of the 100000 rows that are possibly collinear, so you only have to check those in a subsequent step. Maybe add another intermediate step where you round to the nearest 0.01.
Well, I'm not sure whether this would work. It would fail if a collinear triple could be rounded into a non-collinear triple. John?
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!