计算几何问题汇总--圆与矩形

我在上一篇博客中(详见:计算几何问题汇总–点与线的位置关系)谈到了计算几何最基本的问题:解决点与线(线段or直线)的位置关系判断。那么,更进一步,还需要探讨复杂一点的情况:比如面与线,面与面之间的关系。本文中,我就先说说最常见的两种几何图形:圆与矩形。我将就矩形与圆的碰撞判断问题、线与矩形、线与圆之间的碰撞问题作出分析,以及给出这些解决问题的算法、代码。

在此之前,我默认所有对本文内容感兴趣的读者,都了解基本的计算几何概念,并且对我的上一篇博客:计算几何问题汇总–点与线的位置关系 所讲的内容基本熟悉。因为本文涉及的算法,几乎全部都用到了上一篇博客中所定义的类和函数。

简单将上一篇博客的内容陈列如下,方便读者阅读后面本文的算法:

模块名:PointLine

class Point: 点类,两个属性,分别是横纵坐标x, y

class Segment: 线段类,两个属性,分别是两个端点p1, p2

class Line: 直线类,两个属性,分别是直线上任意两点p1, p2

class Vector: 向量类,以向量的起点和终点为参数,建立一个由横纵坐标为两个属性的类

func: pointDistance(p1, p2): 计算两点之间距离的函数。返回一个浮点型的值

func: pointToLine(C, AB): 计算点C到直线AB的距离。返回一个浮点型的值

func: pointInLine(C, AB): 判断点C是否在直线AB上。在,返回True;不在,返回False

func: pointInSegment(C, AB): 判断点C是否在线段AB上。在,返回True;不在,返回False

func: linesAreParallel(l1, l2): 判断两条直线l1, l2是否平行。平行,返回True;不平行,返回False

func: crossProduct(v1, v2): 计算两个向量叉积

func: segmentsIntersect(s1, s2): 判断两个线段是否相交

func: segmentIntersectsLine(segment, line): 判断一条线段和一条直线是否相交

好了,以上是我在上一篇博客中定义的类和函数,我把他们的基本功能,参数设置等等简要列在了上面,以便理解本文后面将要给出的代码。至于具体的算法及分析,请翻看我的上一篇博客。

需要注意的是,我在本文中,把上一篇博客的工作全部封装成了一个模块:PointLine.py,方便本文的代码调用。

接下来,就进入本文的主题吧。

1. 圆与点的位置关系

简单来分,二维空间内,圆与点的位置关系,只有两种:

(1)点在圆上(包括在圆周上以及在圆内);
(2)点在圆外

而判断的方法很直接,计算点到圆心的距离,再用这个距离和圆的半径比较即可。

先定义一个圆类:两个属性,圆心及半径。

class Circle(object):
    """Circle has 2 attributes: center and radius"""

    def __init__(self, center, radius):
        self.center = center
        self.radius = radius

然后写出判断点与圆关系的完整代码如下:

from PointLine import *


class Circle(object):
    """Circle has 2 attributes: center and radius"""

    def __init__(self, center, radius):
        self.center = center
        self.radius = radius


def pointInCircle(point, circle):
    """determine whether a point in a circle"""

    return (pointDistance(point, circle.center) - circle.radius) < 1e-9

其中,pointDistance() 函数在模块 PointLine 已经存在。

最后的距离判断还是要满足浮点值比较的原则,上一篇博客中详细说过,不再赘述。

2. 圆与线的位置关系

(1) 圆与直线的位置关系

简单划分,还是两种:相交(包括相切);不相交

判断的依据是根据圆心到直线的距离与圆半径相比较。判别函数如下:

def lineIntersectsCircle(line, circle):
    """determine whether a line intersects a circle"""

    dis = pointToLine(circle.center, line)
    return dis - circle.radius < 1e-9

其中,pointToLine() 在模块PointLine中已经存在。

(2) 圆与线段的位置关系

线段由于其位置上的限制,导致我们在判断线段和圆的关系的时候会麻烦一点。判断思路如下:

  1. 判断线段 s 所在的直线 l 与圆心的距离 dis 和圆的半径 r 之间的关系。若 dis<=r 则进行2、3步的判断;若 dis>r ,直接返回False.(也就是说肯定与圆不相交)
  2. 计算出圆心到直线 l 的垂线与直线 l 的交点(也就是垂足),记为点
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值