前排提示,本文章内容来源于牛客进阶课程计算几何。(本人仅转述加总结,想要了解更多请点击牛客竞赛课程专栏购买)

本博客为菜鸡转述,如有错误请轻喷,大佬请点击右上角离开。

本文章较长,概念性知识较多,请各位看官做好反复观看准备,以及准备好纸笔进行画图。

一、关于浮点数与精度

这一部分,我们要明确c++的三种浮点类型,以及为什么会有精度误差,怎么降低精度误差。

float double 以及long double

随着计算机的发展,我们基本以及淘汰了 float,所以我们只讲 double 和 long double。(不会把?不会吧!不会还有人在用float吧!!),在 IEEE-754 标准中,规定 double 是 64bit,其中一个 bit 用于表示正负,11位用于表示科学计数法,剩下的表示内容,附上图片。

由于在计算机内部是用二进制表示数字的,当我们要表示 1 4 \dfrac{1}{4} 41​ 的时候,计算机可以用 2 − 2 2^{-2} 2−2 来表示。
但是,当我们想表示 1 3 \dfrac{1}{3} 31​ 的时候,计算机会采用
2 − 2 + 2 − 3 + 2 − 4 + ⋯ + 2 − ∞ 2^{-2}+2^{-3}+2^{-4}+\cdots +2^{-\infty} 2−2+2−3+2−4+⋯+2−∞ ,按照极限理论,只要位数无限多,这两式子就相等。

那么问题来了,计算机只给了 52 位用于存储数据,我们就只能含泪丧失精度,在运算的时候这个损失还会进一步加大。在计算几何里,经常会有精度问题导致答案错误,为了降低精度误差,我们采用以下原则

  1. 能使用整数就不使用浮点数;
  2. 别用 float,视情况使用 long double;
  3. 减少数学函数的使用(如三角函数,开方);
  4. 比较时加入容限;
  5. 尽量通过判定而非计算去得到答案(这里你可能看不懂,但我下面会讲一个例子来解释它)。

关于 long double,不同编译器实现不一样,而且跟编译器的位数有关,但一般都比 double 位数多,所以当精度达不到你预期的时候请开 long double。

二、关于除 0

请大家务必记住 double 运算中编译器是不会对你的除 0 操作进行报错的!
请大家务必记住 double 运算中编译器是不会对你的除 0 操作进行报错的!
请大家务必记住 double 运算中编译器是不会对你的除 0 操作进行报错的!

重要的事情说三遍!在 double 类运算中,除以 0 一般会产生两种结果,一种是无穷数 inf,另一种是非数 NaN,具体如何触发请移步百度。
下面是关于 NaN 的比较的一张表

可以看到,除了 == 操作,其他的操作都返回的 false。当你发现你的运行程序有一些奇怪的 bug 的时候,你应该排查下是否有除 0 问题。

3、关于模板

写计算几何板子必须高度可靠,请大伙努力尝试构建属于自己的板子,在理解的基础上有限度的使用别人的板子。

4、一些关于点,线,多边形你必须知道的基础知识

1、关于向量
  • 向量的点积(Dot product)
    相信大家在中学都学过向量的点,这里就不做赘述。
  • 向量的叉积(Cross product)
    叉积的几何意义为一条方向垂直两线平面大小,其大小为 ∣ a ⃗ ∣ ∣ b ⃗ ∣ sin ⁡ α |\vec{a}| |\vec{b}| \sin \alpha ∣a ∣∣b ∣sinα。
    ,四指由 a ⃗ \vec{a} a 开始,指向 b ⃗ \vec{b} b ,拇指的指向就是 a ⃗ × b ⃗ \vec{a}\times \vec{b} a ×b 的方向,这一性质被称作 to-left 测试,是计算几何经常运用的向量性质之一。

2、点,线的定义

我们通常这样子来定义线段和点

struc Point
{   double x,y;
}
struct Line
{Point s,v;
}

值得注意的是,由于计算几何中大量运用了向量的性质,在线以及线段的定义里,我们推荐使用的是用一个端点一个向量的方法来定义。

3、比较常见的点线关系判断以及线线关系判断
  • 判断点与直线的关系
    通过 to-letf 测试,我们可以得知,如果一个点不在直线上,那么该点与直线上任意一点的所连成的直线的向量(我们命名为 a ⃗ \vec{a} a ),与该直线的向量(我们命名为 b ⃗ \vec{b} b ), a ⃗ × b ⃗ \vec{a}\times \vec{b} a ×b 的叉积不为0。反之我们判断其处于直线上。
  • 判断点与线段的关系
    我们先判断点是否处于直线上,在判断点的坐标是否处于线段的范围内,即可判断点是否处于直线

  • 判断点与射线
    同样的,我们先判断点是否处于与射线相同的直线上,然后利用向量叉积,注意是叉积的性质,来判断出发点到点构成的向量在射线上的投影, 如果是负数就不处于,反之处于。

  • 线线相交
    直接 to-left 我相信你们懂的

  • 线与线段相交
    判断线段的两个端点是否在直线的两侧

  • 线段与线段相交
    这是一个重点,请手动画图去理解。为了加强理解我将先抛出一个错误的做法。
    假设给你直线AB,CD,按照上面线与线段相交的例子,那我们是不是可以分别判断 AB 在 CD 两侧,CD 在 AB 两侧,这样子我们就可以判断线段是否相交了。

    考虑不到位

    你没考虑以下特殊情况,即三点共线四点共线
    网上流传的做法是先进行快速排斥实验,再 AB、CD 互相判断是否在相互在直线两侧。快速排斥实验是用于快速判断两矩形是否相交的实验
    如下图


    当以 AB、CD 为对角线的矩阵不相交的时候,那么两线段必然不相交,这包括了上面四点共线的特殊情况

    但是看看这代码量吧

    所以我们为什么不直接选择特判呢,当线段 A A A 与 B B B 处于同一直线的时候,看他们是否有一个端点在某另一个线段上,代量不就小多了。

  • 求线与线,线与线段,线段与线段的交点
    首先第一步要做的就是判断是否有交点。然后再求交,网上常用的是一般式求交点,代码长,计算多,一般都是用面积之比的方法推导出交点的式子
    俊杰老师用正弦推导了类似的的式子

    以上就是点与线,相关的练习可以看下方链接
    戳这里
    课程的第一章里其实还涉及到部分点与多边形的知识,同时也有对应的题目,其中讲了一个判断点在多边形内部的重要算法——光线回转法,对此我想专门写一个博客,到时候和关于牛客的练习的题解一起放出来,所以本博客到此为止。

如有想购买牛客计算几何的,戳这里 链接
后排推销其他牛客竞赛各类课程
dp
数学(强烈推荐)
字符串(强烈推荐)
数据结构

从0开始的计算几何(一)———点与线相关推荐

  1. 【FZU - 2140 】Forever 0.5 (计算几何,构造)

    题干: Given an integer N, your task is to judge whether there exist N points in the plane such that sa ...

  2. 点到直线的距离c语言程序,计算几何算法2. 关于线和点到线的距离(二维和三维)...

    关于直线 直线方程 点到直线的距离 用两点表示的直线 2d隐式表示的直线的情形 参数方程表示的直线 一个点到射线或线段的距离 代码实现 距离计算是计算机图形学和计算几何的基本问题,而且有很多关于这方面 ...

  3. 0.7秒,完成动漫线稿上色

    鱼羊 发自 凹非寺 量子位 报道 | 公众号 QbitAI 给一张这样繁复的线稿: 一步步填上颜色.赋上光影: 你猜需要多长时间? 答案是最快0.7秒. 没错,这又是AI的手笔. 厚涂不在话下,换种漫 ...

  4. 0.96寸ST7735的LCD 4线SPI调试小坑记录

    今天把0.96寸的ST7735的LCD从新唐的M030TD2AE移到STM32F103C8T6上用,驱动文件直接复制过来,屏幕死活显示不了. 搞了好久,最后能显示了,但还是不明白为什么,想不通,记录一 ...

  5. g9008v android7,三星G9008V(Galaxy S5 移动4G版 安卓5.0)手机快速救砖,线刷教程分享,小白轻松救活手机...

    三星G9008V(Galaxy S5 移动4G版 安卓5.0)手机变砖了怎么办?对于经常刷机的安卓玩家来说,碰到刷机失败导致三星G9008V(Galaxy S5 移动4G版 安卓5.0)手机无法启动甚 ...

  6. ug10.0缺少html文件,【答疑】安装好了的ug10.0没有插入应该怎么办呀? - 视频教程线上学...

    ug10.0快捷键大全,ug10.0常用快捷键有哪些 2018-04-02 浏览量:16042 提问者:平行线 回答: ug的版本有很多,下面小编给大家总结了ug10.0快捷键,ug10.0快捷键大全 ...

  7. 一分二USB-C双PD3.0智能快充与一般充电线区别

    目前市面上存在的USB-C PD充电线类似大致分为: 1:C TO C 的PD快充线(或是全功能(带E-Marker 过5A或者不带过3A)或者只具备PD快充) 2:C TO 2C 与 C TO 1C ...

  8. 两直线平行交叉相乘_计算几何算法5. 直线、线段和平面相交(2D和3D)

    直线和线段相交 平面相交 直线-平面相交 两平面相交 三个平面相交 实现 intersect2D_2Segments() inSegment() intersect3D_SegmentPlane() ...

  9. A - TOYS(POJ - 2318) 计算几何的一道基础题

    Calculate the number of toys that land in each bin of a partitioned toy box. 计算每一个玩具箱里面玩具的数量 Mom and ...

最新文章

  1. mybatis-generator 插件扩展,生成支持多种数据库的分页功能
  2. Jetbrains全系列完美破解--------亲测可用
  3. Pycharm设置utf-8自动显示
  4. TPT:中科院等提出用于VideoQA的跨模态交互时间金字塔Transformer
  5. php ucenter单点登录,说说ucenter的单点登录
  6. 苹果4创建id显示服务器错误,苹果无法创建账户是什么意思
  7. 免费可商用的音乐资源
  8. 短视频热度还能持续多久
  9. 视觉SLAM十四讲从理论到实践第二版源码调试笔记(理论基础1-6章)
  10. wangeditor上传本地视频的方法
  11. python经典代码
  12. 如果实现类似微信附近的人功能
  13. #牛客网 吐泡泡 (栈)
  14. 【答读者问12】如何理解backtrader的line以及对line进行操作?
  15. Keystone基本命令
  16. 移动端手机调试的方法
  17. java unpack_参数,解包-UNpack
  18. Java开源技术分享交流群
  19. Android File格式上传图片
  20. Linux单机运行vasp,VASP单机编译

热门文章

  1. 分享阿里云网站备案号问题及解答
  2. fpga中求有符号数的绝对值
  3. 无线网打不开无服务器,无线路由器可以上网但网页打不开怎么办
  4. 保存和加载模型的方法
  5. 七、JDK1.7中HashMap扩容机制
  6. 【31】核心易中期刊推荐——电子信息技术计算机技术
  7. 数字信号处理--基于MATLAB的小波去噪算法--小波变换在信号降噪和压缩中的应用
  8. oracle和mysql的安装_Windows下Oracle的下载与安装
  9. QSortFilterProxyModel实现筛选与排序固定行号(垂直表头序号)
  10. office word2007怎样去掉回车符