Commit eb749fd9 authored by Philipp Schäfer's avatar Philipp Schäfer
Browse files

ART - AdaptiveRayGrid

- now has once double resolution function for theta and phi respectively
    - phi-function now also checks whether phi is circular
    - phi-function also uses modulo 360
- fixed multiple out of bounds errors in DoubleRayResolution()
parent a8515c69
......@@ -44,7 +44,7 @@ namespace ITAPropagationPathSim
void Reset(const CRayGrid& rayGrid);
//! Returns a unique set of the rays which were adding during the last adaptation
const std::set< std::shared_ptr<CRay> >& NewRaysOfLastAdaptation() { return vpNewRaysOfLastAdaptation; }
const std::set< std::shared_ptr<CRay> >& NewRaysOfLastAdaptation() const { return vpNewRaysOfLastAdaptation; }
//! Simple adaptation method: Setting the limits to neighboring rays and shoots additional rays to double the angular resolution of the grid.
void ZoomIntoRay(const std::shared_ptr<CRay>& pRay);
......@@ -69,7 +69,8 @@ namespace ITAPropagationPathSim
//! By comparing the vector from three rays to the receiver, this decides between which two rays the eigenray is located and returns their indices
std::vector<int> FindAdvancedRayGridLimits1D(const std::vector< std::shared_ptr<CRay> >& pRays, const int idxMinDist, const VistaVector3D& receiverPosition, const double& threshold) const;
void DoubleRayResolution();
void DoubleAngularResolution(std::vector<double>& angleVector) const;
void DoubleThetaResolution();
void DoublePhiResolution();
};
}
}
......
......@@ -2,6 +2,8 @@
#include <ITAException.h>
#include <math.h>
using namespace ITAPropagationPathSim::AtmosphericRayTracing;
using namespace ITAPropagationPathSim::AtmosphericRayTracing::EigenraySearch;
......@@ -72,8 +74,8 @@ void CAdaptiveRayGrid::DoubleRayResolution()
if (NRays() <= 1)
return;
DoubleAngularResolution(vdThetaDeg);
DoubleAngularResolution(vdPhiDeg);
DoubleThetaResolution();
DoublePhiResolution();
RayMatrix newRayMatrix( NTheta(), RayVector( NPhi() ) );
vpNewRaysOfLastAdaptation.clear();
......@@ -86,35 +88,67 @@ void CAdaptiveRayGrid::DoubleRayResolution()
const bool isNewPhi = (idxPhi % 2) == 1;
RayPtr pRay;
if (IsPoleDirection(vdThetaDeg[idxTheta]))
pRay = Matrix()[idxTheta].front();
pRay = Matrix()[idxTheta/2].front(); //Int-Division to convert to theta index of old matrix
else if (isNewTheta || isNewPhi)
{
pRay = std::make_shared<CRay>(v3SourcePos, vdThetaDeg[idxTheta], vdPhiDeg[idxPhi]);
vpNewRaysOfLastAdaptation.insert(pRay);
}
else
pRay = *iteratorOldRays++;
pRay = *iteratorOldRays;
newRayMatrix[idxTheta][idxPhi] = pRay;
if (!isNewTheta && !isNewPhi)
iteratorOldRays++;
}
}
SetRayMatrix(newRayMatrix);
}
void CAdaptiveRayGrid::DoubleAngularResolution(std::vector<double>& angleVector) const
void CAdaptiveRayGrid::DoubleThetaResolution()
{
if (angleVector.size() < 2)
if (vdThetaDeg.size() < 2)
return;
std::vector<double> newAngleVector;
newAngleVector.reserve( 2 * angleVector.size() - 1 );
newAngleVector.push_back( angleVector.front() );
for (int idxAngle = 1; idxAngle < angleVector.size(); idxAngle++)
newAngleVector.reserve(2 * vdThetaDeg.size() - 1);
newAngleVector.push_back(vdThetaDeg.front());
for (int idxAngle = 1; idxAngle < vdThetaDeg.size(); idxAngle++)
{
const double& angle1 = angleVector[idxAngle - 1];
const double& angle2 = angleVector[idxAngle];
newAngleVector.push_back( (angle1+angle2)/2 );
newAngleVector.push_back( angle2 );
const double& angle1 = vdThetaDeg[idxAngle - 1];
const double& angle2 = vdThetaDeg[idxAngle];
newAngleVector.push_back((angle1 + angle2) / 2);
newAngleVector.push_back(angle2);
}
angleVector = newAngleVector;
vdThetaDeg = newAngleVector;
}
void CAdaptiveRayGrid::DoublePhiResolution()
{
if (vdPhiDeg.size() < 2)
return;
std::vector<double> newAngleVector;
newAngleVector.reserve(2 * vdPhiDeg.size() - 1 + IsCircular());
newAngleVector.push_back(vdPhiDeg.front());
for (int idxAngle = 1; idxAngle < vdPhiDeg.size(); idxAngle++)
{
const double& angle1 = vdPhiDeg[idxAngle - 1];
const double& angle2 = vdPhiDeg[idxAngle];
double newAngle = (angle1 + angle2) / 2;
if (angle2 < angle1)
newAngle = std::fmod(newAngle + 180, 360);
newAngleVector.push_back(newAngle);
newAngleVector.push_back(angle2);
}
if (IsCircular())
{
double newAngle = (vdPhiDeg.front() + vdPhiDeg.back()) / 2;
if (vdPhiDeg.front() < vdPhiDeg.back())
newAngle = std::fmod(newAngle + 180, 360);
newAngleVector.push_back(newAngle);
}
vdPhiDeg = newAngleVector;
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment