惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
CERT Recently Published Vulnerability Notes
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
Security Latest
Security Latest
P
Privacy International News Feed
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
AI
AI
Cisco Talos Blog
Cisco Talos Blog
K
Kaspersky official blog
S
Secure Thoughts
PCI Perspectives
PCI Perspectives
Simon Willison's Weblog
Simon Willison's Weblog
D
DataBreaches.Net
GbyAI
GbyAI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
大猫的无限游戏
大猫的无限游戏
T
Tailwind CSS Blog
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
罗磊的独立博客
V
Visual Studio Blog
aimingoo的专栏
aimingoo的专栏
H
Hackread – Cybersecurity News, Data Breaches, AI and More
IT之家
IT之家
V
V2EX
Last Week in AI
Last Week in AI
有赞技术团队
有赞技术团队
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Tenable Blog
T
Threat Research - Cisco Blogs
T
Troy Hunt's Blog
V2EX - 技术
V2EX - 技术
S
Security @ Cisco Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic
Project Zero
Project Zero
The GitHub Blog
The GitHub Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
Lohrmann on Cybersecurity
F
Full Disclosure
H
Help Net Security
博客园 - Franky
Stack Overflow Blog
Stack Overflow Blog
N
Netflix TechBlog - Medium
Engineering at Meta
Engineering at Meta
A
Arctic Wolf
O
OpenAI News
S
Securelist

博客园 - floodpeak

CPU占用率算法 如何摆脱写文档时截屏的困扰 第六回:寻找交点,离胜利就剩一步 之 纽带 备忘录专题首页 转载系列首页 吐血三八二十四 澄清P问题、NP问题、NPC问题的概念 经典文章专题首页 第五回:设计数据结构,存好了数据好干活 上班途中如打仗 4月语言排行榜出炉,祝贺Visual Basic同比上升两名 计算你的死亡时间 第三回:实现步骤显示,一步一步看得见 第二回:漫谈新思路,是我们自己干的时候了 第一回:回望经典,看看别人是怎么干的 参考文献的各种字母的含义 三角剖分专题首页 挑战系列首页 自制二进制时钟之三:跳动起来
第四回:掌握数学工具,没个好帮手怎么行
floodpeak · 2008-04-16 · via 博客园 - floodpeak


    上篇文章介绍了步骤显示功能的具体实现方式,并且给出了我对面向对象设计的一些建议。本篇将会介绍在本三角剖分算法中涉及到的数学知识,并向您展示在引入新的数学工具后实现的便捷。
    新的算法由寻找辅助线、寻找相交点、寻找三角形三个大块组成,这几大块的大致思路已经在《第二回:漫谈新思路,是我们自己干的时候了》中有所交代。其中,寻找相交点需要进行大量的数学运算,而关键的数学运算是计算射线与线段的交点。

一、老工具
    计算射线与线段的交点可以有很多方法,比如使用解析几何。我大概的描述一下使用解析几何的做法:先找到射线与线段所在的两条直线,得到两条直线的函数,联立为二元一次方程组,解出结果得到两条直线的交点,再判断交点是否在射线上以及交点是否在线段上。
    这种做法原不原始尚不讨论,单就其运算的繁复就已经大打折扣,当然使用这种做法有一个好处:一个耐心的高中生就可搞定,省却了看这篇文章的时间

二、新工具
    隆重推出新的数学工具:向量。我好似看到一堆鸡蛋、西红柿朝我飞来,向量还算新?高中就学过!没错,但是在这里我会引入一些新的用法,从而使这种数学工具焕发新的青春。
    在这里我假设大家已经了解向量的概念,基本的运算法则,在以后的系列中我会详细讲解向量。
    由于是解决平面三角剖分问题,所以使用的向量是二维的,因而这里不会涉及到向量叉乘的问题,但是点乘会经常涉及,垂直向量点乘为零的性质也会经常用到。
    在本篇文章中粗体小写字母代表的是向量,斜体字母代表的是标量,大写字母代表的是点。下面是二维向量类和二维点类的代码:

Vector2

Point2

    在上面的代码中,重载了一系列的运算符,各自功用不难理解,不过是为了方便编程罢了。Point2的Equals方法不是简单的比较两个点的坐标,而是将待比较的两个点连成一个向量,根据向量的长短来进行比较,当向量足够短时就认定两个点相同。Vector2的perp方法返回一个与该向量长度相同,逆时针旋转至垂直的新向量,说着挺玄,看看代码其实就是简单的将横纵坐标交换,然后将原来的y反向,别看它的定义如此简单,后面可有大用途,在我看来该方法的引入使向量大大进化,运算方法更加灵活,向引入该方法的数学家(可惜不知道是谁)致敬!在本篇文章中a的perp以符号~a表示。

三、用向量描述直线

    大家知道,向量是没有位置的,所以要表现一条直线需要一个点和一个向量,而点和向量所决定的直线为A + ct ,其中t的取值为(-∞,+∞),当取其中某个值时确定一个点,特别的,当t为零时,为向量的起始点A,当t为1时,为向量的终止点A + c,当t小于零时为向量反方向上的某个点,详情如下图


 
    你是否有什么惊奇的发现,看到这个t的取值图有没有眉头微释,没错,得到了t你就找到了点,而t落在的区间就决定了它与射线、线段的关系:t>0时点落在射线上,t∈[0,1]时点落在线段上,哈哈,就是这么简单,当你找到了点,它的位置就尽在掌握,岂一个爽字了得。

四、射线与线段的交点
    上面给出了向量描述直线的方法,求射线与线段的交点实质上就是求它们所在直线的交点,显然的,当A + ct = M + eu时正是交点,如下图:
 


    整理一下上面的等式,得到ct = (M–A) + eu(一),这里的M–A就是一个从M开始到A结束的向量,当然由于上面的代码中已经给出了二维点的减号重载,程序里直接将两个点相减就可以了。
    下面的任务就是求出tu,继而得到交点了,这里需要一些技巧,还记得上文中提到的perp吗?
    在上述等式的两边同时乘以e的perp,也即~e,由于(~e)•e = 0,所以上面的等式就恒等变形为ct•(~e) = (M–A)•(~e),继而t = (M–A)• (~e) / c•(~e),这些都是已知量了,t也就求出来了,将t代入(一)式,u也即求出,当然也可如法炮制在(一)式两边同时乘以个~ctu都求出后,发现t>1,故而两直线的交点落在了蓝色射线上,但是没有落在AB线段上,而0<u<1,故而该交点落在了线段MN上,怎么样,简单!
    另外,当考虑某条射线和一系列线段相交时将求出的各个t记录下来,经过将t排序可以按照射线的方向将各个交点排序,这在《第七回:寻找三角形,夺取红旗》中会用到。

射线与线段的交点通过引入向量这一数学工具用一种较为简便的方式解决了,在程序中只需三行就可以得到tu,继而找到交点的位置,配之操作符的种种重载,代码犹如数学公式,一目了然,优雅之至!在《第六回:寻找交点,离胜利就剩一步 之 开找》中你将见到这段代码。向量知识博大而精深,这篇小文只是九牛之一毛,但对于该算法已经够用了。下一篇将详细讲述数据结构的设计,用一种较为合适的方式来存储运算过程中得到的各种数据以及最后的运算结果。