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

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

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


原文地址:https://blog.csdn.net/c661280411470yb/article/details/132078688
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/331844

相关文章

Python对PDF书签进行添加,修改提取和删除操作

《Python对PDF书签进行添加,修改提取和删除操作》PDF书签是PDF文件中的导航工具,通常包含一个标题和一个跳转位置,本教程将详细介绍如何使用Python对PDF文件中的书签进行操作... 目录简介使用工具python 向 PDF 添加书签添加书签添加嵌套书签Python 修改 PDF 书签Pytho

Java如何根据word模板导出数据

《Java如何根据word模板导出数据》这篇文章主要为大家详细介绍了Java如何实现根据word模板导出数据,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... pom.XML文件导入依赖 <dependency> <groupId>cn.afterturn</groupId>

Java计算经纬度距离的示例代码

《Java计算经纬度距离的示例代码》在Java中计算两个经纬度之间的距离,可以使用多种方法(代码示例均返回米为单位),文中整理了常用的5种方法,感兴趣的小伙伴可以了解一下... 目录1. Haversine公式(中等精度,推荐通用场景)2. 球面余弦定理(简单但精度较低)3. Vincenty公式(高精度,

Mysql数据库中数据的操作CRUD详解

《Mysql数据库中数据的操作CRUD详解》:本文主要介绍Mysql数据库中数据的操作(CRUD),详细描述对Mysql数据库中数据的操作(CRUD),包括插入、修改、删除数据,还有查询数据,包括... 目录一、插入数据(insert)1.插入数据的语法2.注意事项二、修改数据(update)1.语法2.有

Python文件操作与IO流的使用方式

《Python文件操作与IO流的使用方式》:本文主要介绍Python文件操作与IO流的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、python文件操作基础1. 打开文件2. 关闭文件二、文件读写操作1.www.chinasem.cn 读取文件2. 写

Java实现MinIO文件上传的加解密操作

《Java实现MinIO文件上传的加解密操作》在云存储场景中,数据安全是核心需求之一,MinIO作为高性能对象存储服务,支持通过客户端加密(CSE)在数据上传前完成加密,下面我们来看看如何通过Java... 目录一、背景与需求二、技术选型与原理1. 加密方案对比2. 核心算法选择三、完整代码实现1. 加密上

SQL常用操作精华之复制表、跨库查询、删除重复数据

《SQL常用操作精华之复制表、跨库查询、删除重复数据》:本文主要介绍SQL常用操作精华之复制表、跨库查询、删除重复数据,这些SQL操作涵盖了数据库开发中最常用的技术点,包括表操作、数据查询、数据管... 目录SQL常用操作精华总结表结构与数据操作高级查询技巧SQL常用操作精华总结表结构与数据操作复制表结

Java使用Stream流的Lambda语法进行List转Map的操作方式

《Java使用Stream流的Lambda语法进行List转Map的操作方式》:本文主要介绍Java使用Stream流的Lambda语法进行List转Map的操作方式,具有很好的参考价值,希望对大... 目录背景Stream流的Lambda语法应用实例1、定义要操作的UserDto2、ListChina编程转成M

Python中Flask模板的使用与高级技巧详解

《Python中Flask模板的使用与高级技巧详解》在Web开发中,直接将HTML代码写在Python文件中会导致诸多问题,Flask内置了Jinja2模板引擎,完美解决了这些问题,下面我们就来看看F... 目录一、模板渲染基础1.1 为什么需要模板引擎1.2 第一个模板渲染示例1.3 模板渲染原理二、模板

Git可视化管理工具(SourceTree)使用操作大全经典

《Git可视化管理工具(SourceTree)使用操作大全经典》本文详细介绍了SourceTree作为Git可视化管理工具的常用操作,包括连接远程仓库、添加SSH密钥、克隆仓库、设置默认项目目录、代码... 目录前言:连接Gitee or github,获取代码:在SourceTree中添加SSH密钥:Cl