• 【Leetcode】判断平面中1个点是否落在三角形内


    参考资料:

    题目: https://blog.csdn.net/dongtinghong/article/details/78657403

    符号重载: https://blog.csdn.net/cdlwhm1217096231/article/details/89326480#commentBox

    const: https://blog.csdn.net/kaida1234/article/details/80403534

    题目:

    已知平面中1个点P和平面内1个三角形(3个顶点坐标A、B、C),判断该点的位置(三角形内,三角形边上,三角形外)。

    三种解题思路:

    1)

    P点落在三角形内或者边上,P与各顶点的连线和三角形各边的夹角之和等于180°。

    P点落在三角形外,P与各顶点的连线和三角形各边的夹角之和不等于180°。

    2)

    P点在三角形内,沿着A-B-C-A方向走,P点都在三角形边的左侧 / 右侧。

    3)

    选取A点作为顶点,以AB、AC边作为基,平面内所有点都可以写成 P = A + m(B-A) + n(C-A)的形式。

    若 m = [0,1], n = [0,1],且m+n = 1,则该点落在三角形内部和边上。

    由上式可知,AP = mAB + nAC,其中AP、AB和AC均为向量。

    向量方程组:

    AP AB = (mAB + nAC)AB

    AP AC = (mAB + nAC)AC

    解方程组得到m、n。

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    typedef int type;
    
    class  point {
    public:
        point(type x_, type y_)
            :x(x_), y(y_) {
                
            }
    
        point() {
            x = 0;
            y = 0;
        };
        
        friend ostream &operator<<(ostream &out, point &p);  
        
        // subtract
        point operator - (const point &v) const {
            return point(x-v.x, y-v.y);
        }
        
        // dot product
        type dot(point v) {
            return x*v.x + y*v.y;
        }
        
    private:
        type x;
        type y;
    };
    
    ostream &operator<<(ostream &out, point &p) {
        out << p.x << ", " << p.y;
        return out;
    }
    
    int wherePoint(vector<point> triP, point tar) {
        point p0 = triP[0];
        point p1 = triP[1];
        point p2 = triP[2];
        cout << "p0 : " << p0 << endl;
        cout << "p1 : " << p1 << endl;
        cout << "p2 : " << p2 << endl;
        
        point l0 = p1 - p0;
        point l1 = p2 - p0;
        point l2 = tar - p0;
        
        type dot00 = l0.dot(l0);
        type dot01 = l0.dot(l1);
        type dot11 = l1.dot(l1);
        type dot02 = l0.dot(l2);
        type dot12 = l1.dot(l2);
        
        double temp = dot01*dot01 - dot11*dot00;
        
        double n = (dot02*dot01 - dot00*dot12) / temp;  // int / int = int
        if(n > 1 || n < 0) {
            cout << "out of range!" << endl;
            return -1;
        }
        
        double m = (dot02*dot11 - dot01*dot12) / temp * (-1.0);
        if(m > 1 || m < 0) {
            cout << "out of range!" << endl;
            return -1;
        }
        
        if (m == 0 || n == 0) {
            cout << "on the edge!" << endl;
            return 0;
        }
        if ( m+n <= 1 ){
            cout << "in the range!" << endl;
            return 1;
        }
    else {
    return 0;
    } }
    int main (int argc, char** argv){ cout << "Input 3 tri points and 1 point" << endl; vector<point> tripPoints; type a, b; for(int i = 0; i < 3; ++i) { cin >> a; cin >> b; point p(a,b); tripPoints.push_back(p); } cin >> a; cin >> b; point target(a,b); int result = wherePoint(tripPoints, target); return 0; }

    C++ 知识点:

    1. const修饰成员函数。const放在函数体之前,形参之后,修饰成员函数。该成员函数不能修改对象的成员变量,也不能调用非const的成员函数。

    2. const修饰函数形参。当函数形参是指针引用变量时,const才有意义。若为普通传值形参,由于该形参是对实参的一个拷贝,在函数体内修改了形参对实参没有影响。

    在重载 ”-“ 的成员函数中,底层const作用于形参上(常量引用),不能改变引用v的源值

        // subtract
        point operator - (const point &v) const {
            return point(x-v.x, y-v.y);
        }

    顶层const修饰的变量,如下所示,

    const int ci = 42;     // 顶层const,不能修改ci
    int i = ci;                  // 正确,当拷贝ci时,忽略ci的顶层const
    int * const pi = &i;   // 顶层const,不能给pi赋值
    *pi = 0;                   // 正确。顶层const,可以通过pi改变对象的内容

    函数形参有顶层const修饰时,传给他常量对象或者非常量对象都是可以的。

    3. 重载输出符号 <<

    cin是istream类的对象,cout是ostream类的对象。如果想实现符号重载,就必须以全局函数(友元函数)的形式重载,或者到标准库中修改相应的函数定义。

    ostream &operator<<(ostream &out, point &p) {
        out << p.x << ", " << p.y;
        return out;
    }

    由于上述重载函数用到了point类的private变量,因此必须在point类中将该重载函数声明为友元函数。

    4. int = int / int ;

    double = int / double;

  • 相关阅读:
    Oracle 12C 物理Standby 主备切换switchover
    Oracle 性能之 Enq: CF
    dyld: Library not loaded: /usr/local/opt/readline/lib/libreadline.7.dylib
    OGG 从Oracle备库同步数据至kafka
    WARNING: inbound connection timed out (ORA-3136)
    11G 新特性之 密码延迟认证
    org-mode 写 cnblogs 博客
    inner join, left join, right join, full outer join的区别
    Emacs 浏览网页
    服务器被攻击后当作矿机,高WIO
  • 原文地址:https://www.cnblogs.com/gdut-gordon/p/11470043.html
Copyright © 2020-2023  润新知