日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二维计算几何基础知识

發布時間:2024/10/8 编程问答 70 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二维计算几何基础知识 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.點積:

向量點積的定義:(x1,y1)*(x2,y2)=x1*x2+y1*y2;滿足交換律

向量點積的代數意義:向量V1的模 * 向量V2的模 * cos<V1,V2>

向量點積的幾何意義:α在β的投影α’與β的長度乘積

2.叉積

向量叉積定義:(x1,y1) x (x2,y2) =x1*y2 - x2*y1;滿足反交換律;

向量叉積幾何意義:有向面積

叉積大小為兩向量圍成的平行四邊形的有向面積

結論:flag=a x b

  • flag>0,a在b的順時針方向(180度范圍內)
  • flag<0,a在b的逆時針方向(180度范圍內)
  • flag=0,a與b同向或反向
  • 3.兩線段判交

    在平面上兩直線,有平行、重合、相交三種關系

    若兩條線段所在的直線平行,則兩條線段平行

    兩條線段p1p2和Q1Q2相交的必要條件:(P2-P1) x (Q1-P1) * (P2-P1) x (Q2-P1) <= 0

    還有這兩種情況:

    在左圖中只滿足了一個“跨立”條件,即Q1和Q2在直線P1P2的兩側,于是我們應該做兩次跨立實驗才能保證它們是相交的;

    而右圖則是邊界條件的特殊情況,不方便用跨立實驗來判斷;

    不過通過觀察兩張圖后,我們發現:當兩線段不相交時,以這兩條線段為對角線的格點矩形沒有交集!

    于是我們可以借助這一點來增加判交條件以保證算法的正確性,我們稱之為快速排斥實驗,如下圖:

    線段的規范相交和非規范相交

    #include <stdio.h> #include <math.h> #include <algorithm> #include <string.h> #include <math.h> using namespace std;const double eps = 1e-8; //三態函數:減少浮點數誤差 int sgn(double x) {if(fabs(x) < eps)return 0;if(x < 0)return -1;else return 1; } struct Point {double x,y;Point(){}Point(double _x,double _y){x = _x;y = _y;}Point operator -(const Point &b)const{return Point(x - b.x,y - b.y);}//叉積double operator ^(const Point &b)const{return x*b.y - y*b.x;}//點積double operator *(const Point &b)const{return x*b.x + y*b.y;} }; struct Line {Point s,e;Line(){}Line(Point _s,Point _e){s = _s;e = _e;}//兩直線相交求交點//第一個值為0表示直線重合,為1表示平行,為0表示相交,為2是相交//只有第一個值為2時,交點才有意義pair<int,Point> operator &(const Line &b)const{Point res = s;if(sgn((s-e)^(b.s-b.e)) == 0){if(sgn((s-b.e)^(b.s-b.e)) == 0)return make_pair(0,res);//重合else return make_pair(1,res);//平行}double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));res.x += (e.x-s.x)*t;res.y += (e.y-s.y)*t;return make_pair(2,res);} };//判斷線段相交 bool inter(Line l1,Line l2) {return//快速排斥實驗max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&//跨立實驗sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0; }//向量的模 typedef Point Vector; double Length(Vector A){return sqrt(A*A); }//求向量A和向量B的夾角,弧度制 double Angle(Vector A,Vector B) {return acos((A*B)/Length(A)/Length(B)); }

    4.判斷直線和線段相交

    //判斷直線L1和線段L2相交 bool seg_inter_line(Line L1,Line L2) {return sgn((L2.s-L1.e)^(L1.s-L1.e))*sgn((L2.e-L1.e)^(L1.s-L1.e))<=0; }

    利用叉積計算點到直線距離

    //利用叉積計算:點到直線距離 double DisLine(Line l,Point p) {Vector v1=p-l.s,v2=l.s-l.e;return fabs(v1*v2)/Length(v2);//平行四邊形的面積除以底邊即平行四邊形的高 }

    ?點到線段的距離

    點到線段距離的計算根據點與直線的位置分為兩大類 (第二類分為兩小類)

    1,如左圖所示,如果點與線段的垂直線與線段所在直線 的交點在線段上,所求的距離就是點到線段的距離

    2,如右圖所示,如果是在射線上,就是點到射線一端的 距離,圖中點到線段的距離就是P到A的距離

    dsy的模板?

    double DisSegment(Point P,Point A,Point B) {if(sgn(A.x-B.x)==0&&sgn(A.y-B.y)==0)//兩點重合return Length(A-P);//兩點之間的距離Vector v1=B-A,v2=P-A,v3=P-B;//p點投影到射線if(sgn(v1*v2)<0) return Length(v2);if(sgn(v1*v3)>0) return Length(v3);//p點投影到線段return fabs(v1*v2)/Length(v2);//點到直線距離 }

    kuangbin的模板?

    //兩點距離 double dist(Point a,Point b) {return sqrt((a-b)*(a-b)); }//點到線段的距離,返回點到線段最近的點 Point NearestPointToLineSeg(Point p,Line L) {Point result;double t=((p-L.s)*(L.e-L.s))/((L.e-L.s)*(L.e-L.s));if(t>=0&&t<=1){result.x=L.s.x+(L.e.x-L.s.x)*t;result.y=L.s.y+(L.e.y-L.s.y)*t;}else{if(dist(p,L.s)<dist(p,L.e))result=L.s;elseresult=L.e;}return result; }

    判斷凸多邊形

    //判斷凸多邊形,允許共線邊 //點的編號0~n-1,可以是順時針和逆時針 bool isConvex(Point poly[],int n){bool s[3];memset(s,false,sizeof s);for(int i=0;i<n;i++){s[sgn( (poly[(i+1)%n]-poly[i])^(poly[(i+2)%n]-poly[i]) )+1]=true;if(s[0]&&s[2]) return false;}return true; }

    ?

    總結

    以上是生活随笔為你收集整理的二维计算几何基础知识的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。