ACM 计算几何基础模板

这篇博客介绍了计算几何中常用的数据结构和操作,包括点、向量、直线和圆的定义及函数封装。作者提供了误差处理常数、点的距离和斜率计算、向量的点积、叉积、旋转以及直线和圆的相关函数。此外,还分享了用于点排序的函数,如LeftThenLow和angleSort。内容适合对计算几何有一定了解的读者,便于理解和复用代码。
摘要由CSDN通过智能技术生成

在ACM计算几何中,我们常常重复用到许多方法,例如求点距,求直线方程,等等。不妨利用模板总结之。这些模板为我从网上学习后加入自己的理解糅合得来qwq,看了很多的博客,查了很多书籍,其中印象最深的是林夕林夕关于计算几何模板的总结,大家也可以去参考他的应该比我的更详细qwq
(不过大佬最近好像出没比较少了)
所以我这个主要还是留着自己参考吧,能帮到他人再好不过了

为了不产生歧义,方便理解,本模板使用笛卡尔坐标系,封装的多是数学中常见的函数。

前置知识:高中数学,向量外积相关

模板仅供参考学习,不保证任何情况下不会因为误差WA掉或是RE掉

基础声明

首先,打acm的时候double这个数据类型就比较恶心(容易浮动导致误差),而计算几何中各种计算又几乎没法单独用整型解决。因此我们需要一个小常数来判断误差。

例如,计算啥啥面积的时候,我们需求误差在10的-6次方以内,那么就可以定义这个常数为10的-6次方:

const double eps = 1e-6;

然后,我们的目标是,当误差小于1e-6时,误差将被忽略不计。也就是说,两个数比较时,差距在1e-6以内,我们就可以认为这两个数相等。

一般的计算中,本来两个相等的数字,因为我们计算路径的不同,浮点数就可能会发生不同的浮动,导致 = = == ==运算符检查本来应该相等的两个浮点数时返回了0。这时我们就可以用误差来避免了。

以下为重载大小判断的函数:

int cmp(const double& a, const double& b)
{
   
	if(fabs(a - b) < eps) return 0; // 若误差范围内相等,返回0
	else if(a > b) return 1; // 若a > b,返回1
	return -1;	// 若a < b,返回-1
}

另外还有计算几何中常用的常量:

const double pi = 3.1415927536;
const double INF = 1e100;

浮点数的表数范围巨大,可以表示到10的200多次方,但是实际上几十次方浮动误差就大到难以接受了……因此,我们可以用一个100次方表示无穷大,反正它够大就对了,但是却不能直接拿来做计算(总之就是误差非常大)。

另外,我们也常用C++内置的反三角函数acos()来求角度。但是这个函数有个问题,我们都知道反余弦函数的定义域是 [ − 1 , 1 ] [-1,1] [1,1],然而由于浮点数的浮动偏移,我们得到的1很可能实际上是1.00001,1.0000001这种数,这些数据不在反余弦函数的定义域内了,那么把它们作为参数传进去就没法计算,就会导致Runtime Error,就没法AC!QAQ!所以我们可以把acos()函数二次包装一下,打消这个顾虑。

double acs(double x)
{
   
	if(x > 1) x = 1;
	else if(x < -1) x = -1;
	return acos(x);
}

顺便把反正弦函数也包装一下

double asn(double x)
{
   
	if(x > 1) x = 1;
	else if(x < -1) x = -1;
	return asin(x)
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值