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

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调用Orator ORM进行数据库操作

《Python调用OratorORM进行数据库操作》OratorORM是一个功能丰富且灵活的PythonORM库,旨在简化数据库操作,它支持多种数据库并提供了简洁且直观的API,下面我们就... 目录Orator ORM 主要特点安装使用示例总结Orator ORM 是一个功能丰富且灵活的 python O

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、

Python利用自带模块实现屏幕像素高效操作

《Python利用自带模块实现屏幕像素高效操作》这篇文章主要为大家详细介绍了Python如何利用自带模块实现屏幕像素高效操作,文中的示例代码讲解详,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、获取屏幕放缩比例2、获取屏幕指定坐标处像素颜色3、一个简单的使用案例4、总结1、获取屏幕放缩比例from

通过prometheus监控Tomcat运行状态的操作流程

《通过prometheus监控Tomcat运行状态的操作流程》文章介绍了如何安装和配置Tomcat,并使用Prometheus和TomcatExporter来监控Tomcat的运行状态,文章详细讲解了... 目录Tomcat安装配置以及prometheus监控Tomcat一. 安装并配置tomcat1、安装

Python中操作Redis的常用方法小结

《Python中操作Redis的常用方法小结》这篇文章主要为大家详细介绍了Python中操作Redis的常用方法,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解一下... 目录安装Redis开启、关闭Redisredis数据结构redis-cli操作安装redis-py数据库连接和释放增