I have an array of "lines" each defined by 2 points. I am 开发者_运维知识库working with only the line segments lying between those points. I need to search lines that could continue one another (relative to some angle) and lie on the same line (with some offset)
I mean I had something like 3 lines
I solved some mathematical problem (formulation of which is my question) and got understanding that there are lines that could be called relatively one line (with some angle K and offset J)
And of course by math formulation I meant some kind of math formula like
- Sort all your segments based on angle (in range 0 to Pi), and build a sorted map of angle-to-segment.
- Decide on some angle difference threshold below which two segments can be considered parallel. Iterate through your map and for each mapping, consider adjacent mappings on either side of the angle (needs wrap around) which are considered parallel.
- Within each set of nearly-parallel segments, see if they are "continuations" of each other.
Two segments (A,B) and (C,D) are roughly collinear if all possible pairings of the 4 points are roughly parallel. You can use the same test as above.
Pseudo-code:
Angle(A,B)
return Atan((B.y-A.y) / (B.x-A.x)) // use atan2 if possible, but needs wrapping
NearlyParallel(angle1, angle2)
delta = Abs(angle1-angle2)
return (delta < threshold) or (delta > Pi-threshold)
Collinear(A,B, C,D)
// Assume NearlyParallel(Angle(A,B), Angle(C,D)) == true
return NearlyParallel(Angle(A,C), Angle(B,D)) and NearlyParallel(Angle(A,D), Angle(B,C))
What have you tried so far?
I guess one way is to look for pairs of lines where:
- the directions are similar
|theta_1 - theta_2| < eps
for someeps
- there is at least one pair of end points where the points are close
Depending on the size of your problem you may be able to just check all pairs of lines for the conditions
Starting with: A = a2 – a1 where a1 and a2 are the angle of the two lines.
We can do this:
tan(A) = tan(a1 – a2) = (tan(a2) – tan(a1)) / (1 + tan(a1) tan(a2))
If tan(a2) is bigger than tan(a1) then tan(A) will be the acute angle between the two lines. You can then check tan(A) against your tolerance.
So I guess the formula would be:
tan(A) = (tan(a2) – tan(a1)) / (1 + tan(a1) tan(a2)) when tan(a2) > tan(a1)
But I'm no mathematician
精彩评论