向量积&&凸包算法
参考:Thanks
百度百科
http://blog.csdn.net/keng_s/article/details/52131034
https://www.cnblogs.com/aiguona/p/7232243.html
一定要有耐心,仔细的看。(#^.^#)
预备:
向量积
概念:
向量积,数学中又称外积、叉积,物理中称矢积、叉乘,是一种在向量空间中向量的二元运算。与点积不同,它的运算结果是一个向量而不是一个标量。并且两个向量的叉积与这两个向量和垂直。
计算:a,b,c均为向量
向量的叉乘,即求同时垂直两个向量的向量,即c垂直于a,同时c垂直于b(a与c的夹角为90°,b与c的夹角为90°)
c = a×b = (a.y*b.z-b.y*a.z , b.x*a.z-a.x*b.z , a.x*b.y-b.x*a.y)
以上图为例a(1,0,0),b(0,1,0),c=a×b = (0,0,1)
相关:
向量积|c|=|a×b|=|a| |b|sin<a,b>
即c的长度在数值上等于以a,b,夹角为θ组成的平行四边形的面积。
如果a,b的叉积|c|的数值>0 说明 b在a的逆时针方向
|c|的数值=0 说明 b和a在一条直线上
|c|的数值<0 说明 b在a的顺时针方向
===========================================================分割线
凸包
概念:
1.在一个实数向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称 为X的凸包。X的凸包可以用X内所有点(X1,...Xn)的凸组合来构造.
2. 在二维欧几里得空间中,凸包可想象为一条刚好包著所有点的橡皮圈。
3. 用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有的点。
定义:
1.点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内。下图中由红色线段表示的多边形就是点集Q={p0,p1,...p12}的凸包。
2.一组平面上的点,求一个包含所有点的最小的凸多边形,这就是凸包问题了。这可以形象地想成这样:在地上放置一些不可移动的木桩,用一根绳子把他们尽量紧地圈起来,并且为凸边形,这就是凸包了。
常用求法:
Graham扫描法
过程:
1.在所有点中选取y坐标最小的一点H,当作基点。如果存在多个点的y坐标都为最小值,则选取x坐标最小的一点。。坐标相同的点应排除。
然后按照其它各点p和基点构成的向量<H,p>;与x轴的夹角进行排序,夹角由大至小进行顺时针扫描,反之则进行逆时针扫描。实现中无需求得夹角,只需根据余弦定理求出向量夹角的余弦值即可。
以下图为例,基点为H,根据夹角由小至大排序后依次为H,K,C,D,L,F,G,E,I,B,A,J。下面进行逆时针扫描。
2.线段<H,K>;一定在凸包上,接着加入C。假设线段<K,C>;也在凸包上,因为就H,K,C三点而言,它们的凸包就是由此三点所组成。但是接下来加入D时会发现,线段<K,D>;才会在凸包上,所以将线段<K,C>;排除,C点不可能是凸包。
3. 即当加入一点时,必须考虑到前面的线段是否在凸包上。
基点开始,凸包上每条相临的线段的旋转方向应该一致,并与扫描的方向相反。
如果发现新加的点使得新线段与上线段的旋转方向发生变化,则可判定上一点必然不在凸包上。实现时可用向量叉积进行判断。
设新加入的点为P[n+1],上一点为P[n],再上一点为P[n-1]。顺时针扫描时,如果向量
(P[n-1],P[n])与(P[n],P[n+1])的叉积为正(逆时针扫描判断是否为负),则将上一点删除。删除过程需要回溯,将之前所有叉积符号相反的点都删除,然后将新点加入凸包。
在上图中,加入K点时,由于线段<H,C>要旋转到<H,K>的角度,为顺时针旋转,所以C点不在凸包上,应该删除,保留K点。接着加入D点,由于线段<K,D>要旋转到<H,K>的角度,为逆时针旋转,故D点保留。按照上述步骤进行扫描,直到点集中所有的点都遍历完成,即得到凸包.

模板:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define PI 3.1415926535
#define DB double
#define eps 1e-8
using namespace std;
const int N=;
int T,n,L;
struct node{
DB x,y;
}d[N],s[N];//d[]存入的所有的点 s[]凸包中所有的点
bool cmp1(node a,node b)
{
if(a.y!=b.y) return a.y<b.y;
else return a.x<b.x;
}
DB Cross(node a1,node a2,node b1,node b2)
{
return (a2.x-a1.x)*(b2.y-b1.y)-(b2.x-b1.x)*(a2.y-a1.y);
}
DB dis(node a,node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y));
}
bool cmp2(node a,node b)//极角排序,原理见紫色部分
{
DB m=Cross(d[],a,d[],b);
if(m>) return ;
else if(m==) return dis(d[],a)<dis(d[],b);
return ;
}
int top;
DB ans;
int main()
{
scanf("%d",&n);
for(int i=;i<=n;++i)scanf("%lf%lf",&d[i].x,&d[i].y);
sort(d+,d+n+,cmp1);
s[++top]=d[];
sort(d+,d+n+,cmp2);
s[++top]=d[];
for(int i=;i<=n;++i)
{
while(top>= && Cross(s[top-],s[top],s[top],d[i])<=) top--;
//控制<0或<=0可以控制重点,共线的,具体视题目而定
s[++top]=d[i];
}
for(int i=;i<top;++i)ans+=dis(s[i],s[i+]);
ans+=dis(s[],s[top]);
printf("%.2lf\n",ans);
return ;
}
盛开吧这世界最美丽的花。
向量积&&凸包算法的更多相关文章
- openlayer的凸包算法实现
最近在要实现一个openlayer的凸多边形,也遇到了不小的坑,就记录一下 1.具体的需求: 通过在界面点击,获取点击是的坐标点,来绘制一个凸多边形. 2.思考过程: 1)首先,我们得先获取点击事件发 ...
- 圈水池 nyoj 78 凸包算法
圈水池 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水, ...
- Graham Scan凸包算法
获得凸包的算法可以算是计算几何中最基础的算法之一了.寻找凸包的算法有很多种,Graham Scan算法是一种十分简单高效的二维凸包算法,能够在O(nlogn)的时间内找到凸包. 首先介绍一下二维向量的 ...
- 计算几何-凸包算法 Python实现与Matlab动画演示
凸包算法是计算几何中的最经典问题之一了.给定一个点集,计算其凸包.凸包是什么就不罗嗦了 本文给出了<计算几何——算法与应用>中一书所列凸包算法的Python实现和Matlab实现,并给出了 ...
- 587. Erect the Fence(凸包算法)
问题 给定一群树的坐标点,画个围栏把所有树围起来(凸包). 至少有一棵树,输入和输出没有顺序. Input: [[1,1],[2,2],[2,0],[2,4],[3,3],[4,2]] Output: ...
- Beauty Contest(graham求凸包算法)
Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 25256 Accepted: 7756 Description Bess ...
- Graham凸包算法简介
凸包真是一个神奇的算法.. 概念 凸包,我理解为凸多边形 叉积 对于向量AB和向量BC,记向量AB*向量BC = AB * BC * sin ∠ABC,而叉积的绝对值其实就是S△ABC/2 对于平面上 ...
- POJ1113:Wall (凸包算法学习)
题意: 给你一个由n个点构成的多边形城堡(看成二维),按顺序给你n个点,相邻两个点相连. 让你围着这个多边形城堡建一个围墙,城堡任意一点到围墙的距离要求大于等于L,让你求这个围墙的最小周长(看成二维平 ...
- 凸包算法(Graham扫描法)详解
先说下基础知识,不然不好理解后面的东西 两向量的X乘p1(x1,y1),p2(x2,y2) p1Xp2如果小于零则说明 p1在p2的逆时针方向 如果大于零则说明 p1在p2的顺时针方向 struct ...
随机推荐
- django amdin后台改成中文
- idea的热部署
1:先找到你要热部署的tomcat之后 ,在设置tomcat时 先选择 server,里面有On 'Update' action () 和 On frame deactivation 这两项 都 ...
- Tesseract5.0训练字库,提高OCR特殊场景识别率(一)
0.目标 很多特殊场景,原生的字库识别率不高,这时候就需要根据需求自己训练字库生成traineddata文件. 一.前期准备工作 1.安装jdk 用于运行jTessBoxEditor 2.安装jT ...
- IIS中配置Office COM组件 [dufu图解系列]
解决问题: 读写office文档目前有2中方法,一种为引用微软的office com组件(下图为Microsoft Office 16.0 Object Library), 另一种为用第三方组件NPO ...
- Spring 容器的基本用法
容器的基本用法 bean 是 Spring 中最核心的东西,因为 Spring 就像是个大水桶,而 bean 就像是容器中的水,水桶脱离了水也没什么用处了,来看看 bean 的定义. public c ...
- MySQL-第十三篇使用ResultSetMetaData分析结果集
1.Result里面包含了一个getMetaData()方法,该方法返回该ResultSet对应的ResultSetMetaData对象. 2.ResultSetMetaData包含的方法: 1> ...
- java_第一年_JDBC(6)
DataBaseMetaData对象:由Connection.getDataBaseMetaData()方法获得,可以用来获取数据库的元数据,提供的方法有: getURL():返回一个String类, ...
- [2019杭电多校第五场][hdu6628]permutation 1
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6628 题意为求字典序第k小的差异数组,差异数组p满足p[i]=a[i+1]-a[i]. 头铁的爆搜,因 ...
- HNUSTOJ-1689 送外卖(TSP问题)
1698: 送外卖 时间限制: 1 Sec 内存限制: 128 MB 提交: 115 解决: 24 [提交][状态][讨论版] 题目描述 在美团和饿了么大行其道的今天,囊中羞涩的小周和小美,也随大 ...
- Java 异步编程
昨天头儿给的学习文档我还没看完,头儿说:“MongoDB光会简单的添删改查什么的不行,要深入了解,你们连$set和$inc使用场景都分不清.” 确实,学习过一年多SQL,确实对学习MongoDB有点影 ...