久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    計算幾何 點到線段的距離 點在簡單多邊形內 點到凸多邊形的距離

     無名小卒917 2018-06-27

    部分內容參考 http://blog.csdn.net/angelazy/article/details/38489293


    1.點到線段的距離 

    矢量算法

    矢量算法過程清晰,如果具有一定的空間幾何基礎,則是解決此類問題時應優先考慮的方法。當需要計算的數據量很大時,這種方式優勢明顯。

    由于矢量具有方向性,故一些方向的判斷直接根據其正負號就可以得知,使得其中的一些問題得以很簡單的解決。

    用此方法考慮,我們只需要找到向量 方向上的投影,具體如下:

                 

    上面的 方向上的單位向量,其意義是給所求向量確定方向。是的兩個向量的內積,且   ,其中θ為向量APAB之間的夾角。是向量長度。

     

    那么即為上圖中線段AC的長度值,不帶有方向性。此數值與上述表征方向的 整體構成有大小、有方向的新向量,即為 方向上的投影向量,C為投影點。

    根據得到的,由向量的方向性可知:如果情況是上圖(a)所示,那么0<r<1;如果是如圖(b)所示的情況,那么r ≥1;如果是如圖(c)所示的情況,那么得到r ≤0;

    特殊情況如點在線段上、點在端點、點在線段延長線上等等的情況全部適用于此公式,只是作為特殊情況出現,無需另作討論。這也是矢量算法思想的優勢所在。

    故根據r值的不同,最短距離

    代碼如下 :

    1. double PointTOline( point_t const&a,point_t const&b,point_t const&p){  
    2.     double ap_ab = (b.x - a.x)*(p.x - a.x)+(b.y - a.y)*(p.y - a.y);//cross( a , p , b );  
    3.     if ( ap_ab <= 0 )  
    4.         return sqrt( (p.x-a.x)*(p.x-a.x) + (p.y-a.y)*(p.y-a.y) );  
    5.   
    6.     double d2 = ( b.x - a.x ) * ( b.x - a.x ) + ( b.y-a.y ) * ( b.y-a.y ) ;  
    7.     if ( ap_ab >= d2 ) return sqrt( (p.x - b.x )*( p.x - b.x ) + ( p.y - b.y )*( p.y - b.y ) ) ;  
    8.   
    9.     double r = ap_ab / d2;  
    10.     double px = a.x + ( b.x - a.x ) *r;  
    11.     double py = a.y + ( b.y - a.y ) *r;  
    12.     return sqrt( (p.x - px)*(p.x - px) + (p.y - py)*(p.y - py) );  
    13. }  

    2. 點在簡單多邊形內,

    (1) 如果多邊形是凸多邊形,可用叉積法,先graham逆時針排序,然后旋轉一周,判斷方向是否一致


    如圖,點在凸包內,方向一定一致的。


    (2)凹包要用射線法判斷;

    給定點A與簡單多邊形P[N],判斷A是否在P上
    從A向右做射線,如果射線與P的邊有奇數個交點,A在P上,否則A在P外

    剔除幾種特殊情況
    ·水平邊不判斷
    ·點在邊上直接給結論
    ·點與邊的交點恰好是端點,則只計數y值大的那個端點
    代碼如下
    1. /* 
    2.  *  點與簡單多邊形相交,使用射線法,剔除三種特殊情況后,判斷交點的奇偶 
    3.  *  從0開始標號 
    4.  ×  注意n <= 2 的時候 
    5.  */  
    6. struct point_t{  
    7.     int x,y;  
    8. };  
    9. bool isOnline( point_t const&a,point_t const&b, point_t const&po ){  
    10.     return po.x >= min( a.x , b.x ) &&  
    11.            po.x <= max( a.x , b.x ) &&  
    12.            po.y >= min( a.y , b.y ) &&  
    13.            po.y <= max( a.y , b.y ) &&  
    14.            ( po.x - a.x ) * ( b.y - a.y ) == ( po.y - a.y ) * ( b.x - a.x );  
    15. }  
    16. bool isInSimple( point_t * p ,int n , point_t const&po ){  
    17.   
    18.     p[n] = p[0];  
    19.     bool flag = 0;  
    20.     int tmp;  
    21.     for ( int i = 0; i < n;++i ){  
    22.         if ( isOnline( p[i] , p[i+1] , po ) ) return true;  
    23.         if ( p[i].y == p[i+1].y ) continue;  
    24.         p[i].y < p[i+1].y ? tmp = i+1 : tmp = i ;  
    25.         if ( po.y == p[tmp].y && po.x < p[tmp].x ) flag ^= 1;  
    26.         p[i].y > p[i+1].y ? tmp = i+1 : tmp = i ;  
    27.         if ( po.y == p[tmp].y && po.x < p[tmp].x ) continue ;  
    28.   
    29.         if ( po.x < max( p[i].x , p[i+1].x ) &&  
    30.              po.y > min( p[i].y , p[i+1].y ) &&  
    31.              po.y < max( p[i].y , p[i+1].y ) ) flag ^= 1;  
    32.     }  
    33.     return flag;  
    34. }  

    3.點與凸多邊形的距離
    先判斷是否在多邊形內,在求出到每條邊的距離
    代碼如下
    1. #include <bits/stdc++.h>  
    2. using namespace std;  
    3.   
    4. struct point_t {  
    5.     double x,y;  
    6. };  
    7. double cross(point_t const &O,point_t const &A,point_t const &B){  
    8.     double xOA = A.x - O.x;  
    9.     double yOA = A.y - O.y;  
    10.     double xOB = B.x - O.x;  
    11.     double yOB = B.y - O.y;  
    12.     return xOA * yOB - xOB * yOA;  
    13. }  
    14. double PointTOline( point_t const&a,point_t const&b,point_t const&p){  
    15.     double ap_ab = (b.x - a.x)*(p.x - a.x)+(b.y - a.y)*(p.y - a.y);//cross( a , p , b );  
    16.     if ( ap_ab <= 0 )  
    17.         return sqrt( (p.x-a.x)*(p.x-a.x) + (p.y-a.y)*(p.y-a.y) );  
    18.   
    19.     double d2 = ( b.x - a.x ) * ( b.x - a.x ) + ( b.y-a.y ) * ( b.y-a.y ) ;  
    20.     if ( ap_ab >= d2 ) return sqrt( (p.x - b.x )*( p.x - b.x ) + ( p.y - b.y )*( p.y - b.y ) ) ;  
    21.   
    22.     double r = ap_ab / d2;  
    23.     double px = a.x + ( b.x - a.x ) *r;  
    24.     double py = a.y + ( b.y - a.y ) *r;  
    25.     return sqrt( (p.x - px)*(p.x - px) + (p.y - py)*(p.y - py) );  
    26. }  
    27.   
    28. bool isOnline( point_t const&a,point_t const&b, point_t const&po ){  
    29.     return po.x >= min( a.x , b.x ) &&  
    30.            po.x <= max( a.x , b.x ) &&  
    31.            po.y >= min( a.y , b.y ) &&  
    32.            po.y <= max( a.y , b.y ) &&  
    33.            ( po.x - a.x ) * ( b.y - a.y ) == ( po.y - a.y ) * ( b.x - a.x );  
    34. }  
    35. bool isInSimple( point_t * p ,int n , point_t const&po ){  
    36.     p[n] = p[0];  
    37.     bool flag = 0;  
    38.     int tmp;  
    39.     for ( int i = 0; i < n;++i ){  
    40.         if ( isOnline( p[i] , p[i+1] , po ) ) return true;  
    41.         if ( p[i].y == p[i+1].y ) continue;  
    42.         p[i].y < p[i+1].y ? tmp = i+1 : tmp = i ;  
    43.         if ( po.y == p[tmp].y && po.x < p[tmp].x ) flag ^= 1;  
    44.         p[i].y > p[i+1].y ? tmp = i+1 : tmp = i ;  
    45.         if ( po.y == p[tmp].y && po.x < p[tmp].x ) continue ;  
    46.   
    47.         if ( po.x < max( p[i].x , p[i+1].x ) &&  
    48.              po.y > min( p[i].y , p[i+1].y ) &&  
    49.              po.y < max( p[i].y , p[i+1].y ) ) flag ^= 1;  
    50.     }  
    51.     return flag;  
    52. }  
    53.   
    54. point_t p[120];  
    55. int main(){  
    56.     int n;  
    57.     while(cin>>n && n){  
    58.         point_t po;      
    59.         cin>>po.x>>po.y;  
    60.         for (int i = 0;i < n;++i)  
    61.             cin>>p[i].x>>p[i].y;  
    62.   
    63.         if ( isInSimple( p , n , po ) ) {  
    64.             cout <<"0.00"<<endl;  
    65.             continue;  
    66.         }  
    67.         double ans = PointTOline( p[0],p[1],po );  
    68.         p[n] = p[0];  
    69.         for (int i = 1;i < n ;++i)  
    70.             ans = min( ans, PointTOline(p[i] , p[i+1] , po) );  
    71.         cout <<ans<<endl;  
    72.     }  
    73.     return 0;  
    74. }  





      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 精品无码国产污污污免费| av午夜福利一片免费看久久| 高清看男人插曲女人视频| 色一情一乱一伦麻豆| 国产亚洲精品AA片在线播放天| 亚洲色最新高清AV网站| 无码AV动漫精品一区二区免费| 无套内射视频囯产| 乱码精品一区二区三区| 最新无码国产在线视频人与| 99热精品毛片全部国产无缓冲| 精品人妻系列无码人妻漫画| 中文字幕av一区二区| 精品一区二区不卡无码AV| 高清中文字幕国产精品| 免费又黄又爽又猛的毛片| 日日碰狠狠添天天爽五月婷| 国产成人AV在线免播放观看新 | 午夜免费福利小电影| 任我爽精品视频在线播放| 亚洲AV无码乱码在线观看牲色| 成人无码区免费视频| 国产精品无码无卡在线播放| 中文字字幕在线乱码视频| 性刺激的欧美三级视频中文字幕 | 国内永久福利在线视频图片| 午夜亚洲乱码伦小说区69堂| 強壮公弄得我次次高潮A片 | 99久久er热在这里只有精品99 | 国产成人精品综合在线观看| 久久亚洲精品情侣| 天堂中文8资源在线8| 精品久久久久久无码专区| 天堂V亚洲国产V第一次| 香蕉伊蕉伊中文在线视频| 乱妇乱女熟妇熟女网站| 性欧美VIDEOFREE高清大喷水| 少妇高清精品毛片在线视频 | 任我爽精品视频在线播放| 国产精品中文字幕二区| 3D动漫精品啪啪一区二区免费|