平面中判斷點在三角形內算法(同向法)


1. 概述

平面中判斷點在三角形內外有很多中算法,文獻1中提到了一種同向法,我認為是比較好的解法,兼顧了效率和可理解性。不過這個算法有兩個要注意的地方。

2. 詳論

2.1. 原理與實現

同向法的具體算法摘錄如下:

imglink1

關鍵的實現代碼如下:

//空間三角形
//按照逆時針順序插入值並計算法向量
template <class T>
class Triangle
{
public:
    Vec3<T> v0;
    Vec3<T> v1;
    Vec3<T> v2;

    Triangle()
    {

    }

    Triangle(Vec3<T> v0, Vec3<T> v1, Vec3<T> v2)
    {
        this->v0 = v0;
        this->v1 = v1;
        this->v2 = v2;     
    }

    // v1 = Cross(AB, AC)
    // v2 = Cross(AB, AP)
    // 判斷矢量v1和v2是否同向
    bool SameSide(Vec3<T>& A, Vec3<T>& B, Vec3<T>& C, Vec3<T>& P)
    {
        Vec3<T> AB = B - A ;
        Vec3<T> AC = C - A ;
        Vec3<T> AP = P - A ;

        Vec3<T> v1 = AB ^ AC;
        Vec3<T> v2 = AB ^ AP;

        // v1 and v2 should point to the same direction
        return v1*v2 >= 0 ;
        //return v1 * v2 > 0 ;
    }

    // 判斷平面點P是否在平面三角形內
    bool PointInTriangle2D(Vec3<T>& P)
    {
        Vec3<T> A(v0.x(), v0.y(), 0);
        Vec3<T> B(v1.x(), v1.y(), 0);
        Vec3<T> C(v2.x(), v2.y(), 0);
        return SameSide(A, B, C, P) && SameSide(B, C, A, P) && SameSide(C, A, B, P);
    }
};

2.2. 注意事項

第一個要注意的是,為了方便表達出向量的叉積,使用了三維向量而不是二維向量。但是這個算法是針對的是平面而不是空間,也就是判斷空間中點是否在三角形內是無效的。並且,傳入的三維向量的第三分量最好都為0,否則,無法保證算法的有效性。

第二是點是通過點積來判斷是否同向:

bool SameSide(Vec3<T>& A, Vec3<T>& B, Vec3<T>& C, Vec3<T>& P)
{
    Vec3<T> AB = B - A ;
    Vec3<T> AC = C - A ;
    Vec3<T> AP = P - A ;

    Vec3<T> v1 = AB ^ AC;
    Vec3<T> v2 = AB ^ AP;

    // v1 and v2 should point to the same direction
    return v1*v2 >= 0 ;
    //return v1 * v2 > 0 ;
}

理論上,兩點積等於0,說明兩向量是直角。但是這里的>=0考慮的是零向量的問題,零向量點乘任何點向量還是0。那么什么時候會出現零向量呢?當點正好在三角形的邊界上的時候(兩個相同的向量的叉積為零向量)。也就是說,這里的=0可以判斷點正好在三角形的邊界或者頂點上,而>0才是判斷點是否在三角形的內部。使用的時候可以靈活掌握。

3. 參考

  1. 判斷點是否在三角形內
  2. Point in triangle test
  3. 二維向量的叉積是標量還是向量?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM