计算几何之点操作【模板】

2023-11-02 16:30

本文主要是介绍计算几何之点操作【模板】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

点基本定义

与其说是点,不如说是一个二维向量类的定义,先给出类的完整定义,后文会一一详细介绍

class p {
public:ll x, y;//二维向量,表示一个点p(ll _x = 0, ll _y = 0):x(_x),y(_y){}//向量基本运算的实现+ - · *p operator+(const p& a)const { return p{ x + a.x,y + a.y }; }p operator-(const p& a)const { return p{ x - a.x,y - a.y }; }p operator-() const { return p{ -x,-y }; }ll operator|(const p& a)const { return  x * a.x + y * a.y; }//点乘ll operator*(const p& a)const { return x * a.y - y * a.x; }//叉乘p operator*(const ll a)const { return p{ x * a,y * a }; }//向量数乘ll pow() const { return x * x + y * y; }//向量取平方//求距离double disPoint(const p& a) const;//点到点的距离double disline(const p& a, const p& b)const;//点到直线的距离double disSeg(const p& a, const p& b) const;//点到线段的距离};
double abs(const p& p) { return sqrt(p.pow()); }//向量取模
double triangle(p& a, p& b, p& c) { return (b - a) * (b - c) / 2.0; }//求三角形面积
利用向量求三角形面积

我们了解的三角形面积公式有
{ s = a h 2 s = a b sin ⁡ θ 2 s = p ( p − a ) ( p − b ) ( p − c ) , ( p = a + b + c 2 ) \begin{cases} s=\frac{ah}{2} \\ s=\frac{ab\sin \theta }{2}\\ s=\sqrt[]{p(p-a)(p-b)(p-c)} ,(p=\frac{a+b+c}{2} ) \end{cases} s=2ahs=2absinθs=p(pa)(pb)(pc) ,(p=2a+b+c)
而当给定三个顶点坐标 a = ( x 1 , y 1 ) , b = ( x 2 , y 2 ) , b = ( x 3 , y 3 ) a=(x_1,y_1),b=(x_2,y_2),b=(x_3,y_3) a=(x1,y1),b=(x2,y2),b=(x3,y3),求三角形面积,对计算机而言下面这个公式是最合适的:
s = ( x 2 − x 1 ) ( y 3 − y 1 ) − ( y 2 − y 1 ) ( x 3 − x 1 ) 2 s=\frac{(x_2-x_1)(y_3-y_1)-(y_2-y_1)(x_3-x_1)}{2} s=2(x2x1)(y3y1)(y2y1)(x3x1)
众所周知,这个公式是由向量叉乘的来的,即我们求出向量 a b ⃗ , a c ⃗ \vec{ab},\vec{ac} ab ac ,二维向量叉乘的模的是以 a b , a c ab,ac abac为两条边,所围成的平行四边形面积,我们求得 a b , a c ab,ac abac,令其取二分之一即可得到上式
C o d e Code Code

double triangle(p& a, p& b, p& c) { return (b - a) * (b - c) / 2.0; }
判断点和线段的关系

首先我们可以讲点和线段的位置关系分为以下四种:

我们很容易发现当点在 3 , 4 3,4 34区域时,点和线段的夹角总是有一个钝角( ∠ p a b o r ∠ p b a \angle pab\space or \space \angle pba pab or pba),所以我们计算这对应向量的点积,就可以判断其余弦值的正负性,如果有小于 0 0 0的,那么点就在线段的这两个区域,根据 ∠ p a b \angle pab pab ∠ p b a \angle pba pba哪个是小于 0 0 0的,可以判断出点具体在哪个区域。

对于 1 , 2 1,2 12位置,我们求 a p ⃗ \vec{ap} ap a b ⃗ \vec{ab} ab 的叉积,通过叉积的正负可以得到点的具体区域,如果叉积为 0 0 0,并且点不在 3 , 4 3,4 34区域,那么点就在选段上。

代码就是利用上文重载的运算符进行判断即可,这里就不给出代码了。

求点到线段的距离

我们判断点和线段的位置关系,是为了计算点到线段的距离,当点在 3 , 4 3,4 34区域时,点到线段的距离就是到其端点的距离,在 1 , 2 1,2 12区域时,点到线段的距离就是到对应直线的距离。前者的区里很好求,用点与点的距离公式计算即可。对于后者,我们利用公式:
d = ∣ a p ⃗ × a b ⃗ ∣ ∣ a b ⃗ ∣ d=\frac{\left | \vec{ap}\times \vec{ab} \right | }{\left | \vec{ab}\right |} d= ab ap ×ab
这个公式也非常容易推导,因为叉乘的模是对应向量所围成平行四边形的面积,而 ∣ a b ⃗ ∣ \left | \vec{ab} \right | ab 是底边长度,面积除以底就是高,就可以得到对应距离。

C o d e Code Code

double p::disPoint(const p& a) const {//点到点的距离return sqrt((x - a.x) * (x - a.x) + (y - a.y) * (y - a.y));
}
double p::disline(const p& a, const p& b)const {//点到直线的距离p ap = (*this) - a, ab = b - a;return abs(ap * ab) / abs(ab);
}
double p::disSeg(const p& a, const p& b)const {//点到线段的距离//判断点和线段的位置关系if (((sh - a) | (b - a)) <= 0 || ((sh - b) | (a - b)) <= 0)return min(sh.disPoint(a), sh.disPoint(b));return disline(a, b);
}

补题杭电5-A.Tyhoon

判断点是否在任意多边形内

作者太懒了,还没学……

射线法
角度和判断法

完整代码

#define eps  1e-8
class p {
public:double x, y;//二维向量,表示一个点p(double _x = 0, double _y = 0):x(_x),y(_y){}//向量基本运算的实现+ - · *p operator+(const p& a)const { return p{ x + a.x,y + a.y }; }p operator-(const p& a)const { return p{ x - a.x,y - a.y }; }p operator-() const { return p{ -x,-y }; }double operator|(const p& a)const { return  x * a.x + y * a.y; }//点乘double operator*(const p& a)const { return x * a.y - y * a.x; }//叉乘p operator*(const ll a)const { return p{ x * a,y * a }; }//向量数乘double pow() const { return x * x + y * y; }//向量取平方//求距离double disPoint(const p& a) const;//点到点的距离double disline(const p& a, const p& b)const;//点到直线的距离double disSeg(const p& a, const p& b) const;//点到线段的距离};
double abs(const p& p) { return sqrt(p.pow()); }//向量取模double triangle(p& a, p& b, p& c) { return (b - a) * (b - c) / 2.0; }//求三角形面积double p::disPoint(const p& a) const {//点到点的距离return sqrt((x - a.x) * (x - a.x) + (y - a.y) * (y - a.y));
}double p::disline(const p& a, const p& b)const {//点到直线的距离p ap = (*this) - a, ab = b - a;return abs(ap * ab) / abs(ab);
}
double p::disSeg(const p& a, const p& b)const {//点到线段的距离//判断点和线段的位置关系if ((((*this) - a) | (b - a)) <= -eps || (((*this) - b) | (a - b)) <= -eps)return min(this->disPoint(a), this->disPoint(b));return disline(a, b);
}

这篇关于计算几何之点操作【模板】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/331844

相关文章

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

Python操作PDF文档的主流库使用指南

《Python操作PDF文档的主流库使用指南》PDF因其跨平台、格式固定的特性成为文档交换的标准,然而,由于其复杂的内部结构,程序化操作PDF一直是个挑战,本文主要为大家整理了Python操作PD... 目录一、 基础操作1.PyPDF2 (及其继任者 pypdf)2.PyMuPDF / fitz3.Fre

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND

Python使用openpyxl读取Excel的操作详解

《Python使用openpyxl读取Excel的操作详解》本文介绍了使用Python的openpyxl库进行Excel文件的创建、读写、数据操作、工作簿与工作表管理,包括创建工作簿、加载工作簿、操作... 目录1 概述1.1 图示1.2 安装第三方库2 工作簿 workbook2.1 创建:Workboo

SpringBoot集成EasyPoi实现Excel模板导出成PDF文件

《SpringBoot集成EasyPoi实现Excel模板导出成PDF文件》在日常工作中,我们经常需要将数据导出成Excel表格或PDF文件,本文将介绍如何在SpringBoot项目中集成EasyPo... 目录前言摘要简介源代码解析应用场景案例优缺点分析类代码方法介绍测试用例小结前言在日常工作中,我们经

Ubuntu 24.04启用root图形登录的操作流程

《Ubuntu24.04启用root图形登录的操作流程》Ubuntu默认禁用root账户的图形与SSH登录,这是为了安全,但在某些场景你可能需要直接用root登录GNOME桌面,本文以Ubuntu2... 目录一、前言二、准备工作三、设置 root 密码四、启用图形界面 root 登录1. 修改 GDM 配

JSONArray在Java中的应用操作实例

《JSONArray在Java中的应用操作实例》JSONArray是org.json库用于处理JSON数组的类,可将Java对象(Map/List)转换为JSON格式,提供增删改查等操作,适用于前后端... 目录1. jsONArray定义与功能1.1 JSONArray概念阐释1.1.1 什么是JSONA

Java操作Word文档的全面指南

《Java操作Word文档的全面指南》在Java开发中,操作Word文档是常见的业务需求,广泛应用于合同生成、报表输出、通知发布、法律文书生成、病历模板填写等场景,本文将全面介绍Java操作Word文... 目录简介段落页头与页脚页码表格图片批注文本框目录图表简介Word编程最重要的类是org.apach

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os