利用重心法判斷一個點是否落在三角形面積內,三角形的三個點在同一個平面上,如果選中其中一個點,其他兩個點不過是相對該點的位移而已,比如選擇點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