Библиотека myBasicGeometry — различия между версиями

Материал из roboforum.ru Wiki
Перейти к: навигация, поиск
(Новая: == Назначение библиотеки == Выполнение простейших функций [Вычислительная геометрия|вычислительной г...)
 
(Назначение библиотеки)
 
(не показана 1 промежуточная версия этого же участника)
Строка 1: Строка 1:
 +
{{InfoBlock|Теоретические выкладки по этой теме можно найти на странице [[Прикладная геометрия]]|        Теория}}
 +
 
== Назначение библиотеки ==
 
== Назначение библиотеки ==
  
Выполнение простейших функций [Вычислительная геометрия|вычислительной геометрии].
+
Выполнение простейших функций [[Прикладная геометрия|прикладной вычислительной геометрии]].
  
 
== Функции (описание)==
 
== Функции (описание)==

Текущая версия на 16:18, 25 января 2008

Информация
        Теория

Теоретические выкладки по этой теме можно найти на странице Прикладная геометрия



Назначение библиотеки

Выполнение простейших функций прикладной вычислительной геометрии.

Функции (описание)

rfwGetLine

Получить уравнение прямой по двум её различным точками

rfwLinesCrossing

Получить пересечение двух прямых. Возвращает тип пересечения: -1 - пусто, 0 - прямые совпадают, 1 - точка (результат в 3-м параметре).

rfwSectionsCrossing

Получить пересечение двух отрезков. Возвращает тип пересечения: -1 - пусто, 0 - отрезок (результат в 4-м параметре), 1 - точка (результат в 3-м параметре).

rfwLineAndPolygonSectionCrossing

Выяснить пересекается ли отрезок и внутренность секции многоугольника (см. теорию).

Файлы библиотеки

myBasicGeometry.h

<source lang="cpp">

  1. ifndef myBasicGeometryH
  2. define myBasicGeometryH

//--------------------------------------------------------------------------- typedef double rfwFloat; typedef int rfwInt;

typedef struct{

 rfwFloat x,y;

} rfwPoint;

typedef struct{

 rfwFloat a,b,c;

} rfwLine;

typedef struct{

 rfwFloat xa,ya,xb,yb;

} rfwSection;

rfwFloat max(rfwFloat a,rfwFloat b); rfwFloat min(rfwFloat a,rfwFloat b);

rfwLine rfwGetLine(rfwPoint p1, rfwPoint p2); rfwInt rfwLinesCrossing(rfwLine L1,rfwLine L2,rfwPoint &P); rfwInt rfwSectionsCrossing(rfwSection S1,rfwSection S2,rfwPoint &P,rfwSection &S); rfwInt rfwLineAndPolygonSectionCrossing(rfwInt x1, rfwInt y1, rfwInt x2, rfwInt y2, rfwInt xp, rfwInt yp, rfwInt xc, rfwInt yc, rfwInt xn, rfwInt yn);

  1. endif

</source>

myBasicGeometry.cpp

<source lang="cpp">

  1. pragma hdrstop
  2. include "myBasicGeometry.h"

//---------------------------------------------------------------------------

  1. pragma package(smart_init)

rfwFloat max(rfwFloat a,rfwFloat b) {

 if( a>b ){
   return a;
 }else{
   return b;
 };

};

rfwFloat min(rfwFloat a,rfwFloat b) {

 if( a<b ){
   return a;
 }else{
   return b;
 };

};

rfwLine rfwGetLine(rfwPoint p1, rfwPoint p2) {

 rfwLine l;
 l.a=p2.y-p1.y;
 l.b=p1.x-p2.y;
 l.c=-l.a*p1.x-l.b*p1.y;
 return l;

};

rfwInt rfwLinesCrossing(rfwLine L1,rfwLine L2,rfwPoint &P) {

 rfwFloat d=L1.a*L2.b-L1.b*L2.a;
 rfwFloat d1=L2.c*L1.b-L2.b*L1.c;
 rfwFloat d2=L1.c*L2.a-L2.c*L1.a;
 if(d==0){
   if(d1==0 && d2==0){
     return 0; //Same line
   }else{
     return -1; //Empty
   };
 }else{
   P.x=d1/d;
   P.y=d2/d;
   return 1; //Point
 };

};

rfwInt rfwSectionsCrossing(rfwSection S1,rfwSection S2,rfwPoint &P,rfwSection &S) {

 rfwFloat u,v;
 rfwLine L1,L2;
 L1.a=S1.xa-S1.xb; L1.b=S2.xa-S2.xb; L1.c=S1.xa-S2.xa;
 L2.a=S1.ya-S1.yb; L2.b=S2.ya-S2.yb; L2.c=S1.ya-S2.ya;
 rfwFloat d=L1.a*L2.b-L1.b*L2.a;
 rfwFloat d1=L2.b*L1.c-L2.c*L1.b;
 rfwFloat d2=L1.c*L2.a-L2.c*L1.a;
 //printf("d=%d\nd1=%d\nd2=%d\n",d,d1,d2);
 if(d==0){
   if(d1==0 && d2==0){
     //Same line
     rfwFloat length1=(S1.xb-S1.xa)*(S1.xb-S1.xa)+(S1.yb-S1.ya)*(S1.yb-S1.ya);
     rfwFloat u2a=((S2.xa-S1.xa)*(S1.xb-S1.xa)+(S2.ya-S1.ya)*(S1.yb-S1.ya))/length1;
     rfwFloat u2b=((S2.xb-S1.xa)*(S1.xb-S1.xa)+(S2.yb-S1.ya)*(S1.yb-S1.ya))/length1;
     rfwFloat max_u=max(u2a,u2b);
     rfwFloat min_u=min(u2a,u2b);
     if(max_u<0 || min_u>1){
       return -1; //Empty
     }else{
       u2a=max(0,min_u);
       u2b=min(1,max_u);
       S.xa=S1.xa+u2a*(S1.xb-S1.xa);
       S.ya=S1.ya+u2a*(S1.yb-S1.ya);
       S.xb=S1.xa+u2b*(S1.xb-S1.xa);
       S.yb=S1.ya+u2b*(S1.yb-S1.ya);
       return 0; //Section S1+u*(S2-S1), where u2a<=u<=u2b
     };
   }else{
     return -1; //Empty
   };
 }else{
   u=d1/d;
   v=d2/d;
   if(u>=0 && u<=1 && v>=0 && v<=1){
     P.x=S1.xa+u*(S1.xb-S1.xa);
     P.y=S1.ya+u*(S1.yb-S1.ya);
     return 1; //Point
   }else{
     return -1; //Empty
   };
 };

};

rfwInt rfwLineAndPolygonSectionCrossing(rfwInt x1, rfwInt y1, rfwInt x2, rfwInt y2, rfwInt xp, rfwInt yp, rfwInt xc, rfwInt yc, rfwInt xn, rfwInt yn){

 if(x1==x2 && y1==y2){ return 0; };
 rfwSection s0,s1,sr;
 rfwPoint pr;
 s0.xa=x1; s0.ya=y1;
 s0.xb=x2; s0.yb=y2;
 s1.xa=xp; s1.ya=yp;
 s1.xb=xc; s1.yb=yc;
 rfwInt res=rfwSectionsCrossing(s0,s1,pr,sr);
 if(res==-1){ return 0; };
 if(res==0){
   //Intersection is section "sr"
   if( ( (sr.xa-xc)*(xc-xp)+(sr.ya-yc)*(yc-yp)>0)
    && (-(sr.xa-xc)*(yn-yc)+(sr.ya-yc)*(xn-xc)>0) ){ return 1; };
   if( ( (sr.xb-xc)*(xc-xp)+(sr.yb-yc)*(yc-yp)>0)
    && (-(sr.xb-xc)*(yn-yc)+(sr.yb-yc)*(xn-xc)>0) ){ return 1; };
   return 0;
 };
 if(res==1){
   //Intersection is point "pr"
   if(pr.x==xp && pr.y==yp){ return 0; }; //PR=P
   if(pr.x==xc && pr.y==yc){ //PR=C
     if( -(xn-xc)*(yc-yp)+(yn-yc)*(xc-xp)>0 ){ //Angle PCN<=180 deg
       if( (-(x1-xc)*(yc-yp)+(y1-yc)*(xc-xp)>0)
        && (-(x1-xc)*(yn-yc)+(y1-yc)*(xn-xc)>0) ){ return 1; };
       if( (-(x2-xc)*(yc-yp)+(y2-yc)*(xc-xp)>0)
        && (-(x2-xc)*(yn-yc)+(y2-yc)*(xn-xc)>0) ){ return 1; };
       return 0;
     }else{ //Angle PCN>180 deg
       if( (-(x1-xc)*(yc-yp)+(y1-yc)*(xc-xp)>0)
        || (-(x1-xc)*(yn-yc)+(y1-yc)*(xn-xc)>0) ){ return 1; };
       if( (-(x2-xc)*(yc-yp)+(y2-yc)*(xc-xp)>0)
        || (-(x2-xc)*(yn-yc)+(y2-yc)*(xn-xc)>0) ){ return 1; };
       return 0;
     };
   }else{ //PR belongs to interval (P,C)
     if( -(x1-xc)*(yc-yp)+(y1-yc)*(xc-xp)>0 ){ return 1; };
     if( -(x2-xc)*(yc-yp)+(y2-yc)*(xc-xp)>0 ){ return 1; };
     return 0;
   };
 };

};

</source>