Algorithm u-v空间中均匀分布的点不会在四边形中产生均匀分布的点(在欧几里得意义上)。如果这很重要,您可以在四边形的边界框内直接在2D中工作,并在四边形中写入一个点(可能通过将问题拆分为两个三点)测试来剔除外部的随机点。
对于PostGIS,这是我正在使用的(您可能希望为可能的无限循环设置一个病房)。您可以将算法导出到您的编程语言:Algorithm u-v空间中均匀分布的点不会在四边形中产生均匀分布的点(在欧几里得意义上)。如果这很重要,您可以在四边形的边界框内直接在2D中工作,并在四边形中写入一个点(可能通过将问题拆分为两个三点)测试来剔除外部的随机点。,algorithm,matlab,random,2d,polygon,Algorithm,Matlab,Random,2d,Polygon,对于PostGIS,这是我正在使用的(您可能希望为可能的无限循环设置一个病房)。您可以将算法导出到您的编程语言: CREATE or replace FUNCTION random_point(geometry) RETURNS geometry AS $$ DECLARE env geometry; corner1 geometry; corner2 geometry; minx real; miny real; maxx real;
CREATE or replace FUNCTION random_point(geometry)
RETURNS geometry
AS $$
DECLARE
env geometry;
corner1 geometry;
corner2 geometry;
minx real;
miny real;
maxx real;
maxy real;
x real;
y real;
ret geometry;
begin
select ST_Envelope($1) into env;
select ST_PointN(ST_ExteriorRing(env),1) into corner1;
select ST_PointN(ST_ExteriorRing(env),3) into corner2;
select st_x(corner1) into minx;
select st_x(corner2) into maxx;
select st_y(corner1) into miny;
select st_y(corner2) into maxy;
loop
select minx+random()*(maxx-minx) into x;
select miny+random()*(maxy-miny) into y;
select ST_SetSRID(st_point(x,y), st_srid($1)) into ret;
if ST_Contains($1,ret) then
return ret ;
end if;
end loop;
end;
$$
LANGUAGE plpgsql
volatile
RETURNS NULL ON NULL INPUT;
OP提出的问题有点模糊,因此我将回答的问题是:如何从任意四边形内的均匀分布生成点,这实际上是如何从任意(凸)多边形内的均匀分布生成点的推广。答案基于从三角形中的均匀分布生成样本的情况(参见,这有一个很好的解释) 为了实现这一目标,我们:
MATLAB函数从一般凸多面体上的均匀分布生成点。对于您的问题,基于将四边形分解为三角形的更专门的算法更有效。随机是什么意思?您可以选择位于对角线上的随机点。或者您想完成填充t整个多边形,如果你产生足够多的随机点?如果我产生足够多的随机点,我想填充整个多边形。这再简单不过了:画一个简单的矩形,它的大小足以包围你的多边形。(或者任何“形状或东西”)现在创建随机分布在这个封闭的普通正方形中的点。对于每个点,测试它是否在你的形状内。丢弃那些在形状外的点。就这么简单。希望它有用!我怀疑这不是Turambar需要的,但它会起作用。有些线比其他线长,所以要获得均匀分布,不要拍照画一条线,然后选择一个像素。数数像素,然后随机选择一个,然后从列表中找到它的位置…如果你需要随机点的均匀分布,确保你考虑到两个三角形的面积和适当的权重。回答很好。可爱的图片。我正在尝试实现这一点,我认为应该是be
x'=v0+(v3-x)
我是否完全偏离了基准?再看一看,我不确定我是否正确,但我的v0=[0,0]测试用例将x'置于三角形之外。@gabriel_littman。我相信你是正确的。在方程的图形中缺少R(pi),也就是说,旋转180度。我认为旋转矩阵是[-1,0;0,-1],也就是说,我们取其操作数的负数。这是问题的实际答案!我曾尝试用python实现这一点,但我认为有些地方被破坏了。对于点为[0,1],[1,0],[1,0]的三角形,v3是[2,-1]这似乎没有什么意义。此外,我得到的点位于四边形之外。有什么想法吗?重心法是否适用于有孔的多边形?@Pranav没有。重心坐标需要连续域,我猜可能是凸的(待检查)。对于其他正在查看的人,以下是如何查找点是否位于三角形内的方法:
P = a A + b B + c C + d D
// public-domain code by Darel Rex Finley, 2007
int nodes, nodeX[MAX_POLY_CORNERS], pixelX, pixelY, i, j, swap ;
// Loop through the rows of the image.
for (pixelY=IMAGE_TOP; pixelY<IMAGE_BOT; pixelY++) {
// Build a list of nodes.
nodes=0; j=polyCorners-1;
for (i=0; i<polyCorners; i++) {
if (polyY[i]<(double) pixelY && polyY[j]>=(double) pixelY
|| polyY[j]<(double) pixelY && polyY[i]>=(double) pixelY) {
nodeX[nodes++]=(int) (polyX[i]+(pixelY-polyY[i])/(polyY[j]-polyY[i])
*(polyX[j]-polyX[i])); }
j=i; }
// Sort the nodes, via a simple “Bubble” sort.
i=0;
while (i<nodes-1) {
if (nodeX[i]>nodeX[i+1]) {
swap=nodeX[i]; nodeX[i]=nodeX[i+1]; nodeX[i+1]=swap; if (i) i--; }
else {
i++; }}
// Fill the pixels between node pairs.
// Code modified by SoloBold 27 Oct 2008
// The flagPixel method below will flag a pixel as a possible choice.
for (i=0; i<nodes; i+=2) {
if (nodeX[i ]>=IMAGE_RIGHT) break;
if (nodeX[i+1]> IMAGE_LEFT ) {
if (nodeX[i ]< IMAGE_LEFT ) nodeX[i ]=IMAGE_LEFT ;
if (nodeX[i+1]> IMAGE_RIGHT) nodeX[i+1]=IMAGE_RIGHT;
for (j=nodeX[i]; j<nodeX[i+1]; j++) flagPixel(j,pixelY); }}}
// TODO pick a flagged pixel randomly and fill it, then remove it from the list.
// Repeat until no flagged pixels remain.
.BBBB.
A C
A C
.DDDD.
void GetRandomPoint(Polygon p, ref float x, ref float y) {
float xrand = random();
float yrand = random();
float h0 = p.Vertices[0] + xrand * p.Vertices[1];
float h1 = p.Vertices[2] + yrand * p.Vertices[3];
float v0 = p.Vertices[0] + xrand * p.Vertices[2];
float v1 = p.Vertices[1] + yrand * p.Vertices[3];
GetLineIntersection(h0, h1, v0, v1, x, y);
}
CREATE or replace FUNCTION random_point(geometry)
RETURNS geometry
AS $$
DECLARE
env geometry;
corner1 geometry;
corner2 geometry;
minx real;
miny real;
maxx real;
maxy real;
x real;
y real;
ret geometry;
begin
select ST_Envelope($1) into env;
select ST_PointN(ST_ExteriorRing(env),1) into corner1;
select ST_PointN(ST_ExteriorRing(env),3) into corner2;
select st_x(corner1) into minx;
select st_x(corner2) into maxx;
select st_y(corner1) into miny;
select st_y(corner2) into maxy;
loop
select minx+random()*(maxx-minx) into x;
select miny+random()*(maxy-miny) into y;
select ST_SetSRID(st_point(x,y), st_srid($1)) into ret;
if ST_Contains($1,ret) then
return ret ;
end if;
end loop;
end;
$$
LANGUAGE plpgsql
volatile
RETURNS NULL ON NULL INPUT;