使用 In-Trangle Test 检测极点

Extreme Points

策略 Strategy

  • 问题的转化
    • 如果一个多边形是凸包,那么当且仅当他的所有顶点( v e r t e x vertex vertex)都是极点;
    • 问题就转化为甄别极点,那么如何甄别极点呢?
      • In-Trangle Test,如果成立,则不是极点!

在这里插入图片描述

In-Triangle Test

  • 无罪推论
    • 首先假设所有的点都是极点
    • 然后暴力枚举出所有可能的三角形:
      • 逐一判断除这三个点以外的所有极点,如果通过了 In-Triangle Test,则标注为非极点

在这里插入图片描述

To-Left Test

  • 实现 In-Triangle Test

    In-Triangle Test 转化为三次 To-Left Test

    • 对于一个点,如果位于三角形内,那么对于三条边的的 To-Left Test 都会统一的返回 True 或者 False

在这里插入图片描述

  • 7 7 7 8 8 8 的问题

    使用三刀最多切出 7 7 7 块蛋糕,但是对于三条直线,每一条直线的 To-Left Test 的结果都存在 TrueFalse 两种情况,那么就会有 2 3 = 8 2^3 = 8 23=8 种情况,少的去哪里了?

    • 实际上对于三条边来说,当三者的 To-Left Test 的结果都是 False 时,他们划分出的区域没有交集,如下图紫色标记区域:

在这里插入图片描述

使用行列式计算有向面积

  • 实现 To-Left Test

    • 在已知三角形边长时可以利用海伦公式计算三角形面积:
      S = ( p ( p − a ) ( p − b ) ( p − c ) ) S = \sqrt{(p(p-a)(p-b)(p-c))} S=(p(pa)(pb)(pc))

    • 而已知三个点的二维坐标时,可以利用行列式计算三角形的有向面积,而根据有向面积的符号可以判断出是在左还是在右;

    • 实际上这种方法的好处是,避免了三角函数和除法,而这两种计算会引入浮点数,降低计算的精度

在这里插入图片描述

  • 另外一种做法

    • 实际上使用向量的叉乘也能实现 To-Left Test,当
      a ⃗ × b ⃗ > 0 ,   ( a ⃗ = p q ⃗ , b ⃗ = p s ⃗ ) \vec{a} \times \vec{b} > 0 , \ (\vec{a} = \vec{pq}, \vec{b} = \vec{ps}) a ×b >0, (a =pq ,b =ps )
      时,结果为 True

    • 三维向量叉乘的公式:
      在这里插入图片描述

    • 对于二维的向量,则更加直观:
      a ⃗ × b ⃗ = ∣ a ⃗ ∣ ∣ b ⃗ ∣ s i n θ = x 1 y 2 − y 1 x 2 \vec{a} \times \vec{b} = |\vec{a}||\vec{b}|sin\theta =x_1y_2 - y_1x_2 a ×b =a b sinθ=x1y2y1x2

      • 此时没有第三维 z,计算结果的正负即可表明 a ⃗ \vec{a} a b ⃗ \vec{b} b 是否满足夹角 θ \theta θ 小于 π \pi π,即 s 是否在 pq 左边;

      • 而且实质上,两种方法是等效的,因为二维向量的叉乘等于所构成的平行四边形的有向面积,即三角形的有向面积的两倍:
        在这里插入图片描述
        带入化简,得到的形式与行列式的做法是一致的:
        在这里插入图片描述

  • 总结

    To-Left-Test 可以有两种实现方法,当已知向量时可以直接使用叉乘,而如果只给出了点的坐标,则可使用行列式。

Reference

计算几何 - 邓俊辉

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值