Rev 1221 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
#ifndef LIGHTROOM_H
#define LIGHTROOM_H
#include "grid.h"
#include "solarradiation.h"
#include "hemigrid.h"
#include "expression.h"
class LightRoomObject
{
public:
LightRoomObject(): m_radiusFormula(0) {}
~LightRoomObject();
/** Test if the ray starting at "p" hits the object.
the ray has direction azimuth/elevation and starts from the position denoted by p_x, p_y and p_z
@return 1: object is hit, 0: object is missed, -1: p is inside the object.*/
int hittest(const double p_x, const double p_y, const double p_z,
const double azimuth_rad, const double elevation_rad);
/** sets up a tree as the obstacle.
@param height treehight in meter
@param crownheight height of the start of crown (above ground) in meter
@param formula (as string representation) that yields the radius as f(relativeheight).
the variable of the formula is 0 for ground 1 for tree top. */
void setuptree(const double height, const double crownheight, const QString &formula);
/// returns true if there is no way that a ray hits the object starting from p.
bool noHitGuaranteed(const double p_x, const double p_y, const double p_z);
double maxHeight() const { return m_height; }
double maxRadius() const { return m_baseradius; }
private:
Expression *m_radiusFormula; ///< formula for calculation of crown widht as f(relative_height)
double m_baseradius; ///< maximum radius of the crown (at the bottom of the crown) [m]
double m_height; ///< treehight [m]
double m_crownheight; ///< height of the beginning of the living crown [m]
QVector<double> m_treeHeights;
};
/** virtual room to do some light-experiments.
The basic use of this class is to derive the size/pattern of the light-influence FON for a single tree.
It uses SolarRadiation for the calculation of global radiation and HemiGrid to calculate and store the results.
This calculation is done for each node of a 3D space and afterwards accumulated into a 2D pattern. */
class LightRoom
{
public:
LightRoom();
~LightRoom() { if (m_roomObject) delete m_roomObject; }
/// setup the spatial grid.
void setup(const double dimx, const double dimy, const double dimz,
const double cellsize, const double hemigridsize,
const double latitude=48., const double diffus_frac=0.5);
void setLightRoomObject(LightRoomObject *lro) { if (m_roomObject) delete m_roomObject; m_roomObject = lro; }
void setAggregationMode(const int mode ) { m_aggregationMode = mode; }
/// calculate a full hemiview image from given point
double calculateGridAtPoint(const double p_x, const double p_y, const double p_z, bool fillShadowGrid=true);
/// calculate a hemigrid for each node of the grid (store results in m_3dvalues).
/// @return fraction of "blocked" radiation [0..1]. -1: point inside the object
void calculateFullGrid();
/// access to the hemigrid
const HemiGrid &shadowGrid() const { return m_shadowGrid; }
const HemiGrid &solarGrid() const { return m_solarGrid; }
const FloatGrid &result() const { return m_2dvalues; }
double centerValue() const { return m_centervalue; }
private:
//Grid< QVector<float> > m_3dvalues; ///< storage for resulting 3d light values
FloatGrid m_2dvalues; ///< resulting 2d pattern (derived from 3dvalues)
int m_countX; ///< size of the grid in x-direction
int m_countY;
int m_countZ;
double m_cellsize; ///< length of the side of one cell (equal for all 3 directions)
double m_solarrad_factor; ///< multiplier accounting for the difference of total radiation and the used part of the sky (45°)
HemiGrid m_solarGrid; ///< grid used for solar radiation (direct + diffus)
HemiGrid m_shadowGrid; ///< grid used for shadow calculations
double m_centervalue; ///< value (shadow*height) of the tree center (relative) [-]
int m_aggregationMode; ///< aggregation mod
LightRoomObject *m_roomObject;
};
#endif // LIGHTROOM_H