在学习Graham算法前,需要先了解二维叉乘这个概念。

叉乘的拓展

  1. 在一般的常识或者教科书中规定叉乘只有3d才拥有,其实2d也可以拓展出来一个叉乘形式,而且非常有用。
    拓展方式:假设有两个2d向量a,b,我们直接把他们视为3d向量,z轴补0,那么这个时候的a,b向量的叉乘结果c,c.x=0,c.y=0,c.z=a.xb.y-b.xa.y,
    这个时候可以吧2d的叉乘值定义为得到一个值,而不是得到一个向量,那么这个值k, k = c.z=a.xb.y-b.xa.y,我们可以通过这个k值得到很多有用的性质:
    1.a,b向量构成的平行四边形的面积。
    2.如果k>0时,那么a正旋转到b的角度为<180°,如果k<0,那么a正旋转到b的角度为>180°,如果k=0 那么a,b向量平行。

有了二维叉乘这个基础咱们就可以来学习Graham这个算法了。

#include<bits/stdc++.h>
using namespace std;
int n,top;
struct node{double x,y;
} a[105],b[105];
///a代表输入的点,p代表选择的点
double cross(node p0,node p1,node p2){   ///计算叉乘 p0p1 和 p0p2return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
/**
大于小于号 正好相反
如果k>0时,那么a正旋转到b的角度为<180°
如果k<0,那么a正旋转到b的角度为>180°,
如果k=0 那么a,b向量平行。
首先 a = (1,0) b = (-1,1)
aXb = 1    从a向量逆时针到b向量的角度小于180
bXa = -1   从b向量逆时针到b向量的角度大于180
*/
double dis(node a,node b){return sqrt((a.x - b.x)*(a.x - b.x)+(a.y - b.y)*(a.y - b.y));
}
///极角排序
bool cmp(node p1,node p2){double tmp=cross(a[0],p1,p2);if( tmp>0 || ( tmp==0 && dis(a[0],p1) < dis(a[0],p2) ) ){return 1;}/**两向量小于180度 或者 两个向量平行距离从小到大排序*/return 0;
}
void Graham(){int k=0;///寻找最左下角的点for(int i=0; i<n; i++){if(a[i].y < a[k].y || ( a[i].y == a[k].y && a[i].x < a[k].x ) ){k=i;}}swap(a[0],a[k]);   ///找p[0]sort(a+1,a+n,cmp); ///进行极角排序top=1;p[0]=a[0];p[1]=a[1];for(int i=2; i<n; i++){  ///控制进栈出栈while(cross( p[top-1] , p[top] , a[i] )<0 && top){top--;}top++;p[top]=a[i];}
}
int main(){int m;scanf("%d",&m);while(m--){scanf("%d",&n);for(int i=0; i<n; i++){scanf("%d%d",&a[i].x,&a[i].y);}Graham();for(int i=0; i<=top; i++){printf("%d %d\n",p[i].x,p[i].y);}}return 0;
}

凸包Graham算法相关推荐

  1. java经纬度凸包graham_计算几何-凸包-Graham算法

    一.点集有序化-水平排序 在计算几何中,点集往往无序,因此在计算前需要对点集进行排序,使得算法可以有序高效运行. 水平排序利用点在二维平面上固有的横纵坐标属性进行排序,只涉及点坐标的比较,与极坐标排序 ...

  2. HDUOJ 1392凸包graham算法

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  3. 算法 - 凸包(Graham算法)

    定义:在一个实数向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包 前置:B点位于向量  的左边,  与 叉积为正 B点位于向量  的右边, 与  叉积为负             ...

  4. 凸包Graham Scan算法实现

    凸包Graham Scan算法实现 凸包算法实现点集合中搜索凸包顶点的功能,可以处理共线情况,可以输出共线点也可以不输出而只输出凸包顶点.经典的Graham Scan算法,点排序使用极角排序方式,并对 ...

  5. 凸包模板(Graham算法)

    因为某些原因被迫学习几何知识..先从网上拿个模板来用用 用处: 可以按照极角排序,依次找出凸包边界的点 const int N=10;int n=4,tot;struct node {double x ...

  6. Graham算法解决凸包问题

    Graham算法解决凸包问题 模板题,题目来自洛谷如下. 圈奶牛[模板]二维凸包 题目简要描述 给定一些点,求凸包的周长. 输入格式 输入数据的第一行是一个整数.表示农夫约翰想要围住的放牧点的数目n. ...

  7. 凸包问题-Graham 算法

    这里我只是想记录一下凸包问题,我发现如果要把他讲解非常清楚,需要画比较复杂的集合图形,而我不会.所以,这篇文章可能只能帮你梳理一下算法步骤或者参考一下代码. 什么是凸包问题 找一条线,能够将二维平面上 ...

  8. 【计算几何】凸包之graham算法(适合小白)

    计算几何–凸包(graham算法实现) 题目链接:LeetCode587 https://leetcode-cn.com/problemset/all/ 题目描述 在一个二维的花园中,有一些用 (x, ...

  9. c++ 凸包 分治算法_三维凸包

    缘起 众所周知,二维凸包可以使用 Graham 扫描 内解决. 所以本文来学习一下三维空间中凸包的一种直观算法--增量算法(increment algorithm) 分析 有一条叫 Willy 的苹果 ...

最新文章

  1. Meterpreter重要命令与使用
  2. linux大端小端命令,linux的大小端、网络字节序问题
  3. 转载:迷你云 – 搭建自己的本地多人团队Dropbox 服务
  4. 转载:jsonp详解
  5. C#.NET学习笔记2---C#.第一个C#程序
  6. 用Python读取CSV文件的5种方式
  7. 身高回归现象是否真的存在?
  8. mapxtreme java_MapXtreme Java Edition 4.8使用心得(二)
  9. MATLAB学习——Matlab系统环境介绍
  10. 正本清源:LBS(基于位置服务)技术——高精准IP地址定位的8大误区(下)
  11. 网吧版XP系统制作与优化终极版(转)
  12. 六度好友算法【转载】
  13. 基于微博平台的python爬虫数据采集
  14. Java后端验证苹果登录
  15. 2020年全国大学生数学建模竞赛赛题 选题建议
  16. 天津发票版本文件服务器端口,天津增值税发票综合服务平台入口
  17. matlab实现彩色图像的直方图均衡化
  18. 如何区分斜杠和反斜杠?
  19. matlab画一个放大图中图
  20. linux系统编程之信号(一):信号基本概述

热门文章

  1. Visio中的内容另存为图片且不改变画质
  2. 1.2什么是HLSL
  3. Inno Setup选择语言并写入配置文件、翻译提示信息
  4. input只能输入数字0-9(不含小数点)
  5. STM32-RS485通信软硬件实现
  6. Centos7安装ElasticSearch6.4
  7. Docker中创建MySQL容器,将宿主机目录直接挂载到目录
  8. 盘点最近 火火火火 的 GitHub 项目
  9. 重塑规则 定义未来 三星Galaxy S22系列中国发布
  10. 第九周 棚拍静物——让你的照片更有味道