cv_gordon

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::

参考资料:

题目: 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;

posted on 2019-09-05 21:50  cv_gordon  阅读(1246)  评论(0编辑  收藏  举报