140 lines
3.4 KiB
C++
Executable File
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
|
|
|