NMPB08 Shared Libraries
|
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 }