Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm u-v空间中均匀分布的点不会在四边形中产生均匀分布的点(在欧几里得意义上)。如果这很重要,您可以在四边形的边界框内直接在2D中工作,并在四边形中写入一个点(可能通过将问题拆分为两个三点)测试来剔除外部的随机点。_Algorithm_Matlab_Random_2d_Polygon - Fatal编程技术网

Algorithm u-v空间中均匀分布的点不会在四边形中产生均匀分布的点(在欧几里得意义上)。如果这很重要,您可以在四边形的边界框内直接在2D中工作,并在四边形中写入一个点(可能通过将问题拆分为两个三点)测试来剔除外部的随机点。

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;

对于PostGIS,这是我正在使用的(您可能希望为可能的无限循环设置一个病房)。您可以将算法导出到您的编程语言:

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提出的问题有点模糊,因此我将回答的问题是:如何从任意四边形内的均匀分布生成点,这实际上是如何从任意(凸)多边形内的均匀分布生成点的推广。答案基于从三角形中的均匀分布生成样本的情况(参见,这有一个很好的解释)

为了实现这一目标,我们:

  • 对多边形进行三角化(即生成覆盖多边形的非重叠三角形区域集合)。对于四边形的情况,请创建一条横穿四边形的边 任意两个不相邻的顶点。有关其他多边形,请参见以获取起点,或者仅需要库

  • 要随机选取其中一个三角形,让我们为每个三角形指定一个索引(即0,1,2,…)。对于四边形,它们将为0,1。对于每个三角形,我们分配的权重相等,如下所示:

  • 然后根据给定权重的指数的有限分布生成一个随机指数i。对于四边形,这是伯努利分布:

  • 假设v0,v1,v2是三角形的顶点(由它们的点位置表示,因此v0=(x0,y0)等。然后我们生成两个随机数a0和a1,都是从区间[0,1]均匀绘制的。然后我们通过x=a0(v1-v0)+a1(v2-v0)计算随机点x

  • 请注意,概率为0.5时,x位于三角形外部,但如果它位于三角形与其图像的并集构成的平行四边形内部,旋转圆周率为(v1,v2)(图像中的虚线)。在这种情况下,我们可以生成一个新的点x'=v0+R(pi)(x-v3),其中R(pi)是pi旋转(180度)。点x'将位于三角形内

  • 进一步注意,如果四边形已经是一个平行四边形,那么我们不必随机选取一个三角形,我们可以确定地选取其中一个,然后选择点x,而无需测试它是否在源三角形内


  • 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;