Если это обычный шестиугольник, самый простой метод, который приходит на ум, - разделить его на три ромба. Таким образом (а) они имеют одинаковую площадь, и (б) вы можете выбрать случайную точку в любом ромбе с двумя случайными переменными от 0 до 1. Вот код Python, который работает.
from math import sqrt
from random import randrange, random
from matplotlib import pyplot
vectors = [(-1.,0),(.5,sqrt(3.)/2.),(.5,-sqrt(3.)/2.)]
def randinunithex():
x = randrange(3);
(v1,v2) = (vectors[x], vectors[(x+1)%3])
(x,y) = (random(),random())
return (x*v1[0]+y*v2[0],x*v1[1]+y*v2[1])
for n in xrange(500):
v = randinunithex()
pyplot.plot([v[0]],[v[1]],'ro')
pyplot.show()
Несколько человек в дискуссии подняли вопрос о единообразной выборке дискретной версии шестиугольника. Наиболее естественная дискретизация - с треугольной решеткой, и есть вариант вышеупомянутого решения, который все еще работает. Вы можете немного урезать ромбы, чтобы каждый из них содержал одинаковое количество очков. Они только пропускают происхождение, которое должно быть разрешено отдельно как особый случай. Вот код для этого:
from math import sqrt
from random import randrange, random
from matplotlib import pyplot
size = 10
vectors = [(-1.,0),(.5,sqrt(3.)/2.),(.5,-sqrt(3.)/2.)]
def randinunithex():
if not randrange(3*size*size+1): return (0,0)
t = randrange(3);
(v1,v2) = (vectors[t], vectors[(t+1)%3])
(x,y) = (randrange(0,size),randrange(1,size))
return (x*v1[0]+y*v2[0],x*v1[1]+y*v2[1])
# Plot 500 random points in the hexagon
for n in xrange(500):
v = randinunithex()
pyplot.plot([v[0]],[v[1]],'ro')
# Show the trimmed rhombuses
for t in xrange(3):
(v1,v2) = (vectors[t], vectors[(t+1)%3])
corners = [(0,1),(0,size-1),(size-1,size-1),(size-1,1),(0,1)]
corners = [(x*v1[0]+y*v2[0],x*v1[1]+y*v2[1]) for (x,y) in corners]
pyplot.plot([x for (x,y) in corners],[y for (x,y) in corners],'b')
pyplot.show()
А вот и картинка.
альтернативный текст http://www.freeimagehosting.net/uploads/0f80ad5d9a.png