http://qs1969.pair.com?node_id=382584

dada has asked for the wisdom of the Perl Monks concerning the following question:

hello,

I'm looking for a fast sorting (or "reordering") algorithm. the situation is as follows: I have a bunch of segments, in the form of 4-elements arrays ( START_X, START_Y, END_X, END_Y ). these segments form a polygon, but unfortunately I don't have them in the right order.

to let you understand the problem, consider this polygon:

```   |
5 +  F-----------E
|  |           |
4 +  |           |
|  |           |
3 +  |  C--------D
|  |  |
2 +  |  |
|  |  |
1 +  A--B
|
+--+--+--+--+--+--
1  2  3  4  5
I could have the segments, for example, in this order (letters are not there, they're just for your reference):
```DE = [ 5, 3, 5, 5 ]
AB = [ 1, 1, 2, 1 ]
BC = [ 2, 1, 2, 3 ]
EF = [ 5, 5, 1, 5 ]
FA = [ 1, 5, 1, 1 ]
CD = [ 2, 3, 5, 3 ]
and I need them in this order:
```AB = [ 1, 1, 2, 1 ]
BC = [ 2, 1, 2, 3 ]
CD = [ 2, 3, 5, 3 ]
DE = [ 5, 3, 5, 5 ]
EF = [ 5, 5, 1, 5 ]
FA = [ 1, 5, 1, 1 ]
in fact, what I need is just the order of the points to build the polygon, which is:
```A = [ 1, 1 ]
B = [ 2, 1 ]
C = [ 2, 3 ]
D = [ 5, 3 ]
E = [ 5, 5 ]
F = [ 1, 5 ]
that said, the algorithm I came up with is:
```  # segments are in @seg
my(\$start_x, \$start_y) = (\$seg[0]->[0], \$seg[0]->[1]);
my(\$end_x, \$end_y) = (\$seg[0]->[2], \$seg[0]->[3]);
push(@poly, [\$start_x, \$start_y]);
push(@poly, [\$end_x, \$end_y]);
shift(@seg);
while(@seg) {
for(my \$s = 0; \$s <= \$#seg; \$s++) {
if( \$seg[\$s]->[0] == \$end_x
and \$seg[\$s]->[1] == \$end_y ) {
(\$end_x, \$end_y) = (\$seg[\$s]->[2], \$seg[\$s]->[3]);
push(@poly, [\$end_x, \$end_y]);
splice(@seg, \$s, 1);
}
}
}
# polygon points are in @poly