Files
qt5-legatus-legacy/Lts/Services/AreaEffectSimulation/Utils/tne_algorithmen.cpp
T
2026-08-13 18:33:10 +02:00

140 lines
3.4 KiB
C++
Executable File

/**
* @RDE_HEADER@
* TNE_Algorithemn zur Nachbildung von TNE-Funktionalität, hier Berechnung der Einschlagkoordinaten eines Flächenfeuers
* $Id$
* $HeadURL$
* $Author$
*/
#include "tne_algorithmen.h"
#include <iostream>
namespace AreaEffectSimulation
{
namespace TNE_ALGORITHMEN
{
QVector<QPointF> areaExlosionsGAUSS(int wirkfeldKennung, int breite_m, int tiefe_m, short anzahl_einschlaege)
{
if (anzahl_einschlaege<=0)
return {};
// breite, tiefe sollte ein Vielfaches von 5m sein, vergleiche ICD
// const int breite_m = breite_5m * 5;
// const int tiefe_m = tiefe_5m * 5;
QVector<QPointF> impacts;
impacts.reserve(anzahl_einschlaege);
ULONG xor32 = wirkfeldKennung; // ZZ-Generator initialisieren:
for (int i = 0; i < anzahl_einschlaege; ++i)
{
QPointF point;
// p1 bestimmen (Breite/Ostwert)
point.rx() = breite_m / 2 + xorshift32_nv_limited(&xor32, breite_m / 2, 3);
// ^^^
// p2 bestimmen (Tiefe/Nordwert)
point.ry() = tiefe_m / 2 + xorshift32_nv_limited(&xor32, tiefe_m / 2, 3);
// ^^^
// std::cout << " i=" << i
// << ", p1=" << point.x() << ", p2=" << point.y()
// << std::endl;
impacts.append(point);
} // for
return impacts;
}
QVector<QPointF> areaExlosionsGAUSS_aroundCenter(int wirkfeldKennung, int breite_m, int tiefe_m, short anzahl_einschlaege)
{
if (anzahl_einschlaege<=0)
return {};
// breite, tiefe sollte ein Vielfaches von 5m sein, vergleiche ICD
// const int breite_m = breite_5m * 5;
// const int tiefe_m = tiefe_5m * 5;
QVector<QPointF> impacts;
impacts.reserve(anzahl_einschlaege);
ULONG xor32 = wirkfeldKennung; // ZZ-Generator initialisieren:
for (int i = 0; i < anzahl_einschlaege; ++i)
{
QPointF point;
// p1 bestimmen (Breite/Ostwert)
point.rx() = /*breite_m / 2 + */ xorshift32_nv_limited(&xor32, breite_m / 2, 3);
// p2 bestimmen (Tiefe/Nordwert)
point.ry() = /*tiefe_m / 2 + */ xorshift32_nv_limited(&xor32, tiefe_m / 2, 3);
// std::cout << " i=" << i
// << ", p1=" << point.x() << ", p2=" << point.y()
// << std::endl;
impacts.append(point);
} // for
return impacts;
}
USHORT xorshift32(ULONG *_px)
{
ULONG x32 = *_px;
x32 ^= x32 << 13;
x32 ^= x32 >> 17;
x32 ^= x32 << 5;
*_px = x32;
return x32 % 32768; // für x % n mit n = 2^b; b natürliche Zahl, gilt: x % n = x & (n - 1)
}
SHORT xorshift32_nv(ULONG *_generator, SHORT _bereich, INT_AS_CHAR _sigmaGrenze)
{
//suffix _nv steht für 'normal verteilt'
//DBG_ASSERT(false, "ZZ-generator eingangs=%lu\r", *_generator);
LONG sum = 0;
int i;
for (i = 0; i < 12; i++)
sum += (ULONG)xorshift32(_generator);
// INTEGER-Implementierung 32bit, vgl. GUEZSB60__TN-0006_Wirksimulationsmodelle.docx, Abschnitt 3.3.2.2
short m = 32768 - 1;
LONG zentrierteSumme = sum - 6 * m;
LONG nenner = _sigmaGrenze * m;
if (zentrierteSumme >= 0)
return (SHORT)((zentrierteSumme * _bereich + nenner / 2) / nenner);
else
return (SHORT)((zentrierteSumme * _bereich - nenner / 2) / nenner);
}
SHORT xorshift32_nv_limited(ULONG *_generator, SHORT _bereich, INT_AS_CHAR _sigmaGrenze)
{
SHORT zz = xorshift32_nv(_generator, _bereich, _sigmaGrenze);
if (zz > _bereich)
return _bereich;
if (zz < (-1 * _bereich))
return (-1 * _bereich);
return zz;
}
} // namespace TNE_ALGORITHMEN
} // namespace AreaEffectSimulation