/** * @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 namespace AreaEffectSimulation { namespace TNE_ALGORITHMEN { QVector 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 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 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 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