利用重心法判断一个点是否落在三角形面积内,三角形的三个点在同一个平面上,如果选中其中一个点,其他两个点不过是相对该点的位移而已,比如选择点A作为起点,那么点B相当于在AB方向移动一段距离得到,而点C相当于在AC方向移动一段距离得到。
所以对于平面内任意一点,都可以由如下方程来表示
P = A + u * (C – A) + v * (B - A) // 方程1
如果系数u或v为负值,那么相当于朝相反的方向移动,即BA或CA方向。那么如果想让P位于三角形ABC内部,u和v必须满足什么条件呢?有如下三个条件
u >= 0
v >= 0
u + v <= 1
几个边界情况,当u = 0且v = 0时,就是点A,当u = 0,v = 1时,就是点B,而当u = 1, v = 0时,就是点C
整理方程1得到P – A = u(C - A) + v(B - A)
令v0 = C – A, v1 = B – A, v2 = P – A,则v2 = u * v0 + v * v1,现在是一个方程,两个未知数,无法解出u和v,将等式两边分别点乘v0和v1的到两个等式
(v2) • v0 = (u * v0 + v * v1) • v0
(v2) • v1 = (u * v0 + v * v1) • v1
注意到这里u和v是数,而v0,v1和v2是向量,所以可以将点积展开得到下面的式子。
v2 • v0 = u * (v0 • v0) + v * (v1 • v0) // 式1
v2 • v1 = u * (v0 • v1) + v * (v1• v1) // 式2
解这个方程得到
u = ((v1•v1)(v2•v0)-(v1•v0)(v2•v1)) / ((v0•v0)(v1•v1) - (v0•v1)(v1•v0))
v = ((v0•v0)(v2•v1)-(v0•v1)(v2•v0)) / ((v0•v0)(v1•v1) - (v0•v1)(v1•v0))
整理成 Qt 的函数形式如下:
// Determine whether point P in triangle ABCboolpointInTriangle(QVector2D A, QVector2D B, QVector2D C, QVector2D P){ QVector2D v0 = C - A; QVector2D v1 = B - A; QVector2D v2 = P - A;floatdot00 = QVector2D::dotProduct(v0, v0);floatdot01 = QVector2D::dotProduct(v0, v1);floatdot02 = QVector2D::dotProduct(v0, v2);floatdot11 = QVector2D::dotProduct(v1, v1);floatdot12 = QVector2D::dotProduct(v1, v2);floatinverDeno =1/ (dot00 * dot11 - dot01 * dot01);floatu = (dot11 * dot02 - dot01 * dot12) * inverDeno ;if(u <0|| u >1)// if u out of range, return directly{returnfalse; }floatv = (dot00 * dot12 - dot01 * dot02) * inverDeno ;if(v <0|| v >1)// if v out of range, return directly{returnfalse; }returnu + v <=1; }(以上算法来自于网络,由我整理成 Qt 可用的函数)
点击领取Qt学习资料+视频教程
链接:http://docs.qq.com/doc/DUlVwTW1FZlZuWE9G