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

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 ZIP文件操作技巧详解

《PythonZIP文件操作技巧详解》在数据处理和系统开发中,ZIP文件操作是开发者必须掌握的核心技能,Python标准库提供的zipfile模块以简洁的API和跨平台特性,成为处理ZIP文件的首选... 目录一、ZIP文件操作基础三板斧1.1 创建压缩包1.2 解压操作1.3 文件遍历与信息获取二、进阶技

Java中字符串转时间与时间转字符串的操作详解

《Java中字符串转时间与时间转字符串的操作详解》Java的java.time包提供了强大的日期和时间处理功能,通过DateTimeFormatter可以轻松地在日期时间对象和字符串之间进行转换,下面... 目录一、字符串转时间(一)使用预定义格式(二)自定义格式二、时间转字符串(一)使用预定义格式(二)自

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

IDEA自动生成注释模板的配置教程

《IDEA自动生成注释模板的配置教程》本文介绍了如何在IntelliJIDEA中配置类和方法的注释模板,包括自动生成项目名称、包名、日期和时间等内容,以及如何定制参数和返回值的注释格式,需要的朋友可以... 目录项目场景配置方法类注释模板定义类开头的注释步骤类注释效果方法注释模板定义方法开头的注释步骤方法注

Python 中的 with open文件操作的最佳实践

《Python中的withopen文件操作的最佳实践》在Python中,withopen()提供了一个简洁而安全的方式来处理文件操作,它不仅能确保文件在操作完成后自动关闭,还能处理文件操作中的异... 目录什么是 with open()?为什么使用 with open()?使用 with open() 进行

Linux ls命令操作详解

《Linuxls命令操作详解》通过ls命令,我们可以查看指定目录下的文件和子目录,并结合不同的选项获取详细的文件信息,如权限、大小、修改时间等,:本文主要介绍Linuxls命令详解,需要的朋友可... 目录1. 命令简介2. 命令的基本语法和用法2.1 语法格式2.2 使用示例2.2.1 列出当前目录下的文

Mysql表的简单操作(基本技能)

《Mysql表的简单操作(基本技能)》在数据库中,表的操作主要包括表的创建、查看、修改、删除等,了解如何操作这些表是数据库管理和开发的基本技能,本文给大家介绍Mysql表的简单操作,感兴趣的朋友一起看... 目录3.1 创建表 3.2 查看表结构3.3 修改表3.4 实践案例:修改表在数据库中,表的操作主要

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4