2

How do I find all quadrilaterals in between several intersecting lines? Only condition is that each side of the quadrilateral is one line.

I found this theoretical explanation but not a code for it.

So far I'm pretty much in the beginning. I have my lines (two x,y points for each line) and found all intersection of them (x,y point). If you're interested in the script, see here.

My script is based on php so far but I'm thankful for any advised, also in a different language.


Example

Here a set of lines.

line 715.341 0 757.297 600, 
line 0 249.169 800 179.178, 
line 0 256.196 800 186.205, 
line 0 284.225 800 200.142, 
line 396.716 0 481.041 600, 
line 0 311.374 800 227.29, 
line 0 355.76 800 229.053, 
line 0 521.525 800 437.442, 
line 696.134 0 611.809 600

In my example the intersection points would be the followings. Each point has a number, x and y coordinates as well as two lines ids.

 Point 1. 728.309, 185.45, 0, 1
 Point 2. 728.797, 192.434, 0, 2
 Point 3. 729.852, 207.515, 0, 3
 Point 4. 731.736, 234.465, 0, 5
 Point 5. 732.11, 239.806, 0, 6
 Point 6. 746.324, 443.084, 0, 7
 Point 7. 426.491, 211.856, 1, 4
 Point 8. 669.346, 190.609, 1, 8
 Point 9. 427.466, 218.798, 2, 4
 Point 10. 668.346, 197.723, 2, 8
 Point 11. 430.305, 238.998, 3, 4
 Point 12. 666.027, 214.223, 3, 8
 Point 13. 434.065, 265.752, 4, 5
 Point 14. 436.988, 286.548, 4, 6
 Point 15. 463.17, 472.844, 4, 7
 Point 16. 662.154, 241.778, 5, 8
 Point 17. 660.845, 251.093, 6, 8
 Point 18. 632.176, 455.081, 7, 8
convert -size 800x600 xc:skyblue \
    -fill red -stroke red -strokewidth 2 \
    -draw "line 715.341 0 757.297 600, line 0 249.169 800 179.178, line 0 256.196 800 186.205, line 0 284.225 800 200.142, line 396.716 0 481.041 600, line 0 311.374 800 227.29, line 0 355.76 800 229.053, line 0 521.525 800 437.442, line 696.134 0 611.809 600" \
    -font Courier -pointsize 14 -draw "fill none stroke blue circle 728.309,185.45 726.309,183.45 circle 728.797,192.434 726.797,190.434 circle 729.852,207.515 727.852,205.515 circle 731.736,234.465 729.736,232.465 circle 732.11,239.806 730.11,237.806 circle 746.324,443.084 744.324,441.084 circle 426.491,211.856 424.491,209.856 circle 669.346,190.609 667.346,188.609 circle 427.466,218.798 425.466,216.798 circle 668.346,197.723 666.346,195.723 circle 430.305,238.998 428.305,236.998 circle 666.027,214.223 664.027,212.223 circle 434.065,265.752 432.065,263.752 circle 436.988,286.548 434.988,284.548 circle 463.17,472.844 461.17,470.844 circle 662.154,241.778 660.154,239.778 circle 660.845,251.093 658.845,249.093 circle 632.176,455.081 630.176,453.081" \
    -draw "fill blue stroke blue text 738.309,190.45 '1' text 738.797,197.434 '2' text 739.852,212.515 '3' text 741.736,239.465 '4' text 742.11,244.806 '5' text 756.324,448.084 '6' text 436.491,216.856 '7' text 679.346,195.609 '8' text 437.466,223.798 '9' text 678.346,202.723 '10' text 440.305,243.998 '11' text 676.027,219.223 '12' text 444.065,270.752 '13' text 446.988,291.548 '14' text 473.17,477.844 '15' text 672.154,246.778 '16' text 670.845,256.093 '17' text 642.176,460.081 '18'" \
    lines-intersection.jpg

intersection points of lines

So now the big question is, how I use the information to find all quadrilateral between the points where each side is one line...

One of the quadrilateral I'm looking for is Point 13, 4, 6 and 15:

quadrilateral between point 13, 4, 6 and 15

Community
  • 1
  • 1
wittich
  • 2,079
  • 2
  • 27
  • 50
  • You need to explain what "all rectangles" means. Does it mean that you want to make a rectangle out of every pair of points that is not on a horizontal or vertical line? – kainaw Aug 28 '15 at 16:14
  • Your tags are confusing. Please indicate which language you're coding in, and leave off those in which you aren't. – kittykittybangbang Aug 28 '15 at 16:14
  • You're not looking for rectangles. There are no rectangles in your example. Rectangles have a 90 Deg angle on all 4 corners. Probably should fix your terminology. I Believe Trapezoid would be the correct term. – danielson317 Aug 28 '15 at 16:17
  • Also you have way too much code in this question. Try to ask something more specific. – danielson317 Aug 28 '15 at 16:20
  • sorry guys I mean quadrangle... A square of four points where at least two points are on the same line. – wittich Aug 28 '15 at 16:22
  • *Cryrus* and *danielson317* the question itself is short, I just tried to explain with the example why I have this question... – wittich Aug 28 '15 at 16:27
  • @wittich Your definition of quadrangle makes no sense. A square is a type of quadrangle. Also, give me any two different points and they will be on a line because two different points define a line. – kainaw Aug 28 '15 at 16:50
  • I guess quadrilateral is word I was looking for... The sides has to be from 4 lines which mean that 2 intersection point are on each line. – wittich Aug 28 '15 at 17:07
  • I worked over the question, I hope now its more clear what I look for. – wittich Aug 28 '15 at 17:56

2 Answers2

2

I would recommend breaking down the problem this way:

  1. Find the basic quadrilaterals in the problem set
  2. Find the common edges amongst those basic quadrilaterals
  3. Produce a list or matrix of allowable combinations to show all possible quadrilaterals

Find the basic quadrilaterals: I would recommend start by using a Voronoi/Delaunay process to find the Voronoi diagram.

In case you aren't familiar (or others come across this question who aren't), what you have come up with is a set of graph points (and connecting edges) from a set of lines. The Voronoi diagram defines a set of points that are equidistant from the nearest current points--basically, you'll be finding the centers of the enclosed areas, plus some extras. (More detailed explanation at Wikipedia).

The enclosed areas (rectangles, triangles, etc) that you desire are identified by a subset of the Voronoi points, and you can perform other tests to find that subset programatically. From your example, you may or may not want to discard resulting triangles; if you do, then you can probably just count surrounding edges/faces once you've identified the enclosed areas.

I'm not a PHP expert, but my Google-fu shows a PHP implementation at GitHub. My own research work is in graph structures and robotics, and this kind of usage comes up often.

One interpretation of the Voronoi diagram is that the new points are based on "nearest neighbors"--each point lies within a fixed or an infinite polygon created by the original points.

If you are looking for quadrilateral, then find the nearest 4 points to each Voronoi point. If there is a set of edges that directly connect the 4 points (pt1-pt2-pt3-pt4-pt1), you are inside a quadrilateral. If not, then you are inside another shape or on one of the outside areas that lead to infinity.

(That's the sledgehammer approach, as my old aerospace instructor used to call it. There are more elegant solutions, I'm sure, but classifying shapes was not something I've covered. If I find--or someone suggests--a better answer, I'll update this.)

Find the common edges amongst those basic quadrilaterals For "stacked" quadrilaterals, as shown in your updated question, you can find common edges among the basic quadrilaterals and then produce a list of combinations. For example, if quad A has a common side with quad B, then you produce a larger quadrilateral quad AB.

Produce a list or matrix of allowable combinations After that, you'll probably have to retest until all possible combinations are exhausted. One thing that you will have to test is that the additional shape is still a quadrilateral--if you add a row up and a row left or right, you get an "L"-type shape that is no longer valid.

Not pretty or elegant, but probably effective.

  • Thx @angus_thermopylae I'll try to get familiar with it and see if it answers my question... – wittich Aug 28 '15 at 18:00
  • Okay I started to understand a little the Voronoi diagram, but I'm not sure if I can use it for what I want, as I don't only look for the enclosed areas but also quadrilaterals which have another point inside. The only condition should be that each side of polygone equal respectively one line. I created a Voronoi diagram for my example (http://i.imgur.com/4H1sPZN.png) but I'm not sure how to continue now... – wittich Aug 28 '15 at 22:21
2

Okay I found one solution. Unfortunately I couldn't work it out, using the Voronoi diagram recommended by angus_thermophyale.

The idea I had is, to use the fact, that each quadrilateral must have a summed angle of 360°.

example quadrilateral

Basically I did it the following way:

  1. create a list with all possible combination of 4 intersection points in a chain.
  2. then I justed use every combination where two points are on one line. To filter this I used the line IDs saved for each point.
  3. create vectors between the points and calculate the angles. Each angle has to be bigger then 0° and smaller then 180°
  4. sum the 4 angles and check if it is 360°

Result

all possible quadrilaterals


Let me know if anybody is interested in the code details...

Community
  • 1
  • 1
wittich
  • 2,079
  • 2
  • 27
  • 50