皮克定理和任意多边形的面积公式

article/2025/9/6 2:16:50

1. 叉乘:

若 : \vec{a}=(x_1,y_1)\vec{b}=(x_2,y_2),则: \vec{a}\times \vec{b}=(x_1*y_2~-~x_2*y_1)\vec{z}

而:  |\vec{a}\times\vec{b}|=|x_1*y_2~-~x_2*y_1|=|\vec{a}|*|\vec{b}|*sin(\theta )

则: S_{\bigtriangleup }=1/2~*~|\vec{a}|*|\vec{b}|*sin(\theta )=1/2~*~|x_1*y_2~-~x_2*y_1|

S_{\bigtriangleup }为三角形面积,建议百度叉乘的几何意义

2. 皮克公式: 

\dpi{120} \dpi{150} S_{ polygon }=n~+~s/2~-1

即:多边形面积 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 个三角形

 S_{polygon}=S_{\bigtriangleup OAB}+S_{\bigtriangleup OBC}+S_{\bigtriangleup OCD}+S_{\bigtriangleup ODE},依次用叉乘算出每个三角形的面积,求和就得到了多边形的面积,计算S_{\bigtriangleup OBC}时用到了S_{\bigtriangleup OAB}的边向量\underset{OB}{\rightarrow},于是化简可以得到多边形的面积公式(点的坐标必须是顺时针或逆时针依次给出的):

\large S=\frac{1}{2}|\sum_{1}^{n-1}(x[i]*y[i+1]-x[i+1]*y[i])~+~x[n]*y[1]-x[1]*y[n]|

 

 读者可能会想如果点的坐标不是按顺序依次给出的又该怎么办呢?

(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;
}

 


http://chatgpt.dhexx.cn/article/t8tp4Kox.shtml

相关文章

计算任意多边形的面积(已知各顶点的坐标)

https://blog.csdn.net/Adusts/article/details/80546770 如何计算一个多边形的面积&#xff0c;首先想到的是划分成多个小的三角形&#xff0c;因为三角形我们比较熟悉&#xff0c;而且三角形计算面积的方法也很多 三角形: 1. 半周长 P(abc)/2 2. 面积 SaHa/2absin(C)/2sqrt(…

python中的scapy模块

文章目录 模块简介基本用法Scapy的基本操作Scapy模块中的函数Scapy模块的常用简单实例编写端口扫描器 模块简介 Scapy是一个由Python编写的强大工具&#xff0c;目前很多优秀的网络扫描攻击工具都使用了这个模块。也可以在自己的程序中使用这个模块来实现对网络数据包的发送、…

Scapy使用文档中文版

0x00 前言 scapy是一个强大的交互式(interactive)的包操作程序&#xff0c;用python写的&#xff0c;有一个python的命令行解释器界面&#xff0c;可直接运行&#xff0c;当然也可以作为第三库&#xff0c;导入到我们的python程序中去使用它的类和方法。 关于scapy作者的一个简…

“人生苦短,我用Python“——Socket、Nmap、Scapy

渗透测试模块 Socket实例化Socket类Socket常用的函数服务端函数客户端函数服务端和客户端均可使用的函数使用Socket编写一个简单的服务端和客户端 Nmappython-nmap模块类的实例化python-namp模块中的函数PortScanner类PortScannerAsync类使用python-nmap模块来编写一个扫描器 S…

【Python】scapy模块学习笔记

文章目录 0x00 scapy安装以及环境配置0x01 实验10x02 实验20x03 实验30x04 实验40x04 实验50x06 python代码实现端口扫描 0x00 scapy安装以及环境配置 学习自知乎大佬 ——弈心——网络工程师的Python之路—Scapy基础篇 复现了一波 scapy安装: pip install scapy导入scapy方…

Python-Scapy使用介绍

介绍 Scapy可作为python模块运行,也可以单独运行,scapy在kali自带,可以直接输入scapy进入交互命令行。 Scapy可对网络数据包进行发送、监听、解析等操作,类似于python-nmap模块,只不过scapy更偏向于底层操作。 函数 下面简单了解下scapy的基本使用,这里以kali系统为例…

python的scapy基础使用

Scapy库 解决三个问题&#xff1a; 监听流量&#xff08;与wireshark相同&#xff09; 分析流量 编辑流量数据包&#xff08;链路层 网络层 传输层&#xff09;&#xff0c;应用层也可以编辑 意义不大 提供两种操作方式 基于命令进行交互 python代码调用 基于命令进行交…

Python使用scapy和dpkt抓包并解析

scapy scapy是python中一个可用于网络嗅探的非常强大的第三方库&#xff0c;可以用它来做 packet 嗅探和伪造 packet。 scapy已经在内部实现了大量的网络协议。如DNS、ARP、IP、TCP、UDP等等&#xff0c;可以用它来编写非常灵活实用的工具。 scapy安装&#xff1a; pip inst…

Scapy:交互式数据包处理程序

简介 Scapy是一个强大的&#xff0c;用Python编写的交互式数据包处理程序 可以让用户发送、嗅探、分析和伪造网络包&#xff0c;从而用来侦测、扫描和向网络发动攻击 可以轻松地处理扫描(scanning)、路由跟踪(tracerouting)、探测(probing)、单元测试(unit tests)、攻击(attac…

Scapy基础学习之一

关于Scapy Scapy的是一个强大的交互式数据包处理程序&#xff08;使用python编写&#xff09;。它能够伪造或者解码大量的网络协议数据包&#xff0c;能够发送、捕捉、匹配请求和回复包等等。它可以很容易地处理一些典型操作&#xff0c;比如端口扫描&#xff0c;tracerouting…

Scapy常用操作和命令(1)

&#xfeff;&#xfeff; ls() 列出scapy中实现的所有网络协议 >>> ls() ARP : ARP ASN1_Packet : None BOOTP : BOOTP CookedLinux : cooked linux DHCP : DHCP options DHCP6 : DHCPv6 Generic Message) DHCP6OptAuth : DHCP6 Option - …

python+scapy 抓包与解析

最近一直在使用做流量分析,今天把 scapy 部分做一个总结。 python 的 scapy 库可以方便的抓包与解析包,无奈资料很少,官方例子有限,大神博客很少提及, 经过一番尝试后,总结以下几点用法以便大家以后使用。 python scapy 抓包与解析 转载请注明来自:b0t0w1’blog ## 安…

基于Scapy的传统网络攻击实现

基于Scapy的传统网络攻击实现 前言开发环境与工具系统主要功能 系统原理分析协议工作原理ARP工作原理TCP工作原理 攻击原理及实现方法ARP扫描原理ARP欺骗原理SYN Flood攻击原理实现方法 功能设计功能描述 系统功能实现准备&#xff08;Scapy的下载&#xff09;ARP扫描的实现ARP…

Python Scapy使用方法

0x01 起航Scapy Scapy的交互shell是运行在一个终端会话当中。因为需要root权限才能发送数据包&#xff0c;所以我们在这里使用sudo $ sudo scapy Welcome to Scapy (2.0.1-dev) >>>123 在Windows当中&#xff0c;请打开命令提示符&#xff08;cmd.exe&#xff09;&…

python库:scapy使用

1、安装&#xff1a;sudo pip install scapy 2、查看scapy依赖关系&#xff1a; 2.3.2版本&#xff0c;不依赖任何python库。 3、使用help(scapy)查看帮助 就这么点&#xff0c;任何发送、接受数据包函数都没有看到&#xff0c;和以前的任何显示模块帮助都不一样 正确显示…

Scapy 中文文档:一、介绍

介绍 译者&#xff1a;pdcxs007 来源&#xff1a;Scapy介绍官方文档翻译 原文&#xff1a;Introduction 协议&#xff1a;CC BY-NC-SA 2.5 关于ScapyScapy为何如此特别快速的报文设计一次探测多次解释Scapy解码而不解释快速展示Quick demo合理的默认值学习Python 本人英文水平…

Scapy的介绍(一)

介绍 关于Scapy的 Scapy是一个Python程序&#xff0c;使用户能够发送&#xff0c;嗅探和剖析并伪造网络数据包。此功能允许构建可以探测&#xff0c;扫描或攻击网络的工具。 换句话说&#xff0c;Scapy是一个功能强大的交互式数据包操作程序。它能够伪造或解码大量协议的数据…

scapy基本操作

scapy基本操作 scapy是一款基于Python强大的数据包处理工具。它可以用来发送各类定制的数据包也可以用于数据包解析。 由于毕业论文需要对数据包进行预处理&#xff08;数据清洗&#xff0c;数据归一化等&#xff09;&#xff0c;使用scapy进行数据处理。 本文是scapy学习过程…

Scapy的基本操作

Scapy模块的使用 Scapy的基本操作Scapy模块中的函数利用Scapy进行端口屏蔽探测 Scapy的基本操作 1.IP()类型数据包 在Scapy中&#xff0c;每一个协议就是一个类。只需要实例化一个协议类&#xff0c;就可以创建一个该协议的数据包。例如&#xff0c;如果要创建一个IP类型的数…

数据包工具--Scapy基础篇

数据包工具--Scapy基础篇 零、前言一、Scapy是什么&#xff1f;二、Scapy基础1 利用pip安装库2 基本使用2.1 conf变量2.2 lsc()方法2.3 ls()方法 3 发送数据3.1 创建数据3.2 发送数据3.3 fuzz()方法3.4 发送与接收数据 三、结尾 零、前言 学习过程中用到Scapy这个工具&#xf…