/** * Handler for the HMI language * $Id$ * $HeadURL$ * $Author$ */ #include "effect_show_explosion_area.h" namespace EffectShowManagement { EffectShowExplosionArea::EffectShowExplosionArea(const AreaEffectSimulation::ExplosionArea &explosionArea, const std::shared_ptr &handlerPdmData) : m_explosionArea(explosionArea) , m_handlerPdmData(handlerPdmData) , m_numOfEffectShows(0) , m_logger(getLogger("EffectShowExplosionArea")) { } //============================================================================= int EffectShowExplosionArea::getNumOfEffectShows() { if (m_numOfEffectShows == 0) calculateSquare(); return m_numOfEffectShows; } //============================================================================= Database::EsmEffectShow EffectShowExplosionArea::getEffectShow(int idx) { if (m_numOfEffectShows == 0) calculateSquare(); Database::EsmEffectShow esmEffectShow; if (!m_handlerPdmData->isSmoke(m_explosionArea.chargeStruct())) { int indX = idx % m_areasWidth.numOfAreas; int indY = idx / m_areasWidth.numOfAreas; // calculate lower left position double x_off = 0.0; for (int i = 0; i < indX; ++i) x_off += m_areasWidth.side(i); double y_off = 0.0; for (int i = 0; i < indY; ++i) y_off += m_areasDepth.side(i); LtsCoordTrans::UtmCoordinate lowerLeftPos = m_lowerLeftPos; lowerLeftPos.x = lowerLeftPos.x + x_off; lowerLeftPos.y = lowerLeftPos.y + y_off; LtsCoordTrans::UtmCoordinate lowerLeftPosRotated = rotate(lowerLeftPos, m_lowerLeftPos, rotationRad()); // calculate center position LtsCoordTrans::UtmCoordinate centerPos = lowerLeftPos; centerPos.x = centerPos.x + m_areasWidth.side(indX) / 2.; centerPos.y = centerPos.y + m_areasDepth.side(indY) / 2.; LtsCoordTrans::UtmCoordinate centerPosRotated = rotate(centerPos, m_lowerLeftPos, rotationRad()); esmEffectShow.id = 0; esmEffectShow.name = QStringLiteral("EXP"); esmEffectShow.startTime = m_explosionArea.effectStart().is_set() ? m_explosionArea.effectStart().get() : 0; esmEffectShow.duration = m_explosionArea.effectDuration(); esmEffectShow.centerPosition = centerPosRotated.geographic(); esmEffectShow.idAreaEffectSimulation = m_explosionArea.id(); esmEffectShow.esmParticipantId = -1; esmEffectShow.nameAreaEfffectSimulation = QString::fromStdString(m_explosionArea.name()); esmEffectShow.numOfVolley = getNumberOfVolley(); esmEffectShow.shotsPerVolley = getShotsPerArea() / esmEffectShow.numOfVolley; esmEffectShow.typeOfAmmunition = m_explosionArea.chargeStruct().chargeTypeId(); // can there be more then 48 shoots? if (esmEffectShow.shotsPerVolley > 48) esmEffectShow.shotsPerVolley = 48;// (48 / esmEffectShow.numOfVolley); if (esmEffectShow.shotsPerVolley <= 0) esmEffectShow.shotsPerVolley = 1; esmEffectShow.lowerLeftPosition = lowerLeftPosRotated.geographic(); esmEffectShow.areaWidth = m_areasWidth.side(indX); esmEffectShow.areaDepth = m_areasDepth.side(indY); esmEffectShow.areaRotation = m_explosionArea.area().rotation() + 90; DEBUG_LOG(m_logger) << "\nWidth: " << m_explosionArea.area().width() << " Height: " << m_explosionArea.area().height() << "\nRotated LL Pos: " << lowerLeftPosRotated.mgrs() << "\nRotated Center Pos: " << centerPosRotated.mgrs() << "\nOffset x,y: " << x_off << " , " << y_off << "\nSide x,y: " << m_areasWidth.side(indX) << " , " << m_areasDepth.side(indY) << "\nindX: " << indX << " grid " << m_areasWidth.numSideLength1 << ' ' << m_areasWidth.sideLength1 << ' ' << m_areasWidth.numSideLength2 << ' ' << m_areasWidth.sideLength2 << "\nindY: " << indY << " grid " << m_areasDepth.numSideLength1 << ' ' << m_areasDepth.sideLength1 << ' ' << m_areasDepth.numSideLength2 << ' ' << m_areasDepth.sideLength2; } else { LtsCoordTrans::UtmCoordinate lowerLeftPos = m_lowerLeftPos; //unnötig? LtsCoordTrans::UtmCoordinate lowerLeftPosRotated = rotate(lowerLeftPos, m_lowerLeftPos, rotationRad()); // calculate center position LtsCoordTrans::UtmCoordinate centerPos = lowerLeftPosRotated; centerPos.x = centerPos.x + m_explosionArea.area().width() / 2.; centerPos.y = centerPos.y + m_explosionArea.area().height() / 2.; LtsCoordTrans::UtmCoordinate centerPosRotated = rotate(centerPos, m_lowerLeftPos, rotationRad()); esmEffectShow.id = 0; esmEffectShow.name = QStringLiteral("EXP"); esmEffectShow.startTime = m_explosionArea.effectStart().is_set() ? m_explosionArea.effectStart().get() : 0; esmEffectShow.duration = m_explosionArea.effectDuration(); esmEffectShow.centerPosition = centerPosRotated.geographic(); esmEffectShow.idAreaEffectSimulation = m_explosionArea.id(); esmEffectShow.esmParticipantId = -1; esmEffectShow.nameAreaEfffectSimulation = QString::fromStdString(m_explosionArea.name()); esmEffectShow.typeOfAmmunition = m_explosionArea.chargeStruct().chargeTypeId(); esmEffectShow.numOfVolley = 1; esmEffectShow.shotsPerVolley = 1; esmEffectShow.lowerLeftPosition = lowerLeftPosRotated.geographic(); esmEffectShow.areaWidth = m_explosionArea.area().width(); esmEffectShow.areaDepth = m_explosionArea.area().height(); esmEffectShow.areaRotation = m_explosionArea.area().rotation() + 90; DEBUG_LOG(m_logger) << "\nWidth: " << m_explosionArea.area().width() << " Height: " << m_explosionArea.area().height() << "\nRotated LL Pos: " << lowerLeftPosRotated.mgrs() << "\nRotated Center Pos: " << centerPosRotated.mgrs() << "\nSide x,y: " << m_explosionArea.area().width() << " , " << m_explosionArea.area().height(); } return esmEffectShow; } //============================================================================= void EffectShowExplosionArea::updateEffectShow(Database::EsmEffectShow &data) { data.nameAreaEfffectSimulation = QString::fromStdString(m_explosionArea.name()); data.startTime = m_explosionArea.effectStart().is_set() ? m_explosionArea.effectStart().get() : 0; data.duration = m_explosionArea.effectDuration(); if (data.shotsPerVolley > 48) data.shotsPerVolley = 48;//(48 / data.numOfVolley); if (data.shotsPerVolley <= 0) data.shotsPerVolley = 1; data.typeOfAmmunition = m_explosionArea.chargeStruct().chargeTypeId(); } //----------------------------------------------------------------------------- void EffectShowExplosionArea::calculateSquare() { // start position of the area Core::GeoPosition2D geoPos = m_explosionArea.area().cornerBottomLeft(); m_lowerLeftPos = LtsCoordTrans::UtmCoordinate::fromGeographic(geoPos.lon(), geoPos.lat()); // Calculate squares. m_areasWidth = getAreasSideLength(m_explosionArea.area().width()); // Squares in x-direction m_areasDepth = getAreasSideLength(m_explosionArea.area().height()); // Squares in y-direction // Calculate number of squares if (m_handlerPdmData->isSmoke(m_explosionArea.chargeStruct())) m_numOfEffectShows = 1; else m_numOfEffectShows = m_areasWidth.numOfAreas * m_areasDepth.numOfAreas; DEBUG_LOG(m_logger) << "Calc Square poslef " << m_lowerLeftPos.x << " " << m_lowerLeftPos.y << " witdh" << m_areasWidth.sideLength1 << " depth " << m_areasDepth.sideLength1 << " num of Effect Shows " << m_numOfEffectShows; } //static ---------------------------------------------------------------------- LtsCoordTrans::UtmCoordinate EffectShowExplosionArea::rotate(const LtsCoordTrans::UtmCoordinate &p, const LtsCoordTrans::UtmCoordinate &c, double angle) { LtsCoordTrans::UtmCoordinate res = p; // copy zone, northp res.x = ((p.x - c.x) * cos(angle)) - ((p.y - c.y) * sin(angle)) + c.x; res.y = ((p.x - c.x) * sin(angle)) + ((p.y - c.y) * cos(angle)) + c.y; return res; } //static ---------------------------------------------------------------------- EffectShowExplosionArea::areas_t EffectShowExplosionArea::getAreasSideLength(double sideLength) { areas_t res; int sl = qRound(sideLength + 0.5); int n50 = (sl < 25) ? 1 : (sl + 25) / 50; // number of 50m squares int n300 = n50 / 6; // number of 300m squares int len = n50 * 50; // length to be diveded into squares res.numOfAreas = ((n300 * 6) == n50) ? n300 : n300 + 1; // number of areas at all res.sideLength1 = (len / (res.numOfAreas * 50)) * 50; res.numSideLength2 = (len - (res.numOfAreas * res.sideLength1)) / 50; res.sideLength2 = res.sideLength1 + 50; res.numSideLength1 = res.numOfAreas - res.numSideLength2; //qCritical() << "sl = " << sl << " n50= " << n50 << " n300 = " << n300 << " len = " // << len << " numOfAreas = " << res.numOfAreas << " sideLength1 = " << res.sideLength1; return res; } //----------------------------------------------------------------------------- int EffectShowExplosionArea::getNumberOfVolley() const { const int v = getShotsPerArea(); return getNumberOfVolley(v); } //----------------------------------------------------------------------------- int EffectShowExplosionArea::getShotsPerArea() const { if (!m_numOfEffectShows) return 0; int v = m_explosionArea.cannonCount() * m_explosionArea.cannonRounds(); return v / m_numOfEffectShows; //split even across all effect shows } int EffectShowExplosionArea::getShotsPerArea(int areas) const { if (areas == 0) return 0; int v = m_explosionArea.cannonCount() * m_explosionArea.cannonRounds(); return v / areas; } int EffectShowExplosionArea::getNumberOfVolley(int v) { if (v < 3) // <= 0 should not happen but did... return qMax(1, v); if (v <= 25) return 3; if (v <= 50) return 6; if (v <= 100) return 9; if (v <= 150) return 12; if (v <= 200) return 15; return 18; } //----------------------------------------------------------------------------- double EffectShowExplosionArea::rotationRad() const { return -m_explosionArea.area().rotation() * LtsCoordTrans::deg2rad(); } //----------------------------------------------------------------------------- } // Namespace EffectShowManagement