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

Atmospheric Ray Tracing

- added CRayGrid that describes relationship between neigboring rays
- added specialised CRayGrid: CRayResolutionAdapter
parent b28d9721
/*
* ----------------------------------------------------------------
*
* ITA geometrical acoustics
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2019
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef IW_ITA_PROPAGATIONPATHSIM_ART_SIMULATION_RAYGRID
#define IW_ITA_PROPAGATIONPATHSIM_ART_SIMULATION_RAYGRID
#include <ITAPropagationPathSim/Definitions.h>
// Vista includes
#include <VistaBase/VistaVector3D.h>
// ITA includes
#include <ITAPropagationPathSim/AtmosphericRayTracing/Rays.h>
// STD
#include <vector>
#include <memory>
namespace ITAPropagationPathSim
{
namespace AtmosphericRayTracing
{
class ITA_PROPAGATION_PATH_SIM_API CRayGrid
{
protected:
typedef std::shared_ptr<CRay> RayPtr;
typedef std::vector< RayPtr > RayVector;
typedef std::vector<RayVector> RayMatrix;
RayVector vpRays;
RayMatrix vvpRayMatrix;
VistaVector3D v3SourcePos;
std::vector<double> vdThetaDeg;
std::vector<double> vdPhiDeg;
protected:
CRayGrid() {}
CRayGrid(const RayMatrix& rayMatrix, const std::vector<double>& thetaDeg, const std::vector<double>& phiDeg);
public:
//TODO: Make sure that theta and phi are sorted
CRayGrid(const VistaVector3D& sourcePos, const std::vector<double>& thetaDeg, const std::vector<double>& phiDeg);
protected:
void InitRayVectorFromRayMatrix();
int IndexToThetaIndex(const int& idx) const;
int IndexToPhiIndex(const int& idx) const;
int GetIndex(const std::shared_ptr<CRay>& pRay) const;
public:
std::vector<double> ThetaDeg() const { return vdThetaDeg; }
std::vector<double> PhiDeg() const { return vdPhiDeg; }
int NTheta() const { return vdThetaDeg.size(); }
int NPhi() const { return vdPhiDeg.size(); }
std::vector<std::shared_ptr<CRay>> Rays() const { return vpRays; }
bool IsEmpty() const { return NTheta() == 0 || NPhi() == 0; }
bool Contains(std::shared_ptr<CRay> pRay) const { return std::find(vpRays.cbegin(), vpRays.cend(), pRay) == vpRays.cend(); }
CRayGrid GetNeighboringRays(std::shared_ptr<CRay> pRay) const;
void SetToNeighboringRays(std::shared_ptr<CRay> pRay);
};
}
}
#endif //IW_ITA_PROPAGATIONPATHSIM_ART_SIMULATION_RAYGRID
\ No newline at end of file
......@@ -7,6 +7,7 @@ set( SubDirs ODESolver Simulation Export)
set( DirFiles
Rays.h
RayGrid.h
)
set( DirFiles_SourceGroup "${RelativeSourceGroup}" )
......
//#include "RayGrid.h"
#include <ITAPropagationPathSim/AtmosphericRayTracing/RayGrid.h>
// ITA includes
//#include <ITAException.h>
// STD
#include <cmath>
#include <algorithm>
using namespace ITAPropagationPathSim::AtmosphericRayTracing;
// --- CONSTRUCTORS ---
// --------------------
CRayGrid::CRayGrid(const RayMatrix& rayMatrix, const std::vector<double>& thetaDeg, const std::vector<double>& phiDeg): vvpRayMatrix(rayMatrix), vdThetaDeg(thetaDeg), vdPhiDeg(phiDeg)
{
InitRayVectorFromRayMatrix();
if (!vpRays.empty())
v3SourcePos = vpRays.front()->SourcePoint();
}
CRayGrid::CRayGrid(const VistaVector3D& sourcePos, const std::vector<double>& thetaDeg, const std::vector<double>& phiDeg) : v3SourcePos(sourcePos), vdThetaDeg(thetaDeg), vdPhiDeg(phiDeg)
{
for (int idxTheta = 0; idxTheta < thetaDeg.size(); idxTheta++)
{
vvpRayMatrix.push_back(std::vector< std::shared_ptr<CRay>>());
for (int idxPhi = 0; idxPhi < phiDeg.size(); idxPhi++)
{
auto ray = std::make_shared<CRay>(sourcePos, thetaDeg[idxTheta], phiDeg[idxPhi]);
vvpRayMatrix[idxTheta].push_back(ray);
}
}
InitRayVectorFromRayMatrix();
}
// --- PRIVATE HELPER ---
// ----------------------
void ITAPropagationPathSim::AtmosphericRayTracing::CRayGrid::InitRayVectorFromRayMatrix()
{
vpRays.clear();
for each (RayVector rayVector in vvpRayMatrix)
for each (RayPtr pRay in rayVector)
vpRays.push_back(pRay);
}
int CRayGrid::IndexToThetaIndex(const int& idx) const
{
if (idx < 0 || idx >= vpRays.size())
return -1;
return idx / NPhi(); //Integer-division (floor-function)
}
int CRayGrid::IndexToPhiIndex(const int& idx) const
{
if (idx < 0 || idx >= vpRays.size())
return -1;
return idx % NPhi();
}
int CRayGrid::GetIndex(const std::shared_ptr<CRay>& pRay) const
{
auto it = std::find(vpRays.cbegin(), vpRays.cend(), pRay);
if (it == vpRays.cend())
return -1;
return std::distance(vpRays.cbegin(), it);
}
// --- PUBLIC ---
// --------------
CRayGrid CRayGrid::GetNeighboringRays(std::shared_ptr<CRay> pRay) const
{
if (!Contains(pRay))
return CRayGrid();
const int idx = GetIndex(pRay);
const int idxTheta = IndexToThetaIndex(idx);
const int idxPhi = IndexToPhiIndex(idx);
const int idxThetaMin = std::max(0, idxTheta - 1);
const int idxThetaMax = std::min(NTheta(), idxTheta + 1);
const int idxPhiMin = std::max(0, idxPhi - 1);
const int idxPhiMax = std::min(NTheta(), idxPhi + 1);
std::vector<double> newThetaDeg = std::vector<double>(vdThetaDeg.cbegin() + idxThetaMin, vdThetaDeg.cend() + idxThetaMax);
std::vector<double> newPhiDeg = std::vector<double>(vdPhiDeg.cbegin() + idxPhiMin, vdPhiDeg.cend() + idxPhiMax);
RayMatrix newRayMatrix;
for (int idxTheta = idxThetaMin; idxTheta < idxThetaMax; idxTheta++)
{
newRayMatrix.push_back(RayVector());
for (int idxPhi = idxPhiMin; idxPhi < idxPhiMax; idxPhi++)
newRayMatrix[idxTheta].push_back( vvpRayMatrix[idxTheta][idxPhi] );
}
return CRayGrid(newRayMatrix, newThetaDeg, newPhiDeg);
}
void CRayGrid::SetToNeighboringRays(std::shared_ptr<CRay> pRay)
{
*this = GetNeighboringRays(pRay);
}
#include "RayResolutionAdapter.h"
// ITA includes
//#include <ITAException.h>
// STD
//#include <cmath>
using namespace ITAPropagationPathSim::AtmosphericRayTracing;
bool Simulation::CRayResolutionAdapter::ZoomIntoRay(std::shared_ptr<CRay> pRay)
{
if(!Contains(pRay))
return false;
SetToNeighboringRays(pRay);
DoubleRayResolution();
return true;
}
void Simulation::CRayResolutionAdapter::DoubleRayResolution()
{
vdThetaDeg = DoubleAngleResolution(vdThetaDeg);
vdPhiDeg = DoubleAngleResolution(vdPhiDeg);
RayMatrix newRayMatrix;
vpInsertedRays.clear();
RayVector::const_iterator iteratorOldRays = vpRays.cbegin();
for (int idxTheta = 0; idxTheta < vdThetaDeg.size(); idxTheta++)
{
const bool isNewTheta = (idxTheta % 2) == 1;
newRayMatrix.push_back( RayVector() );
for (int idxPhi = 0; idxPhi < vdPhiDeg.size(); idxPhi++)
{
const bool isNewPhi = (idxPhi % 2) == 1;
RayPtr pRay;
if (isNewTheta || isNewPhi)
{
pRay = std::make_shared<CRay>(v3SourcePos, vdThetaDeg[idxTheta], vdPhiDeg[idxPhi]);
vpInsertedRays.push_back(pRay);
}
else
pRay = *iteratorOldRays++;
newRayMatrix[idxTheta].push_back(pRay);
}
vvpRayMatrix = newRayMatrix;
InitRayVectorFromRayMatrix();
}
}
std::vector<double> Simulation::CRayResolutionAdapter::DoubleAngleResolution(const std::vector<double>& angleVector)
{
if (angleVector.size() < 2)
return angleVector;
std::vector<double> returnVector;
returnVector.push_back( angleVector.front() );
for (int idxAngle = 1; idxAngle < angleVector.size(); idxAngle++)
{
const double angle1 = angleVector[idxAngle - 1];
const double angle2 = angleVector[idxAngle];
returnVector.push_back( (angle1+angle2)/2 );
returnVector.push_back( angle2 );
}
}
/*
* ----------------------------------------------------------------
*
* ITA geometrical acoustics
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2019
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef IW_ITA_PROPAGATIONPATHSIM_ART_SIMULATION_RAYRESOLUTIONADAPTER
#define IW_ITA_PROPAGATIONPATHSIM_ART_SIMULATION_RAYRESOLUTIONADAPTER
#include <ITAPropagationPathSim/AtmosphericRayTracing/RayGrid.h>
// ITA includes
//#include <ITAGeo/Atmosphere/StratifiedAtmosphere.h>
namespace ITAPropagationPathSim
{
namespace AtmosphericRayTracing
{
namespace Simulation
{
class CRayResolutionAdapter : public CRayGrid
{
private:
std::vector< std::shared_ptr<CRay> > vpInsertedRays;
public:
CRayResolutionAdapter(const CRayGrid& rayGrid) : CRayGrid(rayGrid) {}
public:
bool ZoomIntoRay(std::shared_ptr<CRay> pRay);
private:
void DoubleRayResolution();
std::vector<double> DoubleAngleResolution(const std::vector<double>& angleVector);
};
}
}
}
#endif //IW_ITA_PROPAGATIONPATHSIM_ART_SIMULATION_RAYRESOLUTIONADAPTER
\ No newline at end of file
......@@ -8,6 +8,8 @@ set( DirFiles
AdaptiveSolver.h
AdaptiveSolver.cpp
Engine.cpp
RayResolutionAdapter.h
RayResolutionAdapter.cpp
)
set( DirFiles_SourceGroup "${RelativeSourceGroup}" )
......
......@@ -6,6 +6,7 @@ set( RelativeSourceGroup "Source Files\\ITAPropagationPathSim\\AtmosphericRayTra
set( SubDirs ODESolver Simulation)
set( DirFiles
RayGrid.cpp
)
set( DirFiles_SourceGroup "${RelativeSourceGroup}" )
......
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