精华内容
下载资源
问答
  • 多边形算法

    2013-11-25 10:05:55
    多边形算法在VC和linux上面均验证过,定位点非常准确,并且是简单的.c文件,便于直接调用
  • 基于java的泰森多边形算法 基于java的泰森多边形算法 基于java的泰森多边形算法 基于java的泰森多边形算法
  • 泰森多边形算法

    热门讨论 2011-12-28 01:10:31
    实现泰森多边形算法,可用于电信行业实现小区理论覆盖算法。
  • 电子栅栏多边形算法,至少三个点,可以拓展更多的点,亲测可用。传入多边形的顶点和需要测试的点的坐标,即可判断该点是否在多边形内(可以包括边界,也可以不包括,里面有两个方法)。 压缩包包含一个画图的测试类...
  • 基于java的泰森多边形算法 代码简介 方便 可实现对于多边形的渲染
  • 多边形算法制作后回顾 面或者直线上增加节点 凹多边形的切割 涉及内容 向量 直线方程 点线面三者的拓扑关系 无向图 完成进度 算法开始时间2.27 Mon 26Mon 05算法设立 多边形凹点判断、凹点射线 内部线切割 无向...

    凹多边形算法制作后回顾

    面或者直线上增加节点

    凹多边形的切割

    涉及内容

    • 向量
    • 直线方程
    • 点线面三者的拓扑关系
    • 无向图

    完成进度

    算法开始时间2.27

    Mon 26 Mon 05 算法设立 多边形凹点判断、凹点射线 内部线切割 无向图闭环切割 凹多边形算法

    测试如下面,对此用例是成功了,其他的也有成功也有失败

    1552034268176


    优化

    • 凹点延长线保留,不再使用内部线段
    • 外部轮廓保留
    • 直接将上述两点求闭环
    • 优化进行中

    本文代码及可视化代码均放在 gitee 码云上 欢迎star & fork

    展开全文
  • 多边形中的标量点 多边形算法内点的 Scala 版本。 来自 DR Finley 的原始代码( 与 Patrick Mullen 提供的预计算效率改进。)
  • 2019慕尼黑会议的多边形算法 本页致力于基于Dutter [1]的工作在ISPRS PIA + MRSS 2019大会(德国慕尼黑)上介绍的我们的工作[2]中使用的多边形化方法。 它旨在实现建筑轮廓的多边形化。 该算法可在相对复杂的边界上...
  • 扫描线填充多边形算法详解与代码

    万次阅读 多人点赞 2016-10-30 19:54:43
    扫描线填充多边形算法详解与代码首先给出已知信息:多边形结构体里面包含三个信息:顶点个数,顶点和颜色class MyPolygon { public: int m_VerticeNumber; CPoint m_Vertex[50]; COLORREF m_LineColor; }思路: ...

    扫描线填充多边形算法详解与代码

    首先给出已知信息:多边形结构体里面包含三个信息:顶点个数,顶点和颜色

    class  MyPolygon
    {
    public:
        int m_VerticeNumber;
        CPoint m_Vertex[50]; 
        COLORREF m_LineColor;
    }

    思路:
      找到多边形的最小y值和最大y值,然后用这个范围内的每一条水平线与多边形相交,通过得到的交点画线段,由此填充整个多边形。
      具体通过交点画线段:
      1.对存储交点的数组进行排序(从小到大)
      2.数组中数据两两一对,填充每对交点间的线段
      
      这样分析下来我们所要做的只有两件事,一是求出扫描线与多边形边的交点,二是对交点数组进行排序。
      接下来开始一个一个分析:对于求扫描线与多边形的交点,需要考虑到以下几个特殊情况:
      1.扫描线与边重合
      扫描线与边重合
      2.扫描线与边的交点为顶点
      扫描线与边的交点为顶点
      具体情况具体分析咯:
      对于扫描线与边重合,只需要判断该边的两个顶点的y值是不是一样的,是一样的表示该边水平,因此可以直接重画这条线。否则继续之后的判断。
      对于扫描线与顶点重合,大家看上面的图,我画了两种情况,一种是局部极值的顶点,一种不是局部极值的顶点,这两种顶点交点的记录方法还不一样。如果交点是顶点,且为局部极值,这个交点要被连续记录两次;如果交点是顶点,且不是局部极值,这个交点只需要被记录一次。大家可以看图想想,当交点是局部极值顶点是,所要描绘的线段就是该交点,所以记录两次;当交点是顶点,不是局部极值,所要描绘的是该顶点交点到下一个交点这一条线段,所以只能记录一次。
      判断一个顶点是否为局部极值,可以通过与顶点关联的两条边的另外两个顶点来判断,通过判断它们是不是在顶点交点的同一侧来得出顶点的极值性:
      极值点
      非极值点
      
      排序算法:随机快速排序
    下面贴上代码:

    int getMiny(MyPolygon ThePolygon)
    {
        int min = ThePolygon.m_Vertex[0].y;
        for(int i = 1;i<ThePolygon.m_VerticeNumber;i++)
            if(min>ThePolygon.m_Vertex[i].y)
                min = ThePolygon.m_Vertex[i].y;
        return min;
    }
    
    int getMaxy(MyPolygon ThePolygon)
    {
        int max = ThePolygon.m_Vertex[0].y;
        for(int i = 1;i<ThePolygon.m_VerticeNumber;i++)
            if(max<ThePolygon.m_Vertex[i].y)
                max = ThePolygon.m_Vertex[i].y;
        return max;
    }
    
    //交换
    void Swap(int *a,int i,int j){
        int temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }
    //随机快速排序
    
    int qsort(int *a,int begin,int end){
        int i,j,temp;
        i=begin-1;j=begin;
        for(;j<end;j++)
        {
            if(a[j]<=a[end-1])
                Swap(a,++i,j);
        }
        return i;
    }
    
    void randqsort(int *a,int begin,int n){
        while(begin>=n)
            return ;
        srand((unsigned)time(NULL));
        int key=(begin+rand()%(n-begin));
        Swap(a,key,n-1);
        int m=qsort(a,begin,n);
        randqsort(a,begin,m);
        randqsort(a,m+1,n);
    }
    
    void ScanFill(CDC *pDC,MyPolygon ThePolygon, CPoint startPoint, COLORREF fillCol)
    {
        int miny,maxy;
        int sx,sy,tx,ty;
        miny = getMiny(ThePolygon);
        maxy = getMaxy(ThePolygon);
        int *index = new int[100];
        int *judge = new int[ThePolygon.m_VerticeNumber];
        memset(index,-1,sizeof(int)*100);
        memset(judge,0,sizeof(int)*ThePolygon.m_VerticeNumber);
        int x;
        CPoint Point;
        for(int i = miny;i<=maxy;i++)
        {
            //记录扫描线与边线的交点
            int temp = 0;
            for(int i1 = 0, l = ThePolygon.m_VerticeNumber , j1 = l - 1; i1 < l; j1 = i1, i1++) {
    
                sx = ThePolygon.m_Vertex[i1].x;
                sy = ThePolygon.m_Vertex[i1].y;
                tx = ThePolygon.m_Vertex[j1].x;
                ty = ThePolygon.m_Vertex[j1].y;
                int lowy,heighty;
                lowy = (sy<ty)?sy:ty;
                heighty = (sy>ty)?sy:ty;
                //水平线
                if(ty == sy)
                {
                    if(i == ty)
                    {
                        int xmax,xmin;
                        xmax = (sx>tx)?sx:tx;
                        xmin = (sx<tx)?sx:tx;
                        for(int xx = xmin;xx<=xmax;xx++)
                        {
                            Point.x = xx;Point.y = i;
                            pDC->SetPixelV(Point, fillCol);
                        }
                    }
                    continue;
                }
                //没有交点
                if(i<lowy||i>heighty)
                    continue;
                x = sx + (i - sy) * (tx - sx) / (ty - sy);
                //判断交点(x,i)是不是顶点
                if((x == ThePolygon.m_Vertex[i1].x&&i == ThePolygon.m_Vertex[i1].y))
                {
                    //判断顶点是不是极值点  
                    //即判断与交点相关联的两条线的另外两个顶点是不是在交点的同一侧
                    if(i1!=l-1&&judge[i1] == 0){
                        if((i-ThePolygon.m_Vertex[i1+1].y)*(i-ThePolygon.m_Vertex[j1].y)<0)//异号
                            index[temp++] = x;
                        else//同号  极值点 记录两次
                        {
                            index[temp++] = x;
                            index[temp++] = x;
                        }
                    }
                    else if(i1 == l-1&&judge[i1]==0)
                    {
                        if((i-ThePolygon.m_Vertex[0].y)*(i-ThePolygon.m_Vertex[j1].y)<0){//异号
                            index[temp++] = x;
    
                        }
                        else//同号  极值点  记录两次
                        {
                            index[temp++] = x;
                            index[temp++] = x;
                        }
                    }
                    judge[i1] = 1;
                    continue;
                }
                else if((x == ThePolygon.m_Vertex[j1].x&&i == ThePolygon.m_Vertex[j1].y))
                {
                    if(j1 != 0&&judge[j1]==0){
                        if((i-ThePolygon.m_Vertex[i1].y)*(i-ThePolygon.m_Vertex[j1-1].y)<0){//异号
                            index[temp++] = x;
    
                        }
                        else//同号  极值点
                        {
                            index[temp++] = x;
                            index[temp++] = x;
                        }
    
                    }else if(j1 == 0&&judge[j1]==0)
                    {
                        if((i-ThePolygon.m_Vertex[i1].y)*(i-ThePolygon.m_Vertex[l-1].y)<0)//异号
                            index[temp++] = x;
                        else//同号  极值点
                        {
                            index[temp++] = x;
                            index[temp++] = x;
                        }
                    }
                    judge[j1] = 1;
                    continue;
                }
                //交点不是顶点
                index[temp++] = x;
            }
    
            //将index排序
            randqsort(index,0,temp);//随机快速
    
            //填充多边形
            for(int n=0,m=n+1;m<temp&&index[n]!=-1;n+=2,m=n+1)
            {
                for(int xx = index[n];xx<=index[m];xx++)
                {
                    Point.x = xx;Point.y = i;
                    pDC->SetPixelV(Point, fillCol);
                }
            }
            //清零
            for(int k=0;k<100;k++)
                index[k] = -1;
        }
        delete[] index;
        delete[] judge;
    }

    减少计算量。在绘制直线时,有一种DDA算法,它是利用(x,y)直接求出下一个点位于(x+1,y+m)或者(x+1/m, y+1)。在这里可以利用这一点。当已经得到y = e和多边形所有边的交点时,对于下一条扫描线y=e+1,如果没有新边与y=e+1相交,就可以推出y = e+1 和多边形所有边的交点。上述代码中没有实现这一点

    效果:(扫面线填充算法比直接暴力递归的四邻域种子填充算法快上许多)
    效果

    展开全文
  • 泰森多边形算法原理

    万次阅读 2018-03-08 16:21:20
    一、文档目的本文描述了在geomodel模块中,生成泰森多边形所使用的算法。二、概述GIS和地理分析中经常采用泰森多边形进行快速插值,和分析地理实体的影响区域,是解决邻接度问题的又一常用工具。荷兰气候学家A·H·...
    一、文档目的
    本文描述了在geomodel模块中,生成泰森多边形所使用的算法。
    二、概述
    GIS
    和地理分析中经常采用泰森多边形进行快速插值,和分析地理实体的影响区域,是解决邻接度问题的又一常用工具。

    荷兰气候学家A·H·Thiessen提出了一种根据离散分布的气象站的降雨量来计算平均降雨量的方法,即将所有相邻气象站连成三角形,作这些三角形各边的垂直平分线,于是每个气象站周围的若干垂直平分线便围成一个多边形。用这个多边形内所包含的一个唯一气象站的降雨强度来表示这个多边形区域内的降雨强度,并称这个多边形为泰森多边形。如图1,其中虚线构成的多边形就是泰森多边形。泰森多边形每个顶点是每个三角形的外接圆圆心。泰森多边形也称为Voronoi图,或dirichlet图。


    泰森多边形的特性是:
    1,每个泰森多边形内仅含有一个离散点数据。
    2,泰森多边形内的点到相应离散点的距离最近。
    3,位于泰森多边形边上的点到其两边的离散点的距离相等。
    泰森多边形可用于定性分析、统计分析、邻近分析等。例如,可以用离散点的性质来描述泰森多边形区域的性质;可用离散点的数据来计算泰森多边形区域的数据;判断一个离散点与其它哪些离散点相邻时,可根据泰森多边形直接得出,且若泰森多边形是n边形,则就与n个离散点相邻;当某一数据点落入某一泰森多边形中时,它与相应的离散点最邻近,无需计算距离。
    在泰森多边形的构建中,首先要将离散点构成三角网。这种三角网称为Delaunay三角网。


    三、Delaulay三角形的构建
    Delaunay
    三角网的构建也称为不规则三角网的构建,就是由离散数据点构建三角网,如图2,即确定哪三个数据点构成一个三角形,也称为自动联接三角网。即对于平面上n个离散点,其平面坐标为(xiyi)i12n,将其中相近的三点构成最佳三角形,使每个离散点都成为三角形的顶点。


    自动联接三角网的结果为所有三角形的三个顶点的标号,如:1,2,8;2,8,3;3,8,7;……

    为了获得最佳三角形,在构三角网时,应尽可能使三角形的三内角均成锐角,即符合Delaunay三角形产生的准则:

    1、任何一个Delaunay三角形的外接圆内不能包含任何其它离散点。

    2、相邻两个Delaunay三角形构成凸四边形,在交换凸四边形的对角线之后,六个内角的最小者不再增大。该性质即为最小角最大准则。



    下面介绍Tsai(1993)提出的在n维欧拉空间中构造Delaunay三角形的通用算法---凸包插值算法。

    (一)、凸包生成

    1、求出点集中满足min(x-y)、min(x+y)、max(x-y)、max(x+y)的四个点,并按逆时针方向组成一个点的链表。这4个点是离散点中与包含离散点的外接矩形的4个角点最近的点。这4个点构成的多边形作为初始凸包。

    2、对于每个凸包上的点I,设它的后续点为J,计算矢量线段IJ右侧的所有点到IJ的距离,求出距离最大的点K。

    3、将K插入I、J之间,并将K赋给J。

    4、重复2、3步,直到点集中没有在线段IJ右侧的点为止。

    5、将J赋给I,J取其后续点,重复2、3、4步。

    6、当凸包中任意相邻两点连线的右侧不存在离散点时,结束点集凸包求取过程。

    完成这一步后,形成了包含所有离散点的多边形(凸包),如图3所示。


    (二)、环切边界法凸包三角剖分

    在凸包链表中每次寻找一个由相邻两条凸包边组成的三角形,在该三角形的内部和边界上都不包含凸包上的任何其它点。将这个点去掉后得到新的凸包链表。重复这个过程,直到凸包链表中只剩三个离散点为止。将凸包链表中的最后三个离散点构成一个三角形,结束凸包三角剖分过程。


    完成这一步后,将凸包中的点构成了若干Delaunay三角形,如图4所示。


    (三)、离散点内插

    在对凸包进行三角剖分之后,不在凸包上的其余离散点,可采用逐点内插的方法进行剖分。基本过程为:

    1、选择一个尚未构成三角形的离散点

    2、在已经生成的三角形中,找出该离散点的三角形(离散点在该三角形在内部或者在该三角形的边上)

    3、如果离散点在三角形的内部,则将该三角形以及三角形的边删除,然后将三个顶点以及离散点分别连接,形成三个新的三角形。如果离散点在三角形的边上,记录点所在的边E,根据拓扑关系,找出该边的左右相邻三角形T1,T2,添加四条新边和四个新三角形NT,删除T1,T2以及边E。

    对于新生成的三角形,需要挨个对其边进行空外接圆检测。具体做法为:对于新生成的三角形的边E,找出该边相邻的两个三角形,判断该边一侧的对角的顶点是否位于另外一个三角形的外接圆的里面。如果是,则将边E删除,再将两个对角连接起来,形成两个新的三角形。对于新三角形的边,同样需要进行空外接圆检测,如此继续进行,直到所有新生成的三角形都通过空外接圆检测为止。

    4、重复1、2、3,直到所有非凸壳离散点都插入完为止。完成这一步后,就完成了Delaunay三角网的构建,如图5所示。


    四、泰森多边形的建立步骤

    建立泰森多边形算法的关键是对离散数据点合理地连成三角网,即构建Delaunay三角网。建立泰森多边形的步骤为:

    1、离散点自动构建三角网,即构建Delaunay三角网。对离散点和形成的三角形编号,记录每个三角形是由哪三个离散点构成的。

    2、找出与每个离散点相邻的所有三角形的编号,并记录下来。这只要在已构建的三角网中找出具有一个相同顶点的所有三角形即可。

     

                                                   图6 泰森多边形的建立

    3、对与每个离散点相邻的三角形按顺时针或逆时针方向排序,以便下一步连接生成泰森多边形。排序的方法可如图6所示。设离散点为o。找出以o为顶点的一个三角形,设为A;取三角形A除o以外的另一顶点,设为a,则另一个顶点也可找出,即为f;则下一个三角形必然是以of为边的,即为三角形F;三角形F的另一顶点为e,则下一三角形是以oe为边的;如此重复进行,直到回到oa边。

    4、计算每个三角形的外接圆圆心,并记录之。

    5、根据每个离散点的相邻三角形,连接这些相邻三角形的外接圆圆心,即得到泰森多边形。对于三角网边缘的泰森多边形,可作垂直平分线与图廓相交,与图廓一起构成泰森多边形。

    展开全文
  • 线段切割多边形算法

    2021-01-19 16:42:43
    一、问题:用一个线段集切割一个多边形,得到多个切割后的多边形。将其看成以点为节点的图结构,依次搜索最小的闭合区域。 三、算法思路: 1 所有线段求相交,得到所有点,并根据点和点之间的连接关系,得到有...

    大家好,分享一个几何算法思路,欢迎提出更优的方法!

    一、问题:用一个线段集切割一个多边形,得到多个切割后的多边形。将其看成以为节点的图结构,依次搜索最小的闭合区域。

     

    三、算法思路:

    1 所有线段求相交,得到所有点,并根据点和点之间的连接关系,得到有向图 (双向连接)

        vector<Point> AllPts;//所有的交点

        map<int,vector<int>> Graph;//有向图,key为节点下标,value为和其相连的点

    2 去掉所有悬空的线段(出度数+入度数<2)

    3 根据连通情况,将原始图划分为多个连通图(可用Union-Find算法)

     

    4 下面以一个连通图为研究对象,其实就是求最小的闭合区域:

    5 首先寻找外轮廓,

        auto LeftEdgePoint = FindLeftPoint(AllPts);//找到最左点

        vector<int> OutlinePath = FindClosedPath(Graph);//以最左点为起点,寻找外轮廓,结束条件为路径包含所有线段

        DeletePath(Graph,OutlinePath);//查找成功后,将查找到的连通关系从连通图中删除,得到如下的关系

    6 寻找最小闭合路径,直到所有节点被删掉

        while(!Graph.IsEmpty())

        {

            auto startPt = AllPts[Graph.First()];//找任意点为起点
            vector<int> OutlinePath = FindClosedPath(Graph);//寻找闭合轮廓,结束条件为路径不包含任何线段 
            DeletePath(Graph,OutlinePath);//查找成功后,将连通关系从连通图中删除

        }//算法结束

    7 FindClosedPath是核心函数,即在连通图中找到合法的闭合路径,可用回溯法

        vector<int> path;

        bool backTrack(int node){

            if(IsValidPath()) return true;//结束条件:路径闭合(nextPoint为path的起始点),并且不包含任何其他线段

            vector<int> links = Graph[node];//下一个节点

            foreach(auto link in links){//搜索可能性

                if(path.contains(link))continue;//不能回头

                path.push_back(link);//尝试可能性

                if(backTrack(link)) return true;//如果找到了,则返回

                path.Remove(path.end());//回溯

            }

            return false;

        }

    展开全文
  • C# 拓扑结构 多边形算法

    千次阅读 2018-09-29 18:31:52
    原作者... 原作者参考的论文 GIS中自动拓扑算法研究及组件化实现作者:王进宝 链接:https://pan.baidu.com/s/1nWWAxudGGFRvDTIgWsmnag 提取码:4dx9 using System...
  • OpenGL实现的用凸多边去裁剪任意多边形算法,手动画出直线,VS2008工程
  • 最新一个小项目,需要用到地图定义自由区域,并判断选点是否落在此区域内,思路是通过map的polygons中的points来定义多边形边界,通过polygons的fillColor 、strokeColor、strokeWidth来进行选区颜色的渲染。...
  • 逐边裁剪算法思想
  • ArcGIS中生成蜂窝多边形算法解析

    万次阅读 多人点赞 2016-03-28 12:39:45
    近来有不少同学,都有问我关于蜂窝多边形的问题,也就是正六边形,也就是下面这个东东: 一般的问答模式如下: 亲们问:ArcGIS里面那个工具可以做这个东东? 虾神答:额,没有原生的工具。 亲们问:那我看很多人...
  • 请看附件 Email:rxl_171@hotmail.com本人于2007-07-20 17:00 完全解决了任意多边形面积的计算机算法问题,本告示的承诺终止.我宣布面积为:348.225 周长为:279.57.
  • 运用循环单链表存储节点信息,利用向量叉积判断当前节点是不是凸点,是的话就把前后两个点输出来,构成一个三角形,删除本节点,否的话就什么也不做,知道剩下三个节点或者都是凹点。
  • 计算机图形学(简单多边形裁剪算法)简单多边形裁剪算法摘要:多边形裁剪算法与线性裁剪算法具有更广泛的实用意义,因此它是目前裁剪研究的主要课题。本文主要介绍了一种基于多边形顶点遍历的简单多边形裁剪算法,它...
  • //中点算法画圆弧 void drawB(){ int x=-50,y=50; double r=50; int H0=5-4*r; int xi=x,yi=y; int pian=200; glBegin(GL_POINTS); Set(xi+pian,yi+pian,1,0,0); while(xi){ if(H0){ H0...
  • 其实程序本身很小,但是需要一系列配置环境,boost,cgal,opencv配置环境。我的环境是在boost1.68版本,cgal 4.12版本,opencv3.4.2版本。
  • Python版 找到正方形轮廓 import cv2 import numpy as np img = np . zeros ( ( 200 , 200 ) , ...#计算近似的多边形框 hull = cv2 . convexHull ( cnt ) #计算凸形状 c++版
  • 多边形裁剪算法程序 多边形裁剪算法程序 多边形裁剪算法程序

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 30,665
精华内容 12,266
关键字:

多边形的算法