Esempio n. 1
0
////////////////////////////////////////////////////////////////////////////
// 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 );
  }
}