zoukankan      html  css  js  c++  java
  • 二维平面上判断点在三角形内的最优算法

      园子里有很多关于点是否在三角形内的文章,提供了各种方法。这让人很纠结,到底该用哪种算法?这里提供一套我认为最优的算法。如果你有不同的意见,亦或有更好的算法,欢迎来讨论。

      算法使用的是同向法,其原理是:假设点P位于三角形ABC内,会有这样一个规律:三角形的每一个边,其对角点与P在边的同一侧;或者说三角形的每一个顶点与P在其对角边的同一侧。

    (1)代码

    // 2D vector
    class Vec2
    {
    public:
        Vec2()
        {
            x = 0.0f;
            y = 0.0f;
        }
    
        Vec2(float fx, float fy)
            :x(fx), y(fy)
        {
        }
    
        // Add
        Vec2 operator + (const Vec2& v) const
        {
            return Vec2(x + v.x, y + v.y);
        }
    
        // Subtract
        Vec2 operator - (const Vec2& v) const
        {
            return Vec2(x - v.x, y - v.y) ;
        }
    
    
    public:
        float x, y;
    };
     1 // Dot product
     2 inline float Vec2Dot(const Vec2& v1, const Vec2& v2)
     3 {
     4     return v1.x * v2.x + v1.y * v2.y;
     5 }
     6 
     7 // Cross product
     8 inline float Vec2Cross(const Vec2& v1, const Vec2& v2)
     9 {
    10     return v1.x * v2.y - v1.y * v2.x;
    11 }
    12 
    13 // Determine whether two vectors v1 and v2 point to the same direction
    14 // 判断C和P在直线AB的同一侧
    15 inline bool IsSameSide(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& P)
    16 {
    17     Vec2 AB = B - A;
    18     Vec2 AC = C - A;
    19     Vec2 AP = P - A;
    20 
    21     float f1 = Vec2Cross(AB, AC);
    22     float f2 = Vec2Cross(AB, AP);
    23 
    24     // f1 and f2 should to the same direction
    25     return f1*f2 >= 0.0f;
    26 }
    27 
    28 // Same side method
    29 // Determine whether point P in triangle ABC
    30 inline bool IsPointInTriangle(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& P)
    31 {
    32     return IsSameSide(A, B, C, P) &&
    33         IsSameSide(B, C, A, P) &&
    34         IsSameSide(C, A, B, P);
    35 }
    36 
    37 // Determine whether point P in angle ABC
    38 // 点P是否在角ABC内
    39 inline bool IsPointInAngle(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& P)
    40 {
    41     return IsSameSide(A, B, C, P) && IsSameSide(B, C, A, P);
    42 }

    算法中没有使用三角函数的调用,因为这一原因,我认为它是最优的算法。

    (2)测试效果

    我生成一幅1024*1024大小的图像,并设置三个顶点,对图像中的所有像素调用IsPointInAngle函数,以测试其效率:

    图中显示出图像生成时间为868.758毫秒,这是DEBUG版本的。

  • 相关阅读:
    We Never Told Him He Couldn't Do It
    我是天蝎
    学习生活,有感动的时候
    .NET中AOP方便之神SheepAspect
    Effective Java (类和接口)
    Step By Step(Java 系列的目录)
    Linux Shel高级技巧(目录)
    Linux Shell经典实例解析Oracle启动脚本(下)
    Java和C++在细节上的差异(目录)
    Linux Shell经典实例解析Oracle启动脚本(上)
  • 原文地址:https://www.cnblogs.com/WhyEngine/p/4064686.html
Copyright © 2011-2022 走看看