views:

120

answers:

3

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

alt text

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)

alt text

And of course by math formulation I meant some kind of math formula like

alt text

+1  A: 

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

pcantin
+1  A: 

What have you tried so far?

I guess one way is to look for pairs of lines where:

  1. the directions are similar |theta_1 - theta_2| < eps for some eps
  2. 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

second
I know the algorithm, my problem is its formalisation into math using some Matrix and other math words (to write into some paper=)
Kabumbus
a mathematical argument doesn't need to contain 'math words' to be valid. a clear and concise argument describing your method is completely valid.
second
+1  A: 
  1. Sort all your segments based on angle (in range 0 to Pi), and build a sorted map of angle-to-segment.
  2. 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.
  3. 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))
Victor Liu
Grate Answer, Grate solution - clear and resonable. But as I sad my main problem was formlation the problem as some kind of mathmatical rabl-rabl like "argmin(B, A) [Atan((B.y-A.y) / (B.x-A.x))]" btw that line i just write looks like math... but I do not kow how to give to determine in such math model my arrays of A's and B's
Kabumbus
Well, if you want a single boolean expression, then just substitute explicitly: `IsContinuation(A,B, C,D) = NearPar(A,B, C,D) and NearPar(A,C, B,D) and NearPar(A,D, B,C)`. Just keep substituting in the definitions for each function that appears until you get to something that's only in terms of the points A-D and functions like Atan.
Victor Liu