Edit: Changed the title. I’m less interested in the two segments being the same, but rather, if they are colinear with each other, within a certain tolerance. If so, then the lines should be clustered together as a single segment.
Edit: I guess a short way of saying this: I’m trying to cluster similar line segments together in an efficient way.
Say I have line segments f (fx0, fy0) and (fx1, fy1) and g (gx0, gy0) and (gx1, gy1)
These come from something like a computer-vision algorithm edge detector, and in some cases, the two lines are basically the same, but are counted as two distinct lines because of pixel tolerances.
There are several scenarios
fandgshare the exact same endpoints, eg:f = (0,0), (10,10) g = (0,0), (10,10)fandgshare roughly the same endpoints, and roughly the same length, eg :f = (0,0.01), (9.95,10) g = (0,0), (10,10)fis a subset ofg, meaning that its endpoints fall within thegsegment and share the same slope as thegsegment. Think of a roughly drawn line in which the pen has gone back and forth to make it thicker. eg :f = (4.00, 4.02), (9.01, 9.02) g = (0,0), (10,10)
The following would not be considered the same:
fandghave a slope difference beyond a certaintolerancefandgmay have the same slope but are separated by a distance beyondtolerance, i.e. parallel linesfandgare on the same plane and same slope, but don’t overlap at all…i.e. a set of segments within a dashed line.
The easiest way to tell if they are the same is if gx1 - fx1 <= tolerance (repeat for the three other points), but in some cases, line f may be shorter than line g (again, because of pixel differences and/or poor photo scanning).
So is it better to convert the two segments into polar coordinates and compare the angles? In that case, the two rho’s would be within a tolerance. But then you have to make sure the two line segments have the same “direction”, which is trivial to compute in Cartesian or polar coordinates.
So this is easy to figure out a way, but I’m just wondering if there’s a much cleaner way, based in the linear algebra that I’ve long forgotten?
Your problem is two-fold: you want to compare both the difference in length and difference in angles. To compute the difference in length, you’d take the length of the first line and divide it by the length of the second line.
To take the difference in angle, you can use
atanor, my favourite:angle = acos(abs((u dot v)/(u.length * v.length)))Hopefully this helps. Sorry for the mistaken answer earlier.
Old answer:
Here’s an idea for you: why not compare the difference in the start and end points of the two line segments to the total length of one of the lines? Then your difference function would look something like:
This function will return the “difference” between two lines as a fraction of the total length of the first line.