相等判断函数

有的时候我们会用到判断一个数是否大于0,小于0或等于0。大于小于还好办,等于的话可能会出现例如0.00000000001≠0的现象,但是实际计算的时候这两个数是应该按照相等来算的。所以,我们可以自己定义一个函数dcmp(),来判断是否和0极其近似相等。

int dcmp(const double x)
{const double eps = 1e-10;if (std::fabs(x) < eps)return 0;elsereturn x < 0 ? -1 : 1;
}

直线的参数表示

参数式:

\[P = P_0 + tv\]

这个式子的意思就是直线上的所有点的坐标都可以表示成\(P_0+tv\)的格式,其中\(v\)叫做直线的方向向量,\(P_0\)可以用来表示这条直线的起点,\(t\)叫做参数。

直线的交点

如果可以确保直线\(P+tv\)和\(Q+tw\)有唯一交点,且\(\vec v \cdot \vec w\)非零时,如果用\(t_1\)表示该点与\(P\)的距离,用\(t_2\)表示该点与\(Q\)的距离,易证

\[t_1=\frac{\vec w\times \vec u}{\vec v\times \vec w}, t_2=\frac{\vec v\times \vec u}{\vec v\times \vec w}\]

实现如下:

// 这里是用了上述的t1的思路,用交点和P的交点距离求交点
Point getLineInter(Point P, Vector v, Point Q, Vector w) // P + tv和Q + tw的……两点式……
{Vector u = P - Q;double t = mulCross(w, u) / mulCross(v, w);return P + v * t;
}

点到直线的距离

点到直线的距离,很简单,就是叉乘乘出来的那个平行四边形的面积除以它的底。

double getDisPointToLine(Point p, Point a, Point b)
{Vector v1 = b - a, v2 = p - a;return std::fabs(mulCross(v1, v2) / v1.getNorm()); // 如果不加std::fabs,得到的将是有向长度
}

点到线段的距离

点到线段的距离一共有三种情况,设投影点为\(Q\),则有\(Q\)在线段\(AB\)上①,\(Q\)在线段\(AB\)的延长线上②,\(Q\)在线段\(AB\)的反向延长线上③。

对于①:所求的就是点 \(P\)到直线\(AB\)的距离。

对于②:所求的就是向量 \(\vec {PB}\)的模。

对于③:所求的就是向量 \(\vec {PA}\)的模。

至于\(Q\)的位置在哪里,可以用向量的点乘判断。

double getDisPointToSeg(Point P, Point a, Point b)
{if (a == b)return (P - a).getNorm();Vector v1 = b - a, v2 = p - a, v3 = p - b;if (dcmp(mulDot(v1, v2)) < 0)return v2.getNorm();else if (dcmp(mulDot(v1, v3)) > 0)return v3.getNorm();elsereturn std::fabs(mulCross(v1, v2) / v1.getNorm());
}

点与线段的位置关系

一个点和一条线段无非就是两种关系,要么相交,要么相离。如果相交的话就相当于线段的两端点与该点所组成向量共线,且互相组成的两条向量方向相反。所以根据这两个性质,很容易想到需满足的性质为:点乘 < 0,且叉乘 == 0。为了避免精度错误,我这里用dcmp()来判断是否为0。

bool onSeg(Point P, Point hajimari, Point owari)
{return dcmp( mulCross(hajimari - P, owari - P) ) == 0 &&dcmp( mulDot(hajimari - P, owari - P ) ) < 0;
}

线段相交判定

这里的线段相交,是指“规范相交”,即不算在端点处相交的情况。两线段相交的条件很好理解:每条线段的两个端点都在另一条线段的两侧。也就是说,一条线段两侧的端点所组成的向量分别和另一条线段自己构成的向量的叉乘符号相反。

bool isSegInter(Point a1, Point a2, Point b1, Point b2)
{double c1 = mulCross(a2 - a1, b1 - a1),c2 = mulCross(a2 - a1, b2 - a1),c3 = mulCross(b2 - b1, a1 - b1),c4 = mulCross(b2 - b1, a2 - b1);return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
}

点在直线上的投影

既然是点在直线上的投影,那么我们可以把直线\(AB\)通过参数式表示成\(A + tv\)的形式,如果设\(P\)的投影点在\(AB\)上为\(Q\),并且设\(Q\)的坐标为\(A + t_0v\),那么根据\(PQ\perp AB\),不难推出两个向量点乘 == 0。因此,\(\vec v \cdot [P - (A + t_0\vec v)]=0\),根据分配率,可以推出:\(\vec v \cdot (P - A) - t_0 \times (\vec v^2)=0\),这样就可以解出\(t_0\),从而得到\(Q\)。

Point getLineProj(Point P, Point a, Point b)
{Vector v = B - A;return A + v * (mulDot(v, P - a) / mulDot(v, v));
}

转载于:https://www.cnblogs.com/edwardtsui/p/6783233.html

计算几何摸黑(2)-点和直线相关推荐

  1. 【POJ - 3304 】Segments(计算几何,思想转化,直线和线段相交)

    题干: Given n segments in the two dimensional space, write a program, which determines if there exists ...

  2. [计算几何] (二维)圆与直线的交点

    给出圆心O的坐标, 和半径r, 再给出点A,B的坐标构成直线AB, 求出圆与直线AB交点的坐标 如下图 Step1: 首先求出圆心c在直线l 上的投影点pr的坐标 可通过求解向量p1pr(p1pr的长 ...

  3. 计算几何之求圆与直线的交点

    求圆与直线的交点的方法是: 求圆心c在直线l上的投影点pr 求出直线l上的单位向量e 根据r和pr的长度来计算出圆内线段部分的一半base 用pr±base*e即得到答案 题目:CGL_7_D AC代 ...

  4. 旋转卡壳凸包(不用一下子就学完所有)

    目录 前言 参考博客 前置知识 1.极角排序 2.凸包(默认逆时针) 3.对踵点 旋转卡壳能解决的各类问题 1.计算距离 1.1凸多边形直径 1.2凸多边形宽 1.3凸多边形间最大距离 1.4凸多边形 ...

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

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

  6. 判断两条直线是否相交c语言,计算几何-两条线段是否相交(三种算法)

    原标题:计算几何-两条线段是否相交(三种算法) 计算几何中,判断线段是否相交是最基本的题目. 所谓几何, 最基本的当然就是坐标, 从坐标中我们可以知道位置和方向,比如:一个点就是一个位置,两点确定一条 ...

  7. 计算几何——直线、线段和圆的交点

    汇总篇:计算几何汇总 首先,求出圆心O在直线AB上的投影点E 然后求出AB的方向向量e=AB/|AB| 令EC=ED=base base = sqrt(r^2-OE^2) EC = -base *e ...

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

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

  9. 计算几何(二):线段与直线,点与线,线与线的关系

    写在前面 本文基于fxj巨佬的计算几何全家桶,并基于原文进行了自己的一些整理了经验补充,阅读本文前请前往支持巨佬fxj. 直线/线段的表示: 直线与线段的表示采用两点+方向向量的表示方法. 此外,一般 ...

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

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

最新文章

  1. Linux之Ubuntu切换root su -
  2. CentOS6.5 安装SVN 及http访问
  3. Python 全栈开发基础
  4. C#创建用户控件 - IPv4地址输入框
  5. android http 慢,android httpurlconnection數據連接速度慢
  6. Python之路(一)初识Python
  7. vivo解bl锁_黔隆科技刷机教程酷派Y82820忘记密码刷机解锁降级救砖解屏幕锁账户锁教程...
  8. 上海嵌联自控供应车流量统计系统
  9. PAT --- 1055.集体照 (25 分)
  10. 2021年7月20日我国暴雨趋势遥感监测与评估
  11. unity3D灯光烘焙(二)
  12. Android肝帝战纪之字体图标库(iconify)的简单使用
  13. 计算机中的同步和异步
  14. python如何定义函数k_Python 函数
  15. Python爬取王者荣耀官网图片
  16. 用汽车拉苹果的例子来说HTTPS的安全性很容易理解 但HTTPS并不是绝对可靠的
  17. 黑马——C语言的一些基础(2)
  18. python实现简单的ps色阶调整过程
  19. Unity关于无法新建项目的可能解决办法
  20. PV、EV、AC、SV、CV、SPI、CPI

热门文章

  1. 程序员如何删库?(一看就会)Linux
  2. Team Foundation Server BuilderService LOG
  3. [资源]--IOS捷径大全,众多实用小功能
  4. ALDS1_7_C:Tree Walk
  5. Asp.net中汉字转换成为拼音
  6. Hello I am whiter. Nice to meet you!!!
  7. 【Java基础】ArraylistLinkedList机制,failfastfailsafe
  8. 163邮箱服务器注册不了怎么办,outlook邮箱添加163邮箱账户失败该怎么办?
  9. 判断单链表是否中心对称
  10. c语言 愚人节题目,愚人节整人题目大全,耍的就是你!