皮克定理和任意多边形的面积公式
1. 叉乘:
若 : ,,则:
而:
则:
为三角形面积,建议百度叉乘的几何意义
2. 皮克公式:
即:多边形面积 S = 多边形内整数点的个数 n + 多边形边上整数点的个数 / 2 - 1
注:多边形的顶点坐标必须是整数
3. 线段上整数点的个数:
gcd(线段在x轴的投影长,线段在y轴的投影长) + 1
注:线段的两端点坐标都必须是整数
简单证明:
设点 A(x1,y1),B(x2,y2),且 x1 <= x2,y1 <= y2(方便后面的叙述)
现在以 A 点为原点建立直角坐标系,线段 AB 在 x 轴的投影长为:a = x2 - x1,在 y 轴的投影长为:b = y2 - y1,那么线段 AB 的方程为 y = bx/a (0 =< x <= a),设 g = gcd(a,b),b' = b/g,a' = a/g;同样有:y = b'x/a',此时 a' 与 b' 互质,若想 y 为整数,那么必有 x = ka';由于 x 属于 [0,a],那么这样的 x 有:a / a' = g 个,再加上原点这一个,证毕!!!
4. 任意多边形的面积
皮克公式有一定的局限性;上文给出了三角形的公式,对于只知道顶点坐标的情况下,我们可以将 n 边形化成 n-2 个三角形
,依次用叉乘算出每个三角形的面积,求和就得到了多边形的面积,计算时用到了的边向量,于是化简可以得到多边形的面积公式(点的坐标必须是顺时针或逆时针依次给出的):
读者可能会想如果点的坐标不是按顺序依次给出的又该怎么办呢?
(1)所给多边形为凹包:
如果点不是按照顺序依次给出的,那么所构成的多边形一定不唯一(画画就明了),所以点一定是按顺序给出的
(2)所给多边形为凸包:
我们可以先将点按极角排序,就可套用公式了,(凹包的点极角排序后多边形的顶点不是依次有序的)
ps:极角排序
ps:线性代数知识解释公式来历
5. 应用:
(1)HDU 1705 - Count the grid
题意:
给你三个点,求三个点组成的三角形内有多少个整数点,不算边上的,也就是求皮克公式中的n
代码:
// n = S - s/2 + 1
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long double ld;
int main()
{int x1,y1,x2,y2,x3,y3;while(cin>>x1>>y1>>x2>>y2>>x3>>y3){if(x1==0&&y1==0&&x2==0&&y2==0&&x3==0&&y3==0)break;int a1 = x2-x1,b1 = y2-y1;int a2 = x3-x1,b2 = y3-y1; int S = abs(a1*b2-b1*a2)/2; //要加绝对值int s = __gcd(abs(x1-x2),abs(y1-y2))+1;s += __gcd(abs(x3-x2),abs(y3-y2))+1;s += __gcd(abs(x1-x3),abs(y1-y3))+1-3;//重复计算了3个顶点cout<<S - s/2 + 1<<endl;}return 0;
}
(2)2018年牛客多校算法寒假训练营练习比赛
代码:
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
int main()
{int x1,y1,x2,y2,x3,y3;while(cin>>x1){if(x1==-1) break;cin>>y1>>x2>>y2>>x3>>y3;int a1 = x2-x1,b1 = y2-y1;int a2 = x3-x1,b2 = y3-y1;double S = abs((double)a1*b2-b1*a2)/2.0;int ab = __gcd(abs(x1-x2),abs(y1-y2))+1;int bc= __gcd(abs(x3-x2),abs(y3-y2))+1;int ac= __gcd(abs(x1-x3),abs(y1-y3))+1;int s = ab + bc + ac - 3;printf("%.1f ",S);printf("%lld %d %d %d\n",(ll)S-s/2+1,ab-2,bc-2,ac-2);}return 0;
}
(3) HDU 2036 多边形的面积
代码:
#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
struct point
{int x,y;
}p[150];
int main()
{int n;while(cin>>n&&n){for(int i=0;i<n;++i)cin>>p[i].x>>p[i].y;int ans = p[n-1].x*p[0].y - p[n-1].y*p[0].x;for(int i=0;i<n-1;++i)ans += p[i].x*p[i+1].y - p[i].y*p[i+1].x;printf("%.1f\n",abs(ans)*1.0/2.0);}return 0;
}
(4)牛客网-简单多边形
题意:
判断顶点坐标是按什么顺序给出的
题解:
根据叉乘的几何意义,顺时针计算,结果为负,逆时针结果为正
代码:
#include <cmath>
#include <iostream>
using namespace std;
int x[110];
int y[110];
int main()
{int n;cin>>n;for(int i=1;i<=n;++i)cin>>x[i]>>y[i];int ans = 0;for(int i=1;i<n;++i){ans += x[i]*y[i+1] - x[i+1]*y[i];}ans += x[n]*y[1]-x[1]*y[n];if(ans>0) cout<<"counterclockwise";else cout<<"clockwise";return 0;
}
皮克定理和任意多边形的面积公式相关推荐
- 任意多边形的面积公式
设Ω是m边形(如下图),顶点沿边界正向排列,坐标依次为 建立Ω的多边形区域向量图. 由图知坐标原点与多边形任意相邻的两个顶点构成一个三角形,而三角形的面积可由三个顶点构成的两个平面向量的外积求得. 任 ...
- 凸多边形面积_C++计算任意多边形的面积
任意多边形的面积计算_拾忆楓灵的博客-CSDN博客blog.csdn.net 计算任意多边形的面积 - tenos - 博客园www.cnblogs.com 完美解决计算3D空间任意多边形面积_S ...
- C++实现——任意多边形的面积
//求任意多边形的面积 /*语法:result = polygonarea(vector<Point>&polygon, int N); 参数: polygon:多变形顶点数组 N ...
- 计算任意多边形的面积
转载自 对于凸多边形,很容易计算,如下图,以多边形的某一点为顶点,将其划分成几个三角形,计算这些三角形的面积,然后加起来即可.已知三角形顶点坐标,三角形面积可以利用向量的叉乘来计算. 对于凹多边形,如 ...
- 计算任意多边形的面积(Android)
需求 线段:算出地图上线段的实际长度 面积:算出地图上不规则多边形的实际面积 解决方案 1.线段的实际长度 直接使用高德的AMapUtils.calculateLineDistance(latLng, ...
- poj12652954 [皮克定理 格点多边形]【学习笔记】
Q:皮克定理这种一句话的东西为什么还要写学习笔记啊? A:多好玩啊... PS:除了蓝色字体之外都是废话啊... Part I 1.顶点全在格点上的多边形叫做格点多边形(坐标全是整数) 2.维基百科 ...
- 多边形内角和与多边形的面积公式
正多边形内角计算公式与半径无关 要已知正多边形边数为N 内角和=180(N-2) 半径为R 圆的内接三角形面积公式:(3倍根号3)除以4再乘以R方 外切三角形面积公式:3倍根号3 R方 外切正方形:4 ...
- c++如何求任意多边形的面积
由于项目需要,求解任意不规则多边形的面积 ,想了很久,也不知道怎么叙述,直接代码展示吧 #include <iostream> #include <vector> using ...
- HDOJ2036改革春风吹满地笔记——任意多边形求面积
题目地址 学习了任意多边形的计算,通过向量叉乘来进行计算. 计算公式 如果逆时针给出坐标,求得是正的,就是答案.如果顺时针给出坐标,求得是负,需要变正 具体推导过程 博客地址1 还学了海伦公式求三角形 ...
- [几何] 计算任意多边形的面积、中心、重心
最近项目用到:在不规则任意多边形的中心点加一个图标.(e.g: xx地区发生暴雪,暴雪区域是多边形,给多边形中心加一个暴雪的图标) 之前的设计是,计算不规则多边形范围矩形bounds的中心点.这个比较 ...
最新文章
- html怎么设置取当前日期格式,js获取当前日期,格式为YYYY-MM-DD
- js luhn算法_不会飞的鸟
- 【Elasticsearch】索引和查询性能调优的21条建议-以及调优参数
- pandas 如何删掉第一行_Pandas-数据筛选
- [LOJ6278]数列分块入门 2
- Python基础教程笔记——列表和元组
- 设计模式之行为类模式大PK
- 线段树、前缀数组:HDU1591-Color the ball(区间更新、简单题)
- UIView的layoutSubviews,initWithFrame,initWithCoder方法
- K8S学习笔记之借助Minikube完成在windows环境下Kubernetes的单节点搭建-(超级简单)
- Linux tar gzip压缩和解压
- TCP/IP协议漏洞实验
- 做独一无二的自己,颜宁西湖大学问答全记录
- Phalcon整合beanstalk消息队列
- Codeforces 1398 F. Controversial Rounds —— 线段树+dp
- 魔霸新锐2021版不接显示器开启独显的方式
- TensorFlow-gpu使用方法
- css 实现div内显示一行、两行或三行,超出部分用省略号显示
- python中格式化输出的作用是什么_python格式化输出是什么意思
- 智能BI,如今走到了哪一步?