写在前面

本文基于fxj巨佬的计算几何全家桶,并基于原文进行了自己的一些整理了经验补充,阅读本文前请前往支持巨佬fxj。

前言:

计算几何的使用有一些基本原则,它们能帮助你快速地找到代码中出现的问题并方向明确地解决它们。

  1. 精度:计算几何丢精度是必有的事情,问题只在于你能否满足题目的精度要求。为了避免较大的精度误差,应当减少三角函数,除法,根号的使用,同时,根号函数的精度似乎十分健康。当精度不够时,可以选择long double来解决问题,不过代价就是跑得更慢。
  2. 简洁: 主要通过减少分类讨论的情况数和合理的模块化实现。

精度问题

由于计算几何常用double类型计算,因此丢精度是必然会出现的。这个问题主要体现在比较运算中。

举个例子,在计算几何中算出一个三角形的面积是2.999,但是我们知道这肯定是存在误差的,因此它实际上应当不是2.99,假设在没有误差时它的面积应是3,那么我们要把这个三角面积比较时,就要忽略这一点小误差。

解决这个问题,就要引入贯穿了整个计算几何的核心内容:存在误差时的比较运算
e p s eps eps是一个极小量,通常在 [ 1 0 − 12 , 1 0 − 8 ] [10^{-12},10^{-8}] [10−12,10−8]的范围内,表示精度要求。

a = b a=b a=b → → → a b s ( a − b ) abs(a−b) abs(a−b) < < < e p s eps eps
a < b a < b a<b → → → a < b a < b a<b − − − e p s e p s eps
a > b a > b a>b → → → a > b a>b a>b + + + e p s eps eps

以上比较式的很容易证明:

  1. 认为 a = b a=b a=b时表达式不应成立,同理可得其他两式。
  2. 也可通过分情况讨论:认为 a a a存在误差, b b b不存在误差,分类讨论 a a a偏大偏小的情况。
    注意:这里认为a的误差值不超过 e p s eps eps

由于浮点数计算产生的精度误差是普遍存在于计算几何中,因此通过计算集合得出的数进行的比较运算中,必须用上文的格式写出。

最容易出现的一个错误就是在将某数 a a a与 0 0 0比较时将式子写成 a > 0 a>0 a>0而非 a > 0 + e p s a>0+eps a>0+eps即 a > e p s a>eps a>eps
范神在部分模板中忽略了这一点,现已更正

点/向量相关:

表示

在计算几何中,点和向量往往是等价的,且经常出现一个变量被同时当作点和向量使用的现象,因此一起表示。

struct V
{double x,y;V():x(0),y(0){};V(double a,double b):x(a),y(b){};
}dot[maxn];inline void input(V &a){a.x=read();a.y=read();}void print(const V &a,int op=1){printf("%.10lf %.10lf",a.x,a.y);putchar(op?10:32);}
//op=endl or space

向量的基本运算:

基本的加、减、乘、除、点积、叉积、模长、中点、垂直向量、向量单位化、三角形面积。

拓展
高维点积:定义不变,但在投影方面几何意义只对二维和三维空间有效。
高维叉积:叉积在k维下的定义是三行k列的行列式,第一行为各维度的单位向量,二三行为两个点各自在对应维度的坐标。

注意:
(1)严格意义上,向量叉积是一个(更高维,二维向量叉积为三维)的向量,模长为 x 1 y 2 − x 2 y 1 x_1y_2-x_2y_1 x1​y2​−x2​y1​,方向垂直与纸面,遵循右手定则,这也是叉积可以表示负面积的原因。
(被叉积表示面积的平行四边形是叉积在二维平面内的投影)。
(2)以下模板中的垂直向量并没有考虑方向的问题。

Code

struct V
{double x,y;V():x(0),y(0){};V(double a,double b):x(a),y(b){};
}//点和向量的存储inline void input(V &a){a.x=read();a.y=read();}void print(const V &a,int op=1){printf("%.10lf %.10lf",a.x,a.y);putchar(op?10:32);}
//op=endl or spaceinline V operator + (const V &a,const V &b){return (V){a.x+b.x,a.y+b.y};}
inline V operator - (const V &a,const V &b){return (V){a.x-b.x,a.y-b.y};}inline V operator * (const V &a,const double &x){return (V){a.x*x,b.y*x};}
inline V operator * (const double &x,const V &a){return (V){a.x*x,b.y*x};}
inline V operator / (const V &a,const double &x){return (V){a.x/x,b.y/x};}inline bool operator == (const V &a,const V &b){return abs(a.x-b.x)<eps && abs(a.y-b.y)<eps;}
inline bool operator != (const V &a,const V &b){return !(a==b);}inline double operator * (const V &a,const V &b){return a.x*b.x+a.y*b.y;}
inline double operator ^ (const V &a,const V &b){return a.x*b.y-b.x*a.y;}inline double len (const V &a,const V &b){return sqrt(a.x*b.x+a.y*b.y);}inline V mid(const V &a,const V &b){return (V){(a.x+b.x)/2,(a.y+b.y)/2};}中点坐标公式求中点
inline V cui(const V &a){return (V){a.y,-a.x};}//求垂直向量,使用k1*k2=-1的性质
inline V danwei(const V &a){return a/len(a);}//求单位向量inline double tri_S(const V &a,const V &b,const V &c){return abs((b-a)*(c-a))/2;}//求向量或三点所成三角形面积inline bool operator < (const V &a,const V &b){return a.x<b.x || (abs(a.x-b.x)<eps && a.y<b.y-eps);}
//这个向量的大小比较是将向量按照x为第一关键字,y为第二关键字,升序排列。
//这个算符会在求凸包中被大量使用,平时倒是没什么用

角度相关:

向量夹角:

用向量点积易得。
这个角的取值范围是 [ 0 , π ] [0,π] [0,π].

inline double angle(const V &a,const V &b){return acos( a*b / len(a) / len(b));}
inline bool dun(const V &a,const V &b,const V &c){return ((b-a)*(c-a))<-eps;}//angle:BAC
inline bool rui(const V &a,const V &b,const V &c){return ((b-a)*(c-a))>eps;}
inline bool zhi(const V &a,const V &b,const V &c){return abs(((b-a)*(c-a)))<eps;}

向量的旋转:

设原向量为 ( x , y ) (x,y) (x,y),旋转角度为 θ θ θ,(注意:θ的正负判断遵循右手定则,即逆时针旋转的角为正角),
则旋转后的得到向量为 ( x c o s θ − y s i n θ , x s i n θ + y c o s θ ) (xcosθ-ysinθ,xsinθ+ycosθ) (xcosθ−ysinθ,xsinθ+ycosθ)。

证明:用复数乘法,在复平面内 ( x , y i ) ⋅ ( c o s θ , s i n θ i ) (x,yi)·(cosθ,sinθi) (x,yi)⋅(cosθ,sinθi),结合复平面的性质可得 ( x c o s θ − y s i n θ , i x s i n θ + i y c o s θ ) (xcosθ-ysinθ,ixsinθ+iycosθ) (xcosθ−ysinθ,ixsinθ+iycosθ),结果同上.

inline V rotate(const V &a,const double t)
{double s=sin(t),c=cos(t);return (V){a.x*c-a.y*s,a.x*s+a.y*c};
}

计算几何(一):点,向量相关推荐

  1. 计算几何,三维向量的旋转

    写这篇日志有两个目的:一来是想测试新装上去的 LaTeX 插件显示数学公式是否好用(不过貌似通过RSS获取到的日志是没有办法显示的--):二来是对于三维向量绕任意轴的旋转之前我都是用结论的,今天因为做 ...

  2. java 三维向量类_计算几何,三维向量的旋转 | 学步园

    写这篇日志有两个目的:一来是想测试新装上去的LaTeX插件显示数学公式是否好用(不过貌似通过RSS获取到的日志是没有办法显示的--):二来是对于三维向量绕任意轴的旋转之前我都是用结论的,今天因为做计算 ...

  3. hdu 1174:爆头(计算几何,三维叉积求点到线的距离)

    爆头 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...

  4. 计算几何——向量的叉乘、点乘、夹角

    汇总篇:计算几何汇总 一.向量的叉乘 向量p=(x1,y1), q=(x2,y2) 则 pxq=x1.y2-x2.y1 pxq= - qxp 叉乘的大小等于于2倍三角形面积. 右手法则:手掌表示p向量 ...

  5. 2019秦皇岛ccpc A题:Angle Beats[计算几何:统计符合直角三角形的个数]+[向量hash+3hash]

    题目链接 题目大意:就是已经知道一些点集合{p},然后q次询问每次给出一个点A,问你这个点和点集合里面多少对点可以构成三角形? 解题思路:很无奈这道题卡常了我们常规思路就是:我们分类讨论A这个点,因为 ...

  6. 计算几何总结1———点与向量

    文章目录 点与向量 1.点之间的距离 总结 2.向量的运算(加,减,乘,除)和判等 总结 3.点积和叉积 4.叉积的应用 持续更新...... 提示:这里用到的数据类型都为double,可根据具体情况 ...

  7. 【计算几何】向量叉积和凸包 | 引射线法 | 判断点是否在多边形内部 | 葛立恒扫描法 | Cross Product and Convex Hul

     猛戳!跟哥们一起玩蛇啊 

  8. 二维几何基础大合集!《计算几何全家桶(一)》(基础运算、点、线、多边形、圆、网格)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的模板整合计划 目录 1.基本运算 1.1 判断正负函数(sgn) 1.2 点积(数量积.内积)(Dot) 1.3 向量积 ...

  9. 【第一道计算几何题】 UVA11178 Morley‘s Theorem (二维几何,旋转直线求求交点)

    整理的算法模板合集: ACM模板 要求D点我们只需要把直线BC向左旋转a/3,向右旋转b/3得到两直线求交点即可. 秒啊秒啊 解锁技能树--计算几何,终于能加一个计算几何版块了 #include< ...

最新文章

  1. 外媒:英国索尔兹伯里事件中受伤警察已重返工作
  2. linux中ping命令的用法
  3. 稀有名词解释——Java 堆污染(犄角旮旯问题)
  4. mongodb模糊查询包含特殊字符
  5. Docker用Commit给容器做快照
  6. Error:Connection timed out: connect
  7. 前端开发中那些不招人“待见”的功能
  8. openCV播放视频的程序
  9. Pydev 的覆盖率测试python coverage以及其他使用
  10. Leetcode 224.基本计算器
  11. nis从服务器接替nis主服务器步骤
  12. keeplive发生脑裂问题处理过程
  13. 明清时期中央朝廷与地方关系中的江南著姓望族
  14. 北大青鸟python学费_北大青鸟学费贵吗,北大青鸟学费标准_北大青鸟综合校区为您解答...
  15. springboot毕业设计题目课题参考
  16. L2正则化和collection,tf.GraphKeys
  17. 计算机专用英语词汇1500词打印,计算机专用英语词汇1500词(4)
  18. 复制黏贴直接上传图片
  19. 基于51单片机——八路彩灯设计
  20. 单例模式实例——神码设计模式

热门文章

  1. 【开发必备】2018最新中国国内可用API合集
  2. 题解 | #F. 一个经典概率问题(提供一个好想好实现不用积分的方法)#
  3. 中国前五国产数据库特性比较
  4. mac 每次启动终端都会提示 zsh compinit: insecure directories, run compaudit for list. Ignore insecure
  5. 【ChatGPT4】 如何写爆款文案
  6. java手机游戏主角技能上剑魂,sa.java 源代码在线查看 - 手机游戏之剑魂。。j2me编写。。经典游戏只一 资源下载 虫虫电子下载站...
  7. vue两个按钮切换_vue实现按钮切换图片
  8. 云服务器出租产业,云服务器一般租多大的比较合适?
  9. AI也能作曲!OpenAI神经网络能生成任何流派音乐
  10. 十二个“一”的转换视角解读