精华内容
下载资源
问答
  • 定理 1 在所有定边长的 NNN 边形中,圆内接凸...然后若多边形的各点不全共圆,一定能按如下方法找到面积更大的多边形,方法如下: 设多边形上的点组成的点集为 {G1、G2...GN}\{G_1、G_2 ... G_N\}{G1​、G2​...GN...

    定理 1

    在所有定边长NN 边形中,圆内接凸 NN 边形面积最大。
    *定边长指的是这些 NN 边形边集相等。

    定理 1 证明

    最优性证明

    首先凹多边形可以略去考虑,因为一定找到比其优的凸多边形。

    然后若多边形的各点不全共圆,一定能按如下方法找到面积更大的多边形,方法如下:
    设多边形上的点组成的点集为 {G1G2...GN}\{G_1、G_2 ... G_N\}(按顺时针编号),我们确定编号 3\ge 3 的点的位置,然后按顺序执行以下步骤:

    1. G1G2G3G4{G_1,G_2,G_3,G_4} 四点共圆,跳至第3步。
    2. 我们调整 G1G2G_1、G_2 的位置,使得 G1G2G3G4G_1'、G_2'、G_3、G_4 四点共圆,由扩展婆罗摩笈多公式1 知道 SG1G2G3G4>SG1G2G3G4S_{G_1'G_2'G_3G_4} > S_{G_1G_2G_3G_4},所以总面积一定变大。
    3. 如果所有点(这里指的是 NN 边形上的所有点)都共圆,结束;否则,从 G2G_2 开始重新顺时针编号(即 G2G_2 重编号为 G1G_1G3G_3 重编号为 G2G_2 …),然后跳转到第1步。

    由于该多边形各点不都共圆,所以按以上操作至少进行了一次2操作,即操作后的各点都共圆的多边形面积一定大于原多边形。

    于是我们证明了在各边长确定的情况下,圆内接多边形的面积一定大于非圆内接多边形的面积,即证明了其最优性。接下来我们证明其存在性

    存在性证明

    对于这些给定的 NN 条边,一定能找到一个半径足够大的圆能将这些边顺次排在上面,注意第 11 条边不一定与 第 NN 条边相接。
    如果相接,则这 NN 条边呈闭合态,即构造出了给定边长的圆内接 NN 边形。
    如果不相接,考虑缩小圆的半径,这样第 11 条边与 第 NN 条边的距离就会靠近,并且我们知道这个过程是连续平稳的,所以不断缩小的过程中必然会存在一个半径,使得两条边相接。
    所以定边长的圆内接多边形是存在的。

    其它

    注意原命题的形式,要求保证给定的 NN 条边能合法地构成 NN 边形。

    定理 2

    在所有定半径的圆内接 NN 边形中,正 NN 边形面积最大。
    *定半径指的是这些 NN 边形的外接圆半径相等。

    定理 2 证明

    设面积为 SS,则
    S=i=1NR2sinθi2S=\frac{\sum_{i=1}^{N}R^2sin \theta_i}{2} 其中 θi\theta_i 为圆内接 NN 边型的第 ii 条边所对的圆心角。

    设正弦函数 f(θ)=sinθf(\theta)=sin \theta容易知道其在 [0,π)[0,\pi) 上为上凸函数2。(不考虑多边形仅分布在圆的一侧的情况,因为一定不优,因此只需考虑此域值)
    S=R22i=1Nf(θi)S=\frac{R^2}{2}\sum_{i=1}^Nf(\theta_i)
    JensenJensen 不等式3
    i=1Nf(θi)Ni=1Nf(i=1NθiN)=i=1Nf(2πN)\frac{\sum_{i=1}^Nf(\theta_i)}{N} \le \sum_{i=1}^Nf(\frac{\sum_{i=1}^N\theta_i}{N})=\sum_{i=1}^Nf(\frac{2 \pi}{N})
    SR22Ni=1Nf(2πN)=SS_{一般多边形} \le \frac{R^2}{2}N\sum_{i=1}^Nf(\frac{2 \pi}{N})=S_{正多边形}
    证毕。


    1. 扩展婆罗摩笈多公式:https://baike.baidu.com/item/婆罗摩笈多公式/8780031 ↩︎

    2. 上凸函数:https://wenku.baidu.com/view/e9e94918cfc789eb162dc819.html ↩︎

    3. Jensen 不等式:https://baike.baidu.com/item/琴生不等式/397409?fr=aladdin ↩︎

    展开全文
  • 判定检测点是否在多边形方法,陈树强,陈学工,本文提出一种新方法以检测一个点是否在多边形内。该方法将矢量和射线法结合,彻底解决了射线法所具有奇异情况。实验结果证明
  • 针对正多边形渐变为圆的算法进行了研究,提出了两种算法:加边法,即通过增加正多边形边数的方法逐渐逼近于圆,当正多边形的边数足够多时,可以认为其是一个圆;倒角法,逐渐增加正多边的倒角半径,当倒角半径趋近等于正...
  • 实验结果证明,该方法具有简单、易实现、快速等优点。1.引言判断点在多边形内外是计算机图形学最基本算法,在计算机图形处理、模式识别、CAD 及科学计算可视化中有着广泛应用。判断点在多边形内外算法有主要...

    摘 要 本文提出一种新方法以检测一个点是否在多边形内。该方法将矢量和射线法结合,彻底解决了射线法所具有的奇异情况。实验结果证明,该方法具有简单、易实现、快速等优点。

    1.引言

    判断点在多边形内外是计算机图形学的最基本算法,在计算机图形处理、模式识别、CAD 及科学计算可视化中有着广泛的应用。判断点在多边形内外的算法有主要有定向射线法、角度法。角度法要使用复杂的三角运算,计算量大;在工程上应用最多的是定向射线法,这种方法简单、可靠,但其难以处理对边界点及边界与射线共线等特殊情况的处理。

    2.基本概念

    假设OA、OB是非零矢量,将OA绕点O旋转到与OB方向相同的位置时,所形成的角称为有向角<AOB。规定逆时针旋转为正方向,顺时针旋转为负方向。

    设线段s的两个顶点为a和b,则s与直线l所形成的关系可划分为三大类:(a)s有且仅有一个顶点(a或者b)在l上,称这种关系为半跨越;(b)s的两个顶点a和b分别在l的两侧,称这种关系为跨越;(c)s的两个顶点a和b在l的同一侧或线上,称这种关系为未跨越。

    过点Q作x正方向的水平射线l。若线段s跨越(或半跨越)射线l且与点Q所成的有向角为正,称为正向跨越(或正向半跨越),否则称为负向跨越(负向半跨越)。如图1

    ,线段P1P2、P3P4、P4P5、P6P7都属于正向半跨越直线l,P2P3、P5P6属于负向半跨越直线l,线段P7P8属于负向跨越直线l,线段P8P9、P0P1属于未跨越直线l。设线段s与射线l交于点k,那么线段s可以看作线段ak,kb组合而成(如图1中的P7P8可看作由P7k、kP8矢量和)。若将s与l的关系用f(s,l)的值来表示其权重,如下表示:

    3.多边形内外点判定算法

    在本文中,假定多边形P的顶点P0、P1、…,Pn(=P0)按逆时针方向存储,同样可将多边形看作有n条有向线段Si,即 (i=1,…,n-1),头尾相连而成。

    定理1.过平面上任意一点Q作x正方向的水平射线l,若∑f(Si,l)=0(其中i>=0,i<n),则点Q在多边形P外。

    证明:设射线l与多边形P的Si交点为kj,且kj不属于多边形P的顶点,则将交点分别插入到Pi、Pi+1之间形成两条有向线段Pikj、kjPi+1。将所有此类交点都添加进到顶点序列中,形成一个新的多边形P’,顶点序列为P0、…、Pi、kj、Pi+1、…Pm、kk、Pm+1、 Pn(=P0),如图2

    a)形成的顶点序列为P0、P1、k0、P2、P3、P0。因此多边形P’的有向线段与射线l的跨越情况全部转换为半跨越,如图2(b、c、d、e)四类情况。若将点Q与多边形P’的各个顶点相连,组成一系列有向角。在多边形P’中任选一个在射线l上的点ki作为起始点,则每两个交点之间的所有有向线段所组成的有向角的代数和的关系如图2(b、c、d、e)所示。显然可以得出时,有向角的角度代数和为0,所以点Q在多边形P’外,因P’与P同构,因此,点Q在多边形P外。

     

    定理2.过平面上任意一点Q作x正方向的水平射线l,若∑f(Si,l)=0(其中i>=0,i<n) 的值为2或者-2,则点Q在多边形P内。

    证明过程与定理1证明类似,可以得出 值为2或者-2时,有向角的角度代数和为360或者-360度,从而可以得出点Q在多边形P内。

    算法的具体描述:

    1)获得一个点Pi相对与点Q的位置,如果Pi的y坐标值大于Q的y坐标值,status=1,若小于,则status=-1,否则statue=0;用lastStatus记录上一点的相对位置值。cnt表示f(si,l)的代数和。

    2)temp = status – lastStatus;

         if(temp > 0)

         {

           if(点Q在有向线段Pi-1Pi的右侧)

             cnt = cnt + temp;

                 else if (点Q在有向线段Pi-1Pi上)

            return(“点Q在有向线段Pi-1Pi上”);

       }

             else if(temp < 0)

             {

    if(点Q在有向线段Pi-1Pi的左侧)

                cnt = cnt + temp;

                    else if (点Q在有向线段Pi-1Pi上)

               return(“点Q在有向线段Pi-1Pi上”);

          }

    3)循环(2),直到多边形所有的顶点遍历完毕,

    if(cnt == 0)

            return(“点在多边形外”);

           else return(“点在多边形内”);

    4.算法分析和小结

    射线法的复杂度为O(n),本文算法的复杂度也为O(n)。射线法中对每一条边都要进行两次以上的乘法运算,而本算法只对跨越或者半跨越射线的边最多进行一次叉积运算;射线法需要对奇异情况进行特殊处理,而本算法彻底解决了奇异情况的发生。在本文中,最坏的情况是所需的计算量为(8次加减运算,2次乘法运算)*n。

     

    展开全文
  • * 求取多边形的中心位置(该方法是最原始版,之前因为用的少,所以没有发觉到逻辑上存在错误)~ * Added By Bruce Yang on 2012.09.02.15.30~ * 实践证明,这个方法的逻辑是错误的,汲取这个教训~ */ +(b2Vec2) ...

    今天下午做了一下游戏功能的扩充,不料又落马了,记录一下~

    /**
     * 求取多边形的中心位置(该方法是最原始版,之前因为用的少,所以没有发觉到逻辑上存在错误)~
     * Added By Bruce Yang on 2012.09.02.15.30~
     * 实践证明,这个方法的逻辑是错误的,汲取这个教训~
     */
    +(b2Vec2) getPolyCenterLogicWrong0:(BYPolygon*)polygon {
        b2Vec2* vertices = polygon.vertices;
        int iVerticesCount = polygon.verticesCount;
        float xSum = 0.0f;
        float ySum = 0.0f;
        for(int i = 0; i < iVerticesCount; ++ i) {
            xSum += vertices[i].x;
            ySum += vertices[i].y;
        }
        return b2Vec2(xSum / iVerticesCount, ySum / iVerticesCount);
    }
    
    
    /**
     * Added on 2012.09.02.12.46~
     * 发现上面方法的错误以后,我做了一个修正,发现错误依然存在,甚至一度让我深陷泥潭~
     */
    +(b2Vec2) getPolyCenterLogicWrong1:(BYPolygon*)polygon {
        b2Vec2* vertices = polygon.vertices;
        int iVerticesCount = polygon.verticesCount;
        
        float fMinX = 0, fMaxX = 0;
        float fMinY = 0, fMaxY = 0;
        for(int i = 0; i < iVerticesCount; ++ i) {
            b2Vec2 item = vertices[i];
            if(item.x < fMinX) {
                fMinX = item.x;
            } else if(item.x > fMaxX) {
                fMaxX = item.x;
            }
            
            if(item.y < fMinY) {
                fMinY = item.y;
            } else if(item.y > fMaxY) {
                fMaxY = item.y;
            }
        }
        return b2Vec2((fMinX + fMaxX) / 2.0f, (fMinY + fMaxY) / 2.0f);
    }
    
    
    /**
     * Added on 2012.09.02.12.46~
     * 备注:求取多边形矩形包围框的中心点的终极版方法~
     * 让我迷茫了许久啊,数学没学好脑筋就是转不灵光,哎...
     */
    +(b2Vec2) getPolyCenterFixed:(BYPolygon*)polygon {
        b2Vec2* vertices = polygon.vertices;
        int iVerticesCount = polygon.verticesCount;
        
        float fMinX, fMaxX, fMinY, fMaxY;
        for(int i = 0; i < iVerticesCount; ++ i) {
            b2Vec2 item = vertices[i];
            if(i != 0) {
                if(item.x < fMinX) {
                    fMinX = item.x;
                }
                if(item.x > fMaxX) {
                    fMaxX = item.x;
                }
                if(item.y < fMinY) {
                    fMinY = item.y;
                }
                if(item.y > fMaxY) {
                    fMaxY = item.y;
                }
            } else {
                fMinX = item.x;
                fMaxX = item.x;
                fMinY = item.y;
                fMaxY = item.y;
            }
        }
        
        return b2Vec2((fMinX + fMaxX) / 2.0f, (fMinY + fMaxY) / 2.0f);
    }





    展开全文
  • unique是很关键一步,不可省略...这里排序方法非常好用,不用单独写一个cmp函数了,相当于直接把这个函数写在sort下面 qreal DataConvert::getCrossProduct(const QPointF &iPointA,const QPointF &i

    unique是很关键的一步,不可省略,一般的题目都给定了不会有重合点,但是实际项目应用里保不准。

    可以证明,交点不会出现在凸包上。

    这里的排序方法非常好用,不用单独写一个cmp函数了,相当于直接把这个函数写在sort下面



    qreal DataConvert::getCrossProduct(const QPointF &iPointA,const QPointF &iPointB,const QPointF &iPointC){//获得a->b和a->c的叉积
        //x1y2-x2y1
        return ((iPointB.x()-iPointA.x())*(iPointC.y()-iPointA.y())-(iPointC.x()-iPointA.x())*(iPointB.y()-iPointA.y()));
    }
    QPolygonF DataConvert::getPolysConvexHull(const QPolygonF &iFirstPoly, const QPolygonF &iSecondPoly){//获取两个poly的凸包
        if(iFirstPoly.size()==0)return iSecondPoly;
        if(iSecondPoly.size()==0)return iFirstPoly;
        int Size1=iFirstPoly.size();
        int Size2=iSecondPoly.size();
        //第一步把所有结点取出来
        QVector<QPointF>AllPoints;
        for(int i=0;i<Size1;i++){
            AllPoints.push_back(iFirstPoly[i]);
        }
        for(int i=0;i<Size2;i++){
            AllPoints.push_back(iSecondPoly[i]);
        }
        //其实交点可以不加,因为交点一定不属于凸包,凸包一定是两个多边形顶点的子集
    //    for(int i=0;i<Size1;i++){
    //        QLineF FirstLine=QLineF(iFirstPoly[i],iFirstPoly[(i+1)%Size1]);
    //        //AllPoints.push_back(FirstLine.p1());
    //        for(int j=0;j<Size2;j++){
    //            QLineF SecondLine=QLineF(iSecondPoly[j],iSecondPoly[(j+1)%Size2]);
    //            //AllPoints.push_back(SecondLine.p1());
    //            QPointF intersectionPoint;
    //            int interV=FirstLine.intersect(SecondLine,&intersectionPoint);
    //            if(interV==1)AllPoints.push_back(intersectionPoint);
    //        }
    //    }
        //第二步,寻找基点,此步可以并到第一步里,但是为了代码清晰,便于阅读,多O(n)的复杂度也不太影响
        int startPosition=0;
        for(int i=0;i<AllPoints.size();i++){
            if(AllPoints[startPosition].y()>AllPoints[i].y()||
                    (AllPoints[startPosition].y()==AllPoints[i].y()&&AllPoints[startPosition].x()>AllPoints[i].x())){
                startPosition=i;
            }
            //AllPoints.swap()
        }
        if(startPosition>0){
            qSwap(AllPoints[0],AllPoints[startPosition]);
        }
        //第三,给点按照与基点的叉积排序
        qSort(AllPoints.begin()+1,AllPoints.end(),[=](const QPointF &aa,const QPointF &bb){
            qreal crossAns=DataConvert::getCrossProduct(AllPoints[0],aa,bb);
            qreal length1=QLineF(AllPoints[0],aa).length();
            qreal length2=QLineF(AllPoints[0],bb).length();
            return (crossAns>0||(crossAns==0&&length1>length2));
        });
        for(int i=0;i<AllPoints.size();i++){
            qDebug()<<AllPoints[i].x()<<" fuck "<<AllPoints[i].y()<<"\n";
        }
        //第四unique
        QVector<QPointF>uniquePoints;
        for(int i=0;i<AllPoints.size();i++){
            uniquePoints.push_back(AllPoints[i]);
            int j=i;
            while(i<AllPoints.size()){
                if(DataConvert::fuzzyEqual(AllPoints[(i+1)%AllPoints.size()].x(),AllPoints[j].x())&&
                        DataConvert::fuzzyEqual(AllPoints[(i+1)%AllPoints.size()].y(),AllPoints[j].y())){
                    i++;
                }
                else break;
            }
        }
        //第五开始算凸包
        int s[1000];
        s[0]=0;
        s[1]=1;
        int top=1;
        for(int i=2;i<uniquePoints.size();i++){
            while(top&&DataConvert::getCrossProduct(uniquePoints[s[top-1]],uniquePoints[s[top]],uniquePoints[i])<0)top--;
            s[++top]=i;
        }
        top++;
        qDebug()<<"top  "<<top<<"\n";
        //把凸包里的点组成新的poly输出
        QPolygonF newpoly;
        for(int i=0;i<top;i++){
            newpoly.push_back(uniquePoints[s[i]]);
        }
        return newpoly;
    }


    展开全文
  • 本文讨论了闵可夫斯基和的逆问题(称为闵可夫斯基和分解),即将一个凸多边形分解为两个更为简单的凸多边形的问题,首先通过三角分解的方法证明了凸多边形闵可夫斯基和分解的存在性,在此基础上研究了在边个数和面积...
  • 本文参考自:点击打开链接 利用向量积(叉积)计算三角形的面积和多边形的面积 包含详细证明方法
  • 提取条纹中心线是线条结构中关键步骤光扫描视觉测量系统。 它直接决定了从图像获得三维点云。 由于反射率和/或物体表面颜色,照明条件变化和其他因素, 图像中条纹灰度值和... 这证明了有效性方法的实用性。
  • 在这项工作中,我们借助Baxter Q -operator和Sklyanin变量分离方法解决了该模型。 我们为GKP激发特征函数和特征值提供了一个明确构造。 我们演示了前者如何在超级Wilson循环中定义所谓多粒子六边形转变,并...
  • 提出了一种适合等值线图裁剪处理算法,该算法通过构造扫描带,然后对落在每条扫描带内线段进行处理,从而获得等值线在裁剪...用实际大量数据进行了多边形区域裁剪测试,实践证明,这种方法可行且提高了效率。
  • 为了提高无网格法计算效率,该文提出一种新型MLPG法——多边形无网格法,该方法采用改进PU函数作为形函数,试探函数预先满足位移边界条件;...分析实例证明多边形无网格法是一种精确和实用数值方法
  • 探讨了平面多边形的Voronoi图的性质,提出了一种新的求解平面多边形的Voronoi图的算法,其核心思想是单独考虑每个Voronoi图对象,分开计算其分治区,然后再构成一个具有拓扑关系的Voronoi图.这种计算方法较其他现有...
  • <br />阿基米德证明圆面积和周长关系的方法 它把面积看成一个无穷多边性的接近,设多边形的边到中心的距离为h, 则有: S=1/2*h*b+1/2*h*b+...+1/2*h*b Go S=1/2*h*(b+b+...+b) ...
  • 所谓星形多边形,指是这样的多边形:在其内部至少有一点P,其余任何一个在多边形内(包含边上)点和P点连线都在多边形内,P称为中点,通常一个星形多边形有不止一个中点。 判定方法是先将所有边两两求出交点...
  • 多场多边形弹跳

    2020-04-03 17:46:19
    方法首先针对三个时空维度和四个时空维度单场情况开发,并在经典势能示例以及量子涨落计算上得到了证明。 考虑到更高阶校正,系统考虑了超出线性阶电位系统扩展,这为多个标量场铺平了道路。 因此,...
  • 本文中的Jordan曲线定理(JCT)的证明集中于图形说明和分析方法,以使拓扑证明更易于理解,并且基于Tverberg的方法,该方法被认为是相当深奥的,没有图形解释。 初步构造了约旦多边形的参数化模型。 引入四个引理花...
  •  我们曾经用两种巧妙的方法证明了这样一个... y 和 z 这两个点就把整个多边形的边界分成了两个部分。   <br />  回忆登山引理的内容:对于两个函数值从 0 连续地变到 1 的“折线段函数” f(x) 和
  • 但此时,前一节我们用到两种证明方法现在都派不上用场了,我们需要用到一些全新手段。下面这个证明真可谓是巧妙到了诡异地步,真不知是谁想出来。 对于多边形边界上任意两点 A(x1, y1) 、 B(x2, y2) ,...
  • 我们知道多边形可以分为多个三角形,而三角形面积可以利用叉乘的方法计算 S = 1/2 * | AB | * | AC | * sin( A ), 而AB 和 AC 就是 向量。 注意:每一次使用叉乘求面积,不能加绝对值,因为每一步叉乘求...
  • 介绍了该算法中用到的简单要素类多边形合并算子, 利用对重合边的判断来进行多边形的合并; 最后对提出的算法进行了实验分析。实验证明, 本算法在进行大数据的多边形集合合并时效率较高, 基于本算法开发的功能用于实际...
  • 针对曲线结构特征,引入极化角点指数作为特征角点候选依据,提出了一种与曲线起始点位置无关基于角点检测的多边形近似算法。实验证明,此方法快速有效,结果稳定,噪声抑制效果较好。
  • 在本文中,提出了一种用于检测任意三角形,正多边形和圆形通用框架,该... 现有技术对合成图像和自然图像比较实验也证明,在最坏条件下,基于PLDD的方法在最大时间复杂度O(n(2))情况下性能更强大,更准确。
  • 1、求π\piπ的方法 我们在代码中一般把π\piπ记作PI,PI = acos(-1)。因为我们都知道cos(π\piπ) = -1,所以PI = arccos(-1)。 acos() 2、余弦定理 c^2 = a^2 + b^2 - 2acos(t); 3、向量 (1)向量加、减、数乘...
  • 如果所讨论的点不在多边形的边界上,则该点在外部时为偶数,在内部时为奇数。 该算法基于一个简单的观察,如果一个点沿着一条射线从无穷远移动到探测点,并且如果它穿过多边形的边界,可能多次,那么它交替地从外...
  • [???]多边形面积

    2010-11-07 17:18:00
    这道题其实很简单,题目中给条件太特殊了,其实网上面就有一般性计算几何的方法,具体不介绍了,就是S=SUM{x[i-1]*y[i]-x[i]*y[i-1]}/2 i=1,2,3,...n,其中x[0]=x[n],y[0]=y[n],具体可以用叉积证明,在这里就不...
  • 这道题其实很简单,题目中给条件太特殊了,其实网上面就有一般性计算几何的方法,具体不介绍了,就是S=SUM{x[i-1]*y[i]-x[i]*y[i-1]}/2 i=1,2,3,...n,其中x[0]=x[n],y[0]=y[n],具体可以用叉积证明,在这里就不...
  • 容斥原理证明及应用

    千次阅读 2018-09-30 23:28:43
    普通容斥原理 例题 给定平面上n个多边形,请求出其覆盖总面积。 n≤10,&amp;nbsp;边数≤50,000n\le 10,~边数\le 50,...该方法实现较为复杂,在多边形数量多时候占优势,但是边数很多情况下就显得力不...

空空如也

空空如也

1 2 3 4
收藏数 72
精华内容 28
关键字:

多边形的证明方法