參考資料: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;