NMPB08 Shared Libraries
SousCalculs/ElementaryPath.cpp
Go to the documentation of this file.
00001 
00008 #include "ElementaryPath.h"
00009 #include <assert.h>
00010 
00011 namespace ElementaryPathNMPB
00012 {
00026         void ConvexHull(vector<ProfilePointNMPB*>& pathItems, int n1, int n2, int level)
00027         {
00028                 int      i;
00029                 double   d1,z1,d2,z2;
00030                 int      initS;
00031                 double   dist, zray, zmax, zdif;
00032                 Position2D *p;
00033 
00034                 // ray equation & height for the convex hull
00035                 d1 = pathItems[n1]->position2D->d ;
00036                 p = pathItems[n1]->position2D_withHeight();
00037                 z1 = p->z ;
00038                 delete p;
00039 
00040                 d2 = pathItems[n2]->position2D->d ;
00041                 p = pathItems[n2]->position2D_withHeight();
00042                 z2 = p->z ;
00043                 delete p;
00044                 
00045                 for (i = n1+1 ; i < n2 ; i++)
00046                 {
00047                   dist = pathItems[i]->position2D->d ;
00048                   zray = z1 + (z2 - z1) * (dist - d1) / (d2 - d1) ;
00049                   p = pathItems[i]->position2D_withHeight();
00050                   pathItems[i]->h_ray = zray - p->z ;
00051                   delete p;
00052                 }
00053 
00054                 // seek the higher point to the ray
00055                 initS = 0  ;
00056                 zmax = 0. ;
00057 
00058                 for (i = n1+1 ; i < n2 ; i++)
00059                 {
00060                         // if point is not reflection or side diffraction
00061                         if (pathItems[i]->ext != NULL && pathItems[i]->ext->type != ETReflection_NMPB && pathItems[i]->ext->type != ETSideDiffraction_NMPB)
00062                         {
00063                                 zdif = -pathItems[i]->h_ray ;
00064 
00065                                 if (initS == 0 || zdif > zmax)
00066                                 {
00067                                         initS = i;
00068                                         zmax = zdif;
00069                                 }
00070                         }
00071                 }
00072 
00073                 // if the higher point is above the ray : it is kept as diffracted 
00074                 //      and the function is called on the left and on the right of this point
00075                 if (zmax > 0)
00076                 {
00077                   pathItems[initS]->isDiff = 1 ;
00078 
00079                   ConvexHull(pathItems ,n1 , initS, level+1);
00080                   ConvexHull(pathItems ,initS , n2, level+1);
00081 
00082                   return ;
00083                 }
00084 
00085                 // if the higher point is under the SR ray (level 0) but not too low : it is kept as diffracted
00086                 
00087                 if (level == 0 && initS != 0)
00088                 {
00089                          zdif = - pathItems[initS]->h_ray ;
00090                          double tmp = 0.34 * (pathItems[initS]->position2D->d - d1) * (d2 - pathItems[initS]->position2D->d) / (d2 - d1) ;
00091                          assert (tmp >= 0) ;
00092                          zdif = zdif / sqrt (tmp) ; 
00093                          if (zdif > -0.5) pathItems[initS]->isDiff = 1 ;
00094                 }
00095         }
00096 
00106         void SetElementaryPath(PropagationPath* path)
00107         {
00108                 // check there are at least 2 elements in the path :
00109                 int pointsNumber = (int) path->pathPoints.size();
00110                 if (pointsNumber < 1)
00111                 {
00112                         printf (".ERROR: path empty \n") ;
00113                         throw new int( ERRNoPoint );
00114                 }
00115                 else if (pointsNumber < 2)
00116                 {
00117                         printf (".ERROR: only one point in the path \n") ;
00118                         throw new int( ERROnePoint );
00119                 }
00120 
00121                 // 3D -> 2.5D (all points will be in a plane ; if vertical reflection or lateral diffraction, image points are calculated and distances are cumulated) :
00122                 ProfilePointNMPB* source = path->pathPoints[0];
00123                 source->position2D->d = 0;
00124                 source->position2D->z = source->position3D->z;
00125                 source->isDiff = 0;
00126                 source->h_ray = 0;
00127 
00128                 // alternative solution : does not depend on Reflection / SideDiffraction flags
00129                 for (int i = 1 ; i < pointsNumber ; i++)
00130                 {
00131                         path->pathPoints[i]->position2D->d 
00132                                 = path->pathPoints[i-1]->position2D->d 
00133                                 + GroundDistance (path->pathPoints[i-1]->position3D, path->pathPoints[i]->position3D) ;
00134                         path->pathPoints[i]->position2D->z = path->pathPoints[i]->position3D->z ;
00135                         path->pathPoints[i]->h_ray = 0 ;
00136                         path->pathPoints[i]->isDiff = 0 ;       
00137                 }                       
00138 
00139                 // simplified solution : detect new starting point on the fly
00140                 // note : not tested
00141                 /*
00142                 ProfilePointNMPB* prec_screen = path->pathPoints[0]; // use source as origin
00143                 double accuDistance = 0; // accumulated ground distance
00144 
00145                 for (int i = 1 ; i < pointsNumber ; i++)
00146                 {
00147                         ProfilePointNMPB* pathPoint = path->pathPoints[i];
00148                         FillPlanePosition(pathPoint, prec_screen, accuDistance);
00149                         pathPoint->isDiff = 0;
00150                         pathPoint->h_ray = 0;
00151 
00152                         // if point is reflection, side diffraction, or is receiver :
00153                         if (path->pathPoints[i]->ext->type == ETReflection_NMPB || 
00154                                 path->pathPoints[i]->ext->type == ETSideDiffraction_NMPB)
00155                         {
00156                                 accuDistance = pathPoint->position2D->d;
00157                                 prec_screen  = pathPoint ;
00158                         }
00159                 }
00160                 */
00161         
00162                 // original solution
00163                 /*
00164                 int i_precReflexion = 0; // source is considered as first reflection
00165                 double accuDistance = 0; // accumulated ground distance
00166                 for (int i = 1 ; i < pointsNumber ; i++)
00167                 {
00168                         // if point is reflection, side diffraction, or is receiver :
00169                         if (path->pathPoints[i]->ext->type == ETReflection_NMPB || 
00170                                 path->pathPoints[i]->ext->type == ETSideDiffraction_NMPB || 
00171                                 i == pointsNumber - 1)
00172                         {
00173                                 // determine 2D position for all the points between the 2 reflections :
00174                                 ProfilePointNMPB* prec_screen = path->pathPoints[i_precReflexion];
00175                                 ProfilePointNMPB* cur_screen = path->pathPoints[i];
00176                                 
00177                                 for (int j = i_precReflexion + 1 ; j < i ; j++)
00178                                 {
00179                                         ProfilePointNMPB* pathPoint = path->pathPoints[j];
00180                                         FillPlanePosition(pathPoint, prec_screen, accuDistance);
00181                                         pathPoint->isDiff = 0;
00182                                         pathPoint->h_ray = 0;
00183                                 }
00184 
00185                                 FillPlanePosition(cur_screen, prec_screen, accuDistance);
00186                                 cur_screen->isDiff = 0;
00187                                 cur_screen->h_ray = 0;
00188 
00189                                 accuDistance = cur_screen->position2D->d;
00190                                 i_precReflexion = i;                    
00191                         }
00192                 }
00193                 */
00194 
00195                 // convex hull for vertical diffractions
00196                 ConvexHull(path->pathPoints, 0, pointsNumber - 1, 0);
00197 
00198                 // SR distance (|S'R'| if reflections) : SR distance with the enlarged trajectory taking account of reflections and lateral diffractions (but not vertical diffractions)
00199                 Position2D *sourcePos = source->position2D_withHeight();
00200                 Position2D *sourceRecep = path->pathPoints[pointsNumber-1]->position2D_withHeight();
00201                 path->distSR = distance2D(sourcePos,sourceRecep);
00202                 delete sourcePos;
00203                 delete sourceRecep;
00204         }
00205 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines