精华内容
下载资源
问答
  • 在许多点中找出包围这些点的最小凸多边形,界面使用Qt实现,如要运行exe文件需要电脑上装有Qt或有相关库文件,不过算法和界面是没多大关系的……
  • js计算最小凸多边形

    2018-12-12 16:22:00
    本质上,用户希望出现的是凸多边形而不是凹多边形,需求进一步抽象就是我们需要根据用户在地图上绘制的点计算最小凸多边形,根据需求我在网上找到了一个算法地址如下 https://www.nayuki.io/page/convex...

    最近在做项目的时候遇到一个需求:要求用户可以在地图上绘制多边形,项目中使用的是高德地图,由于无法限制用户绘制的方式,可能出现下图的情况

    用户期望的效果如下图所示

    本质上,用户希望出现的是凸多边形而不是凹多边形,需求进一步抽象就是我们需要根据用户在地图上绘制的点计算最小的凸多边形,根据需求我在网上找到了一个算法地址如下

    https://www.nayuki.io/page/convex-hull-algorithm

    提供多个语言版本,根据需要下载源码

    转载于:https://www.cnblogs.com/whyly/p/10103881.html

    展开全文
  • 最近在做的一个项目中,遇到一个求解包含所有已知点的最小凸多边形问题

    最近所做的一个项目中,需要求解包含所有已知点的最小凸多边形,该问题可以通过递归地寻找最大内角从而寻找到最小凸多边形的边界,相信只要会一两种语言,都可以顺利地写出代码,所以这里不对该算法思路进行探讨,而是从 MATLAB 已有的 Delaunay 三角剖分算法出发,寻找所有剖分出的三角形中仅出现了一次的边界,这些边界就是其最小凸多边形的边界,最后再通过边界跟踪,即可锁定最小凸多边形的边界顺序,从而求解该问题。


    该算法的总体思路如下:

    1、利用 delaunay 函数,对所有数据点进行 Delaunay 三角剖分处理,delaunay 函数的返回值是一个 N * 3 的矩阵,其中 N 为剖分出的三角形个数,3 为每个三角形的三个端点的序号。例如,执行如下语句,可直观地观察剖分结果。

    points = [0, 15, 30, 26, 26, 0; 0, 3, 10, 20, 12, 0];
    triangles = delaunay(points(1, :), points(2, :));
    triplot(triangles, points(1, :), points(2, :));

    其中,triangles 是一个 4 * 3 矩阵:

    triangles =
    
         5     3     4
         1     2     4
         2     5     4
         2     3     5



    2、根据 triangles 矩阵,提取出所有 delaunay 三角剖分时所连接的边,例如 triangles(1, :) = [5, 3, 4], 则其连接的边有 [3, 4], [3, 5], [4,5]。依次扫描 triangles 矩阵的每一行,将 delaunay 三角剖分时所连接的边添加到一个新的矩阵中,最后构成一个 M * 2 的矩阵,其中 M 是一共所连接的边的条数。

    3、显然,直观可见,最小凸多边形上的边应该仅在以上矩阵中出现一次,因此,将以上矩阵中那些出现次数超过一次的边全部去掉,最后保留的便是最小凸多边形的边。

    4、根据最小凸多边形的边,很容易得到构成最小凸多边形的结点的顺序,从而解决问题。


    以下代码综合了以上所有步骤,输入参数 points 是一个 2 * P 矩阵, P 为数据点的个数,第一行是这些数据点对应的 x 坐标,第二行是对应的 y 坐标;输出参数 polygon 是一个 2 * Q 矩阵, Q 为凸多边形的顶点个数(首尾相连),第一行是这些顶点对应的 x 坐标,第二行是对应的 y 坐标。可以在 这里 下载相应文件。

    function polygon = minimal_convex_polygon(points)
        % 进行 delaunay 三角剖分,将所有连接了的边保存在矩阵 lines 中
    	triangles = sort(delaunay(points(1, :), points(2, :)), 2);
    	lines = zeros(size(triangles, 1) * 3, 2);
    	for i = 1:size(triangles, 1)
    		lines(3 * i - 2,:) = [triangles(i, 1), triangles(i, 2)];
    		lines(3 * i - 1,:) = [triangles(i, 1), triangles(i, 3)];
    		lines(3 * i,:) = [triangles(i, 2), triangles(i, 3)];
        end
        % 去掉 lines 中出现次数超过一次的边
    	[~, IA] = unique(lines, 'rows');
    	lines = setdiff(lines(IA, :), lines(setdiff(1:size(lines, 1), IA), :), 'rows');
        % 跟踪 lines 中的数据点,将凸多边形的顶点编号保存在 seqs 中
    	seqs = zeros(size(lines, 1) + 1,1);
    	seqs(1:2) = lines(1, :);
    	lines(1, :) = [];
    	for i = 3:size(seqs)
    		pos = find(lines == seqs(i - 1));
    		row = rem(pos - 1, size(lines, 1)) + 1;
    		col = ceil(pos / size(lines, 1));
    		seqs(i) = lines(row, 3 - col);
    		lines(row, :) = [];
        end
        % 根据 seqs , 得到凸多边形顶点坐标
    	polygon = points(:, seqs);
    end


    测试:

    points = [0, 15, 30, 26, 26, 0, 20, 10; 0, 3, 10, 20, 12, 0, 12, 4];
    plot(points(1, :), points(2, :), '*r', 'LineWidth', 4);
    polygon = minimal_convex_polygon(points);
    hold on;
    plot(polygon(1, :), polygon(2, :), 'LineWidth', 2);



    展开全文
  • import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; public final class ConvexHull { ... /*返回一个新的点列表...壳不包括共线点。 该算法在O(n lo...
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.Objects;
    
    
    public final class ConvexHull {
    
        /*返回一个新的点列表,该列表表示
        给定的一组点。凸壳不包括共线点。
        该算法在O(n logn)时间内运行*/
        public static List<Point> makeHull(List<Point> points) {
            List<Point> newPoints = new ArrayList<>(points);
            Collections.sort(newPoints);
            return makeHullPresorted(newPoints);
        }
    
    
        // 返回凸面外壳,假设每个点[i]<=点[i+1]。在O(n)时间内运行。
        public static List<Point> makeHullPresorted(List<Point> points) {
            if (points.size() <= 1)
                return new ArrayList<>(points);
    
            // 安德鲁算法(凸包)。正y坐标对应于“向上”
            //按照数学惯例,而不是按照计算机的“向下”
            //图形约定。这并不影响结果的正确性。
    
            List<Point> upperHull = new ArrayList<>();
            for (Point p : points) {
                while (upperHull.size() >= 2) {
                    Point q = upperHull.get(upperHull.size() - 1);
                    Point r = upperHull.get(upperHull.size() - 2);
                    if ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x))
                        upperHull.remove(upperHull.size() - 1);
                    else
                        break;
                }
                upperHull.add(p);
            }
            upperHull.remove(upperHull.size() - 1);
    
            List<Point> lowerHull = new ArrayList<>();
            for (int i = points.size() - 1; i >= 0; i--) {
                Point p = points.get(i);
                while (lowerHull.size() >= 2) {
                    Point q = lowerHull.get(lowerHull.size() - 1);
                    Point r = lowerHull.get(lowerHull.size() - 2);
                    if ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x))
                        lowerHull.remove(lowerHull.size() - 1);
                    else
                        break;
                }
                lowerHull.add(p);
            }
            lowerHull.remove(lowerHull.size() - 1);
    
            if (!(upperHull.size() == 1 && upperHull.equals(lowerHull)))
                upperHull.addAll(lowerHull);
            return upperHull;
        }
    
    }
    
    
    final class Point implements Comparable<Point> {
    
        public final double x;
        public final double y;
    
    
        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }
    
    
        public String toString() {
            return "Point(" + x + "," + y + ")";
        }
    
    
        public boolean equals(Object obj) {
            if (!(obj instanceof Point))
                return false;
            else {
                Point other = (Point)obj;
                return x == other.x && y == other.y;
            }
        }
    
    
        public int hashCode() {
            return Objects.hash(x, y);
        }
    
    
        public int compareTo(Point other) {
            if (x != other.x)
                return Double.compare(x, other.x);
            else
                return Double.compare(y, other.y);
        }
    
    }
    

     

    凸包可以理解为在木板上钉了许多钉子,然后用一根橡皮筋框住所有钉子时所得到的多边形。

    安德鲁算法:

    1.将给定集合的点按x坐标升序排列,x相同的按y坐标升序排列。

    2.按下述流程创建凸包的上部

    将排序后的点按照x坐标从小到大的顺序加入凸包U。如果新加入的点使得U不再是凸多边形,则逆序删除之前加入U的点,直到U重新成为凸多边形为止。

    3.按下述流程创建凸包的下部

    将排序后的点按照x坐标从大到小的顺序加入凸包L。如果新加入的点使得L不再是凸多边形,则逆序删除之前加入L的点,直到L重新成为凸多边形为止。

    展开全文
  • (hdu step 7.1.7)Wall(求凸包的周长——求将全部点围起来的最小凸多边形的周长) 题目:WallTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s)...

    题目:

    Wall

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 119 Accepted Submission(s): 47
     
    Problem Description
    Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the King's castle. The King was so greedy, that he would not listen to his Architect's proposals to build a beautiful brick wall with a perfect shape and nice tall towers. Instead, he ordered to build the wall around the whole castle using the least amount of stone and labor, but demanded that the wall should not come closer to the castle than a certain distance. If the King finds that the Architect has used more resources to build the wall than it was absolutely necessary to satisfy those requirements, then the Architect will loose his head. Moreover, he demanded Architect to introduce at once a plan of the wall listing the exact amount of resources that are needed to build the wall.
    Your task is to help poor Architect to save his head, by writing a program that will find the minimum possible length of the wall that he could build around the castle to satisfy King's requirements.



    The task is somewhat simplified by the fact, that the King's castle has a polygonal shape and is situated on a flat ground. The Architect has already established a Cartesian coordinate system and has precisely measured the coordinates of all castle's vertices in feet.
     
    Input
    The first line of the input file contains two integer numbers N and L separated by a space. N (3 <= N <= 1000) is the number of vertices in the King's castle, and L (1 <= L <= 1000) is the minimal number of feet that King allows for the wall to come close to the castle.

    Next N lines describe coordinates of castle's vertices in a clockwise order. Each line contains two integer numbers Xi and Yi separated by a space (-10000 <= Xi, Yi <= 10000) that represent the coordinates of ith vertex. All vertices are different and the sides of the castle do not intersect anywhere except for vertices.
     
    Output
    Write to the output file the single number that represents the minimal possible length of the wall in feet that could be built around the castle to satisfy King's requirements. You must present the integer number of feet to the King, because the floating numbers are not invented yet. However, you must round the result in such a way, that it is accurate to 8 inches (1 foot is equal to 12 inches), since the King will not tolerate larger error in the estimates.

    This problem contains multiple test cases!

    The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.

    The output format consists of N output blocks. There is a blank line between output blocks.
     
    Sample Input
    1
    
    9 100
    200 400
    300 400
    300 300
    400 300
    400 400
    500 400
    500 200
    350 200
    200 200
     
    Sample Output
    1628
     
     
    Source
    Northeastern Europe 2001
     
    Recommend
    JGShining


    题目分析:

                   求凸包的周长。再求图报的周长前。首先要做的是计算凸包——找到将全部点围起来的最小凸多边形。

    对于找到凸包的算法,下面代码用的是graham算法。对这个算法不太熟悉的童鞋能够先看一下:

    http://blog.csdn.net/hjd_love_zzt/article/details/44311333


    代码例如以下:

    /*
     * g.cpp
     *
     *  Created on: 2015年3月16日
     *      Author: Administrator
     */
    
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    
    const double epsi = 1e-8;
    const double pi = acos(-1.0);
    const int maxn = 1001;
    
    
    struct PPoint{//结构体尽量不要定义成Point这样的,easy和C/C++本身中的变量同名
    	double x;
    	double y;
    
    	PPoint(double _x = 0,double _y = 0):x(_x),y(_y){
    
    	}
    
    	PPoint operator - (const PPoint& op2) const{
    		return PPoint(x - op2.x,y - op2.y);
    	}
    
    	double operator^(const PPoint &op2)const{
    		return x*op2.y - y*op2.x;
    	}
    };
    
    
    inline int sign(const double &x){
    	if(x > epsi){
    		return 1;
    	}
    
    	if(x < -epsi){
    		return -1;
    	}
    
    	return 0;
    }
    
    inline double sqr(const double &x){
    	return  x*x;
    }
    
    
    inline double mul(const PPoint& p0,const PPoint& p1,const PPoint& p2){
    	return (p1 - p0)^(p2 - p0);
    }
    
    
    inline double dis2(const PPoint &p0,const PPoint &p1){
    	return sqr(p0.x - p1.x) + sqr(p0.y - p1.y);
    }
    
    inline double dis(const PPoint& p0,const PPoint& p1){
    	return sqrt(dis2(p0,p1));
    }
    
    int n;
    double l;
    PPoint p[maxn];
    PPoint convex_hull_p0;
    
    
    inline bool convex_hull_cmp(const PPoint& a,const PPoint& b){
    	return sign(mul(convex_hull_p0,a,b)>0)|| sign(mul(convex_hull_p0,a,b)) == 0 && dis2(convex_hull_p0,a) < dis2(convex_hull_p0,b);
    }
    
    
    /**
     * 计算点集a[]的凸包b[]。

    当中点集a有n个元素 */ int convex_hull(PPoint* a,int n,PPoint* b){ if(n < 3){//假设顶点数小于3,构不成一个凸包 //输出失败信息 printf("wrong answer ,cause of n smaller than 3\n"); return -1; } int i; for(i = 1 ; i < n ; ++i){//遍历点集中的每个点 //寻找最低点(所谓的最低点就是最靠左下角的点) if(sign(a[i].x - a[0].x) < 0 || (sign(a[i].x - a[0].x) == 0 && sign(a[i].y < a[0].y) < 0 )){ swap(a[i],a[0]); } } convex_hull_p0 = a[0]; sort(a,a+n,convex_hull_cmp);//排序 int newn = 2; b[0] = a[0]; b[1] = a[1]; /** * 在剩下的点中不断前进,假设当前点在前进方向左側, * 则将当前点进栈,否则将近期入栈的点出栈.知道当前点在前进方向的左側 */ for(i = 2 ; i < n ; ++i){ while(newn > 1 && sign(mul(b[newn-1],b[newn-2],a[i])) >= 0){ newn--; } b[newn++] = a[i];//江当前点进栈 } return newn;//返回栈顶指针 } int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d %lf",&n,&l); int i; for(i = 0 ; i < n ; ++i){ scanf("%lf %lf",&p[i].x,&p[i].y); } n = convex_hull(p,n,p); p[n] = p[0]; double ans = 0; for(i = 0 ; i < n ; ++i){//求凸包的周长 ans += dis(p[i],p[i+1]); } ans += 2*pi*l;//加上外面围墙的周长 /** * "."后面的是小数精度控制,这里由于是浮点型。则取零代表不显示小数点(取整) * .不为零时代表最大小数位数 */ printf("%.0lf\n",ans); if(t != 0){//每个输出后面都要跟一个换行 printf("\n"); } } return 0; }





    posted on 2017-06-06 08:31 mthoutai 阅读(...) 评论(...) 编辑 收藏

    转载于:https://www.cnblogs.com/mthoutai/p/6949582.html

    展开全文
  • 题意:给出n个点,求能全部覆盖这些点的最小凸多边形周长 思路:用栈,满足条件的点(角最大且凸)放入栈 栈里的01代表0点,12代表1点,每次判断一个点,如点2,需要判断向量21与向量23的叉积>0,共线不...
  • 一、点云凸包 最小凸多边形也叫作凸包,就是将最外层的点连接起来,它能包含点集中所有的点。 最流行的凸包算法是Graham扫描(Graham scan)算法和Preparata & Hong提出的“分而治之”(Divide-and-Conquer)算法。这...
  • 题目:一幅图像,背景为黑色,其中包含一些白色孤点,求包含白色点的最小凸多边形。 比如图像: 思路:首先找到最下方的白色点。然后遍历每个白色点,求出当前点V1与每个白色点连成的方向向量。找出与单位...
  • 题目: Wall Time Limit: 2000/1000 MS ...再求图报的周长前,首先要做的是计算凸包——找到将所有点围起来的最小凸多边形。 对于找到凸包的算法,以下代码用的是graham算法,对这个算法不太熟悉的童鞋可以先看一下: ...
  • 题意:Surround the TreesTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 209 Accepted Submission(s): 104 Problem DescriptionThere are a lot of ...
  • 凸多边形直径】POJ - 2187 - Beauty Contest 题目链接http://poj.org/problem?id=2187 #include<iostream> #include<stdio.h> #include<algorithm> #include<math...
  • 博客...首先,用多边形逆时针顶点的集合来表示凸多边形。 其次,图形描述-结构描述。 分析,最优子结构性质。 分析,最优三角分解递归结构。 最后,最优值计算。
  • 凸多边形最小距离

    千次阅读 2013-09-24 17:31:59
    给定两个非连接(比如不相交)的凸多边形 P 和 Q, 目标是找到拥有最小距离的点对 (p,q) (p 属于 P 且 q 属于Q)。  事实上, 多边形非连接十分重要, 因为我们所说的多边形包含其内部。 如果多边形...
  • 凸多边形最小面积四边形包围盒算法
  • 凸多边形最小面积外接矩形

    千次阅读 2017-11-04 11:24:08
    给定一个凸多边形 P , 面积最小的能装下 P (就外围而言)的矩形是怎样的呢? 从技术上说, 给定一个方向, 能计算出 P 的端点并且构由此造出外接矩形。 但是我们需要测试每个情形来获得每个矩形来计算最小面积吗?...
  • 凸多边形最小面积包围矩形

    千次阅读 2014-02-23 20:08:03
    计算几何中有这样一条结果:凸多边形最小包围矩形至少有一条边与多边形的一条边共线。 于是遍历每一条边构造包围矩形比较面积大小。说是构造包围矩形,其实只需要投影点到边以及垂直边上取距离最远两点距离得长宽...
  • 旋转卡壳——凸多边形最小距离

    千次阅读 2013-05-31 11:19:54
    凸多边形最小距离 给定两个非连接(比如不相交)的凸多边形 P 和 Q, 目标是找到拥有最小距离的点对 (p,q) (p 属于 P 且 q属于 Q)。  事实上, 多边形非连接十分重要, 因为我们所说的多边形...
  • 凸多边形最优三角形

    2021-03-24 20:55:45
    要求确定该凸多边形的三角剖分,使得该三角剖分中诸三角形上权之和为最小凸多边形三角剖分如下图所示: 2、最优子结构性质: 若凸(n+1)边形P={V0,V1……Vn}的最优三角剖分T包含三角形V0VkVn,1<=k<=...
  • 实现了求凸多边形中三角划分弦长之和最短的问题。其间可以进一步改进。
  • 凸多边形最小周长外接矩形

    千次阅读 2013-09-24 17:34:26
    我们的目标是找到一个最小盒子(就周长而言)外接多边形 P 。  有趣的是通常情况下最小面积的和最小周长的外接矩形是重合的。 有人不禁想问这是不是总成立的。 下面的例子回答了这个问题: 多边形(灰色的)...
  • 凸多边形最小面积外接矩形 给定一个凸多边形 P , 面积最小的能装下 P (就外围而言)的矩形是怎样的呢? 从技术上说, 给定一个方向, 能计算出 P 的端点并且构由此造出外接矩形。 但是我们需要测试每个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 584
精华内容 233
关键字:

最小凸多边形