先说下基础知识,不然不好理解后面的东西

两向量的X乘p1(x1,y1),p2(x2,y2)

p1Xp2如果小于零则说明  p1在p2的逆时针方向

如果大于零则说明 p1在p2的顺时针方向

structnode{doublex,y;

node friendoperator -(node a,node b)//对减法符号进行重载

{return {a.x-b.x,a.y-b.y};

}

}p[10000],s[10000];doubleX(node a,node b){return a.x*b.y-a.y*b.x;

}

这个方法很有用处。比如判断一个点是否在一条线段的左边还是右边,可以用X乘来判断,或者判断两条线段是否相交

接着说说凸包    Graham扫描法

1.在平面上一些散乱的点,首先  找找到这些点中处于最左下方的点

for(int i=1;i<=N;i++)

cin>>p[i].x>>p[i].y;int k=1;for(int i=2;i<=N;i++)

{if(p[i].y

k=i;

}

swap(p[1],p[k]);

2.对这些点进行排序。把按照极角(polar angle)从小到大排序(以 p1为极点),极角相同的点按照到的距离从小到大排序。

intcmp(node a,node b)

{double x=X(a-p[1],b-p[1]);//以p[1]为极点,通过X乘来判断

if(x>0) return 1;//让a处于b的顺时针

if(x==0&&dis(a,p[1])

return 0;

}

sort(p+2,p+N+1,cmp);

3.再开一个结构体数组s 来储存凸包最外围的点,也就是结果,这个有点容易让人搞迷。

遍历剩下的点,while循环把发现不是凸包顶点的点移除出去,因为当逆时针遍历凸包时,我们应该在每个顶点向左转。因此当while循环发现在一个顶点处没有向左转时,就把该顶点移除出去。

至于如何判断向左向右则是根据叉积来判断,前面我们已经解决过这个问题了

doublemulti(node a,node b,node c)

{return X(b-a,c-a);

}

s[1]=p[1];

s[2]=p[2];int t=2;for(int i=3;i<=N;i++)

{//发现在栈里边一个顶点处没有向左转时,就把该顶点移除出去

while(t>=2&&multi(s[t-1],s[t],p[i])<=0) t--;

s[++t]=p[i];

}

这个是求凸包的周长的

hdu1392    http://acm.hdu.edu.cn/showproblem.php?pid=1392

算是模板题吧

#include

using namespacestd;structpoint{doublex,y;

point friendoperator -(point a,point b)

{return {a.x-b.x,a.y-b.y};}

}p[105],s[105];doubledis(point a,point b)

{

point c=a-b;return sqrt(c.x*c.x+c.y*c.y);

}doubleX(point a,point b)

{return a.x*b.y-a.y*b.x;

}intcmp(point a,point b)

{double x=X(a-p[1],b-p[1]);if(x>0) return 1;if(x==0&&dis(a,p[1])

}doublemulti(point p1,point p2,point p3)

{return X(p2-p1,p3-p1);

}intmain()

{intN;while(scanf("%d",&N),N)

{for(int i=1;i<=N;i++) cin>>p[i].x>>p[i].y;if(N==1)

{

printf("0.00\n");continue;

}else if(N==2)

{

printf("%.2lf\n",dis(p[1],p[2]));continue;

}int k=1;for(int i=2;i<=N;i++)if(p[i].y

swap(p[1],p[k]);

sort(p+2,p+1+N,cmp);

s[1]=p[1];

s[2]=p[2];int t=2;for(int i=3;i<=N;i++)

{while(t>=2&&multi(s[t-1],s[t],p[i])<=0) t--;

s[++t]=p[i];

}double sum=0;for(int i=1;i

{

sum+=dis(s[i],s[i+1]);

}

printf("%.2lf\n",sum+dis(s[1],s[t]));

}return 0;

}

emmm  再来个求任意多边形的面积

structPoint {doublex, y;

};//计算任意多边形的面积,顶点按照顺时针或者逆时针方向排列

double polygon_area(Point *p, intn)

{if(n < 3) return 0;double sum = 0;

p[n+ 1] = p[1];for(int i = 1; i <= n; i++)

sum+= p[i].x * p[i + 1].y - p[i].y * p[i + 1].x;//可以理解为不管这个多边形在哪,都以原点为分割点,就算原点在外面也可以算出,因为有正负可以抵消掉多余的

sum= fabs(sum / 2.0);returnsum;

}

再来个求面积均匀的多边形重心

需要把多边形以p[0]为分界点  分成n-2个三角形,求出这些三角形的重心(i,j),乘以该三角形的面积,如上图公式

#include

using namespacestd;structnode{doublex,y;

node friendoperator -(node a,node b)

{return {a.x-b.x,a.y-b.y};

}double friend operator *(node a,node b)//对*进行重载 node*node 相当于X乘

{return a.x*b.y-a.y*b.x;

}

}a[1000010];intmain()

{intt;

cin>>t;while(t--)

{intn;

cin>>n;for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y;double S=0,X=0,Y=0;for(int i=2;i

{double x=(a[i]-a[1])*(a[i+1]-a[1]);//这个乘和下面的不一样,这时X乘,求出三角形面积

X+=(a[1].x+a[i].x+a[i+1].x)*x;//重心(没除以3)乘以面积

Y+=(a[1].y+a[i].y+a[i+1].y)*x;

S+=x;

}

printf("%.2lf %.2lf\n",X/S/(double)3,Y/S/(double)3);//除以3为重心

}return 0;

}

java经纬度凸包graham_凸包算法(Graham扫描法)详解相关推荐

  1. Java 实现sha_Java实现SHA算法的方法详解

    本文实例讲述了Java实现SHA算法的方法.分享给大家供大家参考,具体如下: 一 简介 安全散列算法 固定长度摘要信息 二 SHA算法 SHA-1.SHA-2(SHA-224.SHA-256.SHA3 ...

  2. java实现爬山算法_python实现爬山算法的思路详解

    问题 找图中函数在区间[5,8]的最大值 重点思路 爬山算法会收敛到局部最优,解决办法是初始值在定义域上随机取乱数100次,总不可能100次都那么倒霉. 实现 import numpy as np i ...

  3. 【算法知识】详解堆排序算法

    点击蓝色字关注我们! 什么是堆 「堆」首先是一个完全二叉树,「堆」分为「大顶堆」和「小顶堆」: 「大顶堆」 : 每个节点的值大于或等于其左右孩子节点的值,称为大顶堆. 「小顶堆」同理就是每个节点的值小 ...

  4. 【算法知识】详解基数排序算法

    已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 [算法知识]详解快速排序算法 [算法知识]详解归并排序算法 基本思想 基数排序的思想是将整数按位数切 ...

  5. 【算法知识】详解归并排序算法

    已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 [算法知识]详解快速排序算法 基本思想 归并排序的基本思想是: 先将序列一次次分成子序列,直到子序列 ...

  6. 【算法知识】详解快速排序算法

    基本思想 已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 本文的思路是以从小到大为例讲的. 快速排序的基本思想是任取待排序序列的一个元素作为中心元素 ...

  7. 【算法知识】详解直接插入排序算法

    前言 已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 在玩扑克牌的时候,我们抽到一张牌的时候,都是将它插入到当前手中牌的合适位置的. 如下图: (上图来自算法导论) 直接插入排序 ...

  8. java加密算法入门(三)-非对称加密详解

    1.简单介绍 这几天一直在看非对称的加密,相比之前的两篇内容,这次看了两倍多的时间还云里雾里的,所以这篇文章相对之前的两篇,概念性的东西多了些,另外是代码的每一步我都做了介绍,方便自己以后翻阅,也方便 ...

  9. java的数组与Arrays类源码详解

    java的数组与Arrays类源码详解 java.util.Arrays 类是 JDK 提供的一个工具类,用来处理数组的各种方法,而且每个方法基本上都是静态方法,能直接通过类名Arrays调用. 类的 ...

  10. Java开源生鲜电商平台-Java分布式以及负载均衡架构与设计详解(源码可下载)

    Java开源生鲜电商平台-Java分布式以及负载均衡架构与设计详解(源码可下载) 说明:主要是针对一些中大型的项目需要进行分布式以及负载均衡的架构提一些思路与建议. 面对大量用户访问.高并发请求,海量 ...

最新文章

  1. 分布式事务最经典的七种解决方案
  2. redis install note
  3. 24个经典的MySQL索引问题,你都遇到过哪些?
  4. 索尼Xperia 5前置拍照斩获DxOMark得79分
  5. python中的然后_返回,然后等待另一个函数在python中完成
  6. Button 自动换行
  7. idea中xml文件用浏览器打开
  8. Ansys 15.0 x64 安装
  9. JWT的数字签名的简单理解
  10. TS + vue3.2 + vite2 + element-plus 通用弹框组件封装
  11. java+添加分割符_如何给数字添加分隔符
  12. 面试上海启明星辰+渗透测试工程师! 通过
  13. java报表开发(bi报表开发)
  14. windows xp 自动登录
  15. layui内置模块(layer弹出层)
  16. 迪米特法则(Low of Demeter)
  17. 基于openharmony的智慧婴儿陪睡伴侣
  18. 2 Thread之GUC
  19. 从JDBC到手撸极简版Mybaties(3)JDBC自动解析配置文件
  20. 程序员们都在用什么键盘敲代码?

热门文章

  1. ORA-00937: 不是单组分组函数
  2. 数字手写识别——Java实现KNN算法
  3. python空间点赞_用Python登录好友QQ空间点赞的示例代码
  4. win32 014 使用ResEdit 资源编译器 可视化编程 资源的编写
  5. 利用Web查询文件(.iqy)有效钓鱼
  6. 请问肾阴虚吃什么药?饮食注意什么?还有桂附地黄丸是治肾阴虚还是治肾阳虚的?谢谢
  7. 生产实践中的经典算法(四)-BitMap
  8. SSM框架之Spring
  9. 开源开放 | 面向家庭常见疾病的知识图谱(东南大学)
  10. [C/C++]跳格子游戏 - 2019校招编程刷题