I think the best option is selecting such a polygon at random. The probability of three diagonals being convergent is zero in that case. However, you are going to get = 126 points of intersection inside your 9-gon (and twice as many outside it), so they are going to be close together.

Let me give you a code example, and let's also find the minimum distance between two intersections. There's some discussion afterwards.

with(Statistics):

with(simplex):

s := Sample(RandomVariable(Normal(0, 1)));

# This returns a procedure that will create samples for us. (This is underdocumented

# in Maple 14 but we expect to improve that for the next version.)

hull := []:

while nops(hull) < 9 do

hull := convexhull([op(hull), convert(s(2), list)]);

end do:

hull_plot := plots:-display(plot(hull, style=point, color=black, symbolsize=20),

plot([op(hull), hull[1]], color=green)):

hull_plot;

# This shows the nine points that we've found.

diagonalpairs := map(proc(quad)

local p1, p2, p3, p4;

p1, p2, p3, p4 := op(quad);

return [[p1, p2], [p3, p4]], [[p1, p3], [p2, p4]], [[p1, p4], [p2, p3]];

end proc, combinat:-choose(hull, 4)):

# We've now found all pairs of disjoint pairs of points defining the hull (intersecting

# inside the convex hull and outside it).

# The following procedure takes two points and returns a procedure mapping an

# x-value to the corresponding y-value on the line connecting the two points.

# It will error out if it gets two points with the same x-value - but that happens

# with probability 0.

toProc := proc(p1, p2)

local a, b, x;

a := (p2[2] - p1[2])/(p2[1] - p1[1]);

b := p1[2] - a * p1[1];

return unapply(a*x + b, x);

end proc;

intersections := map(proc(quad)

local x, x0, p1p, p2p;

p1p := toProc(op(quad[1]));

p2p := toProc(op(quad[2]));

x0 := solve(p1p(x) = p2p(x), x);

return [x0, p1p(x0)];

end proc, diagonalpairs):

# We now have the 378 points of intersection of each pair of diagonals.

# Display the hull and the intersections (viewport shrunk to fit the hull).

plots:-display(hull_plot, plot(intersections, style=point),

view=(min .. max)~(map2(map2, op, [1, 2], hull)));

mindist := sqrt(min(map(x -> (x[1][1] - x[2][1])^2 + (x[1][2] - x[2][2])^2,

combinat:-choose(intersections, 2))));

The minimum distance was approximately 0.0024 in the case that I tried.

An interesting question (to me) is what a good distribution is to choose the points from, if you want to obtain a convex hull consisting of 9 points by selecting as few points as possible (in expectation). It seems likely that somebody has thought about this before. Does anyone know of a paper? (*Update*: you can get some very interesting distributions of the points over the interior if you select a uniform distribution, because the polygon becomes an approximation to a square.)

Finally: maybe you were hoping to get nice rationals as a result. You could of course just use the floating point numbers as rationals, but that is not exactly nice. Another option is to try rounding the coordinates of the points in the hull using *convert*(..., *confrac*); that is, taking one of the convergents in the continued fraction expansion. Then of course you should check afterwards that the minimum distance is still positive: too aggressive rounding will make the intersections be equal. Let us know if you need help with this.

Hope this helps,

Erik Postma

Maplesoft.