【Leetcode】判斷平面中1個點是否落在三角形內

參考資料:ios

題目: https://blog.csdn.net/dongtinghong/article/details/78657403函數

符號重載: https://blog.csdn.net/cdlwhm1217096231/article/details/89326480#commentBoxspa

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

 

題目:指針

已知平面中1個點P和平面內1個三角形(3個頂點座標A、B、C),判斷該點的位置(三角形內,三角形邊上,三角形外)。code

三種解題思路:對象

1)blog

P點落在三角形內或者邊上,P與各頂點的連線和三角形各邊的夾角之和等於180°。ip

P點落在三角形外,P與各頂點的連線和三角形各邊的夾角之和不等於180°。ci

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;

相關文章
相關標籤/搜索