The question has changed, thus this answer contains different versions, with and without a closed path.
Perl, open path, 69 bytes
print"@$_$/"for sort{$$a[0]<=>$$b[0]||$$a[1]<=>$$b[1]}map{[/\S+/g]}<>
Each point is expected in STDIN as line, with the coordinates separated by white space.
Any number format is supported that Perl interprets as number (including floating point numbers).
Example:
0 0
4 4
0 4
4 0
-2 1
2 -2
2 4
3.21 .56
.035e2 -7.8
0 2
Output:
-2 1
0 0
0 2
0 4
2 -2
2 4
3.21 .56
.035e2 -7.8
4 0
4 4

Ungolfed:
print "@$_$/" for # print output line
sort { # sort function for two points $a and $b
$$a[0] <=> $$b[0] # compare x part
|| $$a[1] <=> $$b[1] # compare y part, if x parts are identical
}
map { [/\S+/g] } # convert input line to point as array reference
<> # read input lines
Circuit variants
In the first question version, there was a connection between the last and first point to make a circuit.
Center is not existing point, 253 bytes
This variant can fail, if the center is one of the points, see example 3.
Edits:
In his answer swish noticed, that the points should be centered around the origin to ensure a cross-free circuit:
- Sorting needs transformed coordinates.
- The original string representation of the numbers need to be kept for
the output.
Bug fix: the special case for the negative x-axis had included the positive x-axis.
print"$$_[2] $$_[3]$/"for sort{($X,$Y)=@$a;($x,$y)=@$b;(!$X&&!$Y?-1:0)||!$x&&!$y||!$Y&&!$y&&$X<0&&$x<0&&$X<=>$x||atan2($Y,$X)<=>atan2($y,$x)||$X**2+$Y**2<=>$x**2+$y**2}map{[$$_[0]-$M/$n,$$_[1]-$N/$n,@$_]}map{$n++;$M+=$$_[0];$N+=$$_[1];$_}map{[/\S+/g]}<>
Example 1:
4 4
-2 0
2 0
1 1
4 0
-2 -2
-3 -1
1 -2
3 0
2 -4
0 0
-1 -2
3 3
-3 0
2 3
-5 1
-6 -1
Output 1:
0 0
-6 -1
-3 -1
-2 -2
-1 -2
1 -2
2 -4
2 0
3 0
4 0
1 1
3 3
4 4
2 3
-5 1
-3 0
-2 0

Example 2:
Testing number representation and coordinate transformation.
.9e1 9
7 7.0
8.5 06
7.77 9.45
Output 2:
7 7.0
8.5 06
.9e1 9
7.77 9.45

Ungolfed:
print "$$_[2] $$_[3]$/" for sort { # print sorted points
($X, $Y) = @$a; # ($X, $Y) is first point $a
($x, $y) = @$b; # ($x, $y) is second point $b
(!$X && !$Y ? -1 : 0) || # origin comes first, test for $a
!$x && !$y || # origin comes first, test for $b
!$Y && !$y && $X < 0 && $x < 0 && $X <=> $x ||
# points on the negative x-axis are sorted in reverse order
atan2($Y, $X) <=> atan2($y, $x) ||
# sort by angles; the slope y/x would be an alternative,
# then the x-axis needs special treatment
$X**2 + $Y**2 <=> $x**2 + $y**2
# the (quadratic) length is the final sort criteria
}
map { [ # make tuple with transformed and original coordinates
# the center ($M/$n, $N/$n) is the new origin
$$_[0] - $M/$n, # transformed x value
$$_[1] - $N/$n, # transformed y value
@$_ # original coordinates
] }
map {
$n++; # $n is number of points
$M += $$_[0]; # $M is sum of x values
$N += $$_[1]; # $N is sum of y values
$_ # pass orignal coordinates through
}
map { # make tuple with point coordinates
[ /\S+/g ] # from non-whitespace in input line
}
<> # read input lines
Without restriction, 325 bytes
print"$$_[2] $$_[3]$/"for sort{($X,$Y)=@$a;($x,$y)=@$b;atan2($Y,$X)<=>atan2($y,$x)||$X**2+$Y**2<=>$x**2+$y**2}map{[$$_[0]-$O/9,$$_[1]-$P/9,$$_[2],$$_[3]]}map{$O=$$_[0]if$$_[0]>0&&($O>$$_[0]||!$O);$P=$$_[1]if$$_[1]>0&&($P>$$_[1]||!$P);[@$_]}map{[$$_[0]-$M/$n,$$_[1]-$N/$n,@$_]}map{$n++;$M+=$$_[0];$N+=$$_[1];$_}map{[/\S+/g]}<>
In the previous version, the center is put at the begin and the last points on the negative axis are sorted in reverse order to get cross-free to the center
again. However, this is not enough, because the last points could lie on a different line. Thus the following example 3 would fail.
This is fixed by moving the centered origin a little to the top and right.
Because of centering, there must be at least one point with positive x value and a point with positive y value. Thus the minimums of the positive x and y values are taken and reduced to a ninth (a half or third could be enough).
This point cannot be one of the existing points and is made the new origin.
The special treatments of the origin and the negative x-axis can be removed, because there is any point that lies on the new origin.
Example 3:
-2 -2
-1 -1
-2 2
-1 1
2 -2
1 -1
2 2
1 1
0 0
Output 3:
0 0
-1 -1
-2 -2
1 -1
2 -2
1 1
2 2
-2 2
-1 1

Example 1 is now differently sorted:

Ungolfed:
print "$$_[2] $$_[3]$/" for sort { # print sorted points
($X, $Y) = @$a; # ($X, $Y) is first point $a
($x, $y) = @$b; # ($x, $y) is second point $b
atan2($Y, $X) <=> atan2($y, $x) ||
# sort by angles; the slope y/x would be an alternative,
# then the x-axis needs special treatment
$X**2 + $Y**2 <=> $x**2 + $y**2
# the (quadratic) length is the final sort criteria
}
map { [ # make tuple with transformed coordinates
$$_[0] - $O/9, $$_[1] - $P/9, # new transformed coordinate
$$_[2], $$_[3] # keep original coordinate
] }
map {
# get the minimum positive x and y values
$O = $$_[0] if $$_[0] > 0 && ($O > $$_[0] || !$O);
$P = $$_[1] if $$_[1] > 0 && ($P > $$_[1] || !$P);
[ @$_ ] # pass tuple through
}
map { [ # make tuple with transformed and original coordinates
# the center ($M/$n, $N/$n) is the new origin
$$_[0] - $M/$n, # transformed x value
$$_[1] - $N/$n, # transformed y value
@$_ # original coordinates
] }
map {
$n++; # $n is number of points
$M += $$_[0]; # $M is sum of x values
$N += $$_[1]; # $N is sum of y values
$_ # pass orignal coordinates through
}
map { # make tuple with point coordinates
[ /\S+/g ] # from non-whitespace in input line
}
<> # read input lines