//////////////////////////////////////////////////////////////////////////// // SetUpBrightnessArray() //////////////////////////////////////////////////////////////////////////// void clGLIMap::SetUpBrightnessArray() { clBehaviorBase * p_oTemp; //for searching for a behavior clLightBase * p_oGli; //gli light object short int i, j; //loop counters bool bBrightnessFilled = false; //Declare the brightness and photo arrays mp_fBrightness = new float * [m_iNumAltAng]; mp_fPhoto = new float * [m_iNumAltAng]; for ( i = 0; i < m_iNumAltAng; i++ ) { mp_fBrightness[i] = new float[m_iNumAziAng]; mp_fPhoto[i] = new float[m_iNumAziAng]; for ( j = 0; j < m_iNumAziAng; j++ ) mp_fBrightness[i] [j] = 0; } m_fSinMinSunAng = sin( m_fMinSunAngle ); m_iMinAngRow = (int)floor( m_fSinMinSunAng * m_iNumAltAng ); //Now - we need to fill the sky brightness array. Check to see if the //"glilightshell" object has been created p_oTemp = mp_oSimManager->GetBehaviorObject( "glilightshell" ); if ( NULL != p_oTemp ) { p_oGli = dynamic_cast < clLightBase * > ( p_oTemp ); if ( p_oGli->m_iNumAltAng == m_iNumAltAng && p_oGli->m_iNumAziAng == m_iNumAziAng && p_oGli->m_iMinAngRow == m_iMinAngRow ) { //Good! We can assume that their photo brightness array is done, and //copy (if it wasn't done the sky resolution data wouldn't match) for ( i = 0; i < m_iNumAltAng; i++ ) for ( j = 0; j < m_iNumAziAng; j++ ) mp_fBrightness[i] [j] = p_oGli->mp_fBrightness[i] [j]; bBrightnessFilled = true; } } if ( false == bBrightnessFilled ) { //We couldn't get what we needed from clGLILight - try clQuadratGLI p_oTemp = mp_oSimManager->GetBehaviorObject( "quadratglilightshell" ); if ( NULL != p_oTemp ) { p_oGli = dynamic_cast < clLightBase * > ( p_oTemp ); if ( p_oGli->m_iNumAltAng == m_iNumAltAng && p_oGli->m_iNumAziAng == m_iNumAziAng && p_oGli->m_iMinAngRow == m_iMinAngRow ) { //Good! We can assume that their photo brightness array is done, and //copy (if it wasn't done the sky resolution data wouldn't match) for ( i = 0; i < m_iNumAltAng; i++ ) for ( j = 0; j < m_iNumAziAng; j++ ) mp_fBrightness[i] [j] = p_oGli->mp_fBrightness[i] [j]; bBrightnessFilled = true; } } } if ( false == bBrightnessFilled ) { //We couldn't steal the array - so create our own sky brightness array PopulateGLIBrightnessArray(); } }
//////////////////////////////////////////////////////////////////////////// // DoShellSetup() //////////////////////////////////////////////////////////////////////////// void clQuadratGLILight::DoShellSetup(xercesc::DOMDocument * p_oDoc) { try { DOMElement *p_oElement = GetParentParametersElement(p_oDoc); clBehaviorBase * p_oTemp; //for searching for a behavior clLightBase * p_oGli; //quadrat gli light object float fAngChunk; short int iHalfAzi, //for partitioning the sky hemisphere iNumXCells, iNumYCells, //number X and Y grid cells i, j; //loop counters //********************************************** //Read values from the parameter file //********************************************** m_iNumAltAng = 0; m_iNumAziAng = 0; m_fMinSunAngle = 0; //Number of alitude angles FillSingleValue( p_oElement, "li_numAltGrids", & m_iNumAltAng, true ); //Number of azimuth angles FillSingleValue( p_oElement, "li_numAziGrids", & m_iNumAziAng, true ); //Minimum sun angle FillSingleValue( p_oElement, "li_minSunAngle", & m_fMinSunAngle, true ); //Azimuth of north - not required for backwards compatibility FillSingleValue( p_oElement, "li_AziOfNorth", & m_fAzimuthOfNorth, false ); //Height of quadrat light FillSingleValue( p_oElement, "li_quadratLightHeight", & m_fLightHeight, true ); //Whether to calculate all values FillSingleValue( p_oElement, "li_quadratAllGLIs", & m_bCalcAll, true ); //Validate the data if ( 0 >= m_iNumAltAng ) { modelErr stcErr; stcErr.iErrorCode = BAD_DATA; stcErr.sFunction = "clQuadratGLILight::DoShellSetup" ; stcErr.sMoreInfo = "The number of sky altitude divisions must be greater than 0."; throw( stcErr ); } if ( 0 >= m_iNumAziAng ) { modelErr stcErr; stcErr.iErrorCode = BAD_DATA; stcErr.sFunction = "clQuadratGLILight::DoShellSetup" ; stcErr.sMoreInfo = "The number of sky azimuth divisions must be greater than 0."; throw( stcErr ); } if (0 > m_fAzimuthOfNorth || (2.0 * M_PI) < m_fAzimuthOfNorth) { modelErr stcErr; stcErr.iErrorCode = BAD_DATA; stcErr.sFunction = "clQuadratGLILight::DoShellSetup"; stcErr.sMoreInfo = "Azimuth of north must be between 0 and 2PI."; throw( stcErr ); } if ( 0 > m_fLightHeight ) { modelErr stcErr; stcErr.iErrorCode = BAD_DATA; stcErr.sFunction = "clQuadratGLILight::DoShellSetup"; stcErr.sMoreInfo = "The height of the GLI point for the GLI map cannot be less than 0."; throw( stcErr ); } //********************************************** //Populate the sky brightness and photo arrays //********************************************** //Declare 'em mp_fBrightness = new float * [m_iNumAltAng]; mp_fPhoto = new float * [m_iNumAltAng]; for ( i = 0; i < m_iNumAltAng; i++ ) { mp_fBrightness[i] = new float[m_iNumAziAng]; mp_fPhoto[i] = new float[m_iNumAziAng]; for ( j = 0; j < m_iNumAziAng; j++ ) mp_fBrightness[i] [j] = 0; } m_fSinMinSunAng = sin( m_fMinSunAngle ); m_iMinAngRow = (int)floor( m_fSinMinSunAng * m_iNumAltAng ); //Now - we need to fill the sky brightness array. Check to see if the //"glilightshell" object has been created p_oTemp = mp_oSimManager->GetBehaviorObject( "glilightshell" ); if ( NULL != p_oTemp ) { p_oGli = dynamic_cast < clLightBase * > ( p_oTemp ); if ( p_oGli->m_iNumAltAng == m_iNumAltAng && p_oGli->m_iNumAziAng == m_iNumAziAng && p_oGli->m_iMinAngRow == m_iMinAngRow ) { //Good! We can assume that their photo brightness array is done, and //copy (if it wasn't done the sky resolution data wouldn't match) for ( i = 0; i < m_iNumAltAng; i++ ) for ( j = 0; j < m_iNumAziAng; j++ ) mp_fBrightness[i] [j] = p_oGli->mp_fBrightness[i] [j]; } else { //Create our own sky brightness array PopulateGLIBrightnessArray(); } } else { //p_oTemp is NULL //Create our own sky brightness array PopulateGLIBrightnessArray(); } m_fAziChunkConverter = m_iNumAziAng / 360.0; //force float conversion m_fRcpTanMinAng = 1 / ( tan( m_fMinSunAngle ) ); //Calculate search radius to look for shading neighbors clTreePopulation *p_oPop = (clTreePopulation*) mp_oSimManager->GetPopulationObject("treepopulation"); m_fMaxSearchRad = ( mp_oLightOrg->GetMaxTreeHeight() - m_fLightHeight ) * m_fRcpTanMinAng + p_oPop->GetAllometryObject()->GetMaxCrownRadius(); mp_fAziSlope = new float[m_iNumAziAng]; iHalfAzi = m_iNumAziAng / 2; //Get the size of each azimuth chunk in radians fAngChunk = ( 2.0 * M_PI ) / m_iNumAziAng; for ( i = 0; i < iHalfAzi; i++ ) { //slope = tan of azimuth angle mp_fAziSlope[i] = 1 / (tan( fAngChunk * ( i + 0.5 ) )); mp_fAziSlope[i + iHalfAzi] = mp_fAziSlope[i]; } //********************************************** //Set up the quadrat grid //********************************************** //Is there already a grid from the parameter file? mp_oQuadrats = mp_oSimManager->GetGridObject( "Quadrat GLI" ); if ( !mp_oQuadrats ) { //Create the grid with one float data member mp_oQuadrats = mp_oSimManager->CreateGrid( "Quadrat GLI", 0, 1, 0, 0, QUADRAT_CELL_SIZE, QUADRAT_CELL_SIZE ); //Register the data member - called "GLI" m_iGridGliCode = mp_oQuadrats->RegisterFloat( "GLI" ); } else { //Get the data member code m_iGridGliCode = mp_oQuadrats->GetFloatDataCode( "GLI" ); if ( -1 == m_iGridGliCode ) { modelErr stcErr; stcErr.iErrorCode = BAD_DATA; stcErr.sFunction = "clQuadratGLILight::DoShellSetup" ; stcErr.sMoreInfo = "Quadrat GLI grid was incorrectly set up in the parameter file. Missing float \"GLI\"."; throw( stcErr ); } } //Set all the values to -1 iNumXCells = mp_oQuadrats->GetNumberXCells(); iNumYCells = mp_oQuadrats->GetNumberYCells(); fAngChunk = -1; //dangerously reuse for ( i = 0; i < iNumXCells; i++ ) for ( j = 0; j < iNumYCells; j++ ) mp_oQuadrats->SetValueOfCell( i, j, m_iGridGliCode, fAngChunk ); } catch ( modelErr & err ) { throw( err ); } catch ( modelMsg & msg ) { throw( msg ); } //non-fatal error catch ( ... ) { modelErr stcErr; stcErr.iErrorCode = UNKNOWN; stcErr.sFunction = "clQuadratGLILight::DoShellSetup" ; throw( stcErr ); } }
/////////////////////////////////////////////////////////////////////////////// // DoLightSetup ///////////////////////////////////////////////////////////////////////////// void clLightDepSeedSurvival::DoLightSetup() { if (m_bUseStormLight) return; try { float fAngChunk; int i, j, iHalfAzi; //for partitioning the sky hemisphere //Populate the sky brightness and photo arrays //Declare 'em mp_fBrightness = new float * [m_iNumAltAng]; mp_fPhoto = new float * [m_iNumAltAng]; for ( i = 0; i < m_iNumAltAng; i++ ) { mp_fBrightness[i] = new float[m_iNumAziAng]; mp_fPhoto[i] = new float[m_iNumAziAng]; for ( j = 0; j < m_iNumAziAng; j++ ) mp_fBrightness[i] [j] = 0; } m_fSinMinSunAng = sin( m_fMinSunAngle ); m_iMinAngRow = (int)floor( m_fSinMinSunAng * m_iNumAltAng ); PopulateGLIBrightnessArray(); m_fAziChunkConverter = m_iNumAziAng / 360.0; //force float conversion m_fRcpTanMinAng = 1 / ( tan( m_fMinSunAngle ) ); mp_fAziSlope = new float[m_iNumAziAng]; iHalfAzi = m_iNumAziAng / 2; //Get the size of each azimuth chunk in radians fAngChunk = ( 2.0 * M_PI ) / m_iNumAziAng; for ( i = 0; i < iHalfAzi; i++ ) { //slope = tan of azimuth angle mp_fAziSlope[i] = 1 / ( tan( fAngChunk * ( i + 0.5 ) ) ); mp_fAziSlope[i + iHalfAzi] = mp_fAziSlope[i]; } clTreePopulation * p_oPop = ( clTreePopulation * ) mp_oSimManager->GetPopulationObject( "treepopulation" ); m_fMaxSearchDistance = ( mp_oLightOrg->GetMaxTreeHeight() - m_fLightHeight ) * m_fRcpTanMinAng + p_oPop->GetAllometryObject()->GetMaxCrownRadius(); } catch ( modelErr & err ) { throw( err ); } catch ( modelMsg & msg ) { throw( msg ); } //non-fatal error catch ( ... ) { modelErr stcErr; stcErr.iErrorCode = UNKNOWN; strcpy( stcErr.cFunction, "clLightDepSeedSurvival::DoLightSetup" ); throw( stcErr ); } }