feat(tactical-app): full sovereign military suite in Flutter with first-run onboarding, artillery ballistics, HLZ assessment, minefield breach, isochrone, symbols, and overlays
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import 'dart:math' as math;
|
||||
import 'package:intaleq_maps/intaleq_maps.dart';
|
||||
import '../models/military_operations_models.dart';
|
||||
import 'military_grid_utils.dart';
|
||||
|
||||
/// Sovereign On-Device Minefield Threat & Breaching Corridor Engine
|
||||
class MinefieldEngine {
|
||||
MinefieldEngine._();
|
||||
|
||||
static const double earthRadiusM = 6371000.0;
|
||||
|
||||
/// Build Minefield Boundary Box, Density Calculation, and Safe Breaching Corridor
|
||||
static MinefieldZoneResult calculateMinefieldZone({
|
||||
required LatLng startPoint,
|
||||
required LatLng endPoint,
|
||||
required MinefieldType type,
|
||||
double widthMeters = 200.0,
|
||||
}) {
|
||||
// 1. Calculate Length & Azimuth
|
||||
final lengthMeters = MilitaryGridUtils.haversineDistance(
|
||||
startPoint.latitude,
|
||||
startPoint.longitude,
|
||||
endPoint.latitude,
|
||||
endPoint.longitude,
|
||||
);
|
||||
|
||||
final azimuthDeg = MilitaryGridUtils.calculateBearing(
|
||||
startPoint.latitude,
|
||||
startPoint.longitude,
|
||||
endPoint.latitude,
|
||||
endPoint.longitude,
|
||||
);
|
||||
|
||||
final azRad = (azimuthDeg * math.pi) / 180.0;
|
||||
final perpRad = azRad + (math.pi / 2.0);
|
||||
|
||||
final halfWidth = widthMeters / 2.0;
|
||||
|
||||
// Helper: offset lat/lng by distance and bearing
|
||||
LatLng offsetCoord(LatLng origin, double distM, double bearingRad) {
|
||||
final dLat = (distM / earthRadiusM) * (180.0 / math.pi) * math.cos(bearingRad);
|
||||
final dLng = (distM / (earthRadiusM * math.cos(origin.latitude * math.pi / 180.0))) * (180.0 / math.pi) * math.sin(bearingRad);
|
||||
return LatLng(origin.latitude + dLat, origin.longitude + dLng);
|
||||
}
|
||||
|
||||
// 2. Build 4 Corners of Minefield Polygon
|
||||
final p1 = offsetCoord(startPoint, halfWidth, perpRad);
|
||||
final p2 = offsetCoord(endPoint, halfWidth, perpRad);
|
||||
final p3 = offsetCoord(endPoint, halfWidth, perpRad + math.pi);
|
||||
final p4 = offsetCoord(startPoint, halfWidth, perpRad + math.pi);
|
||||
|
||||
final boundary = [p1, p2, p3, p4, p1];
|
||||
|
||||
// 3. Generate Safe Breaching Lane (الممر الآمن عبر الثغرة)
|
||||
// 16-meter wide swept corridor right through the middle
|
||||
const double breachWidthM = 16.0;
|
||||
final halfBreach = breachWidthM / 2.0;
|
||||
|
||||
final midStart = LatLng(
|
||||
(p1.latitude + p4.latitude) / 2.0,
|
||||
(p1.longitude + p4.longitude) / 2.0,
|
||||
);
|
||||
final midEnd = LatLng(
|
||||
(p2.latitude + p3.latitude) / 2.0,
|
||||
(p2.longitude + p3.longitude) / 2.0,
|
||||
);
|
||||
|
||||
final b1 = offsetCoord(midStart, halfBreach, perpRad);
|
||||
final b2 = offsetCoord(midEnd, halfBreach, perpRad);
|
||||
final b3 = offsetCoord(midEnd, halfBreach, perpRad + math.pi);
|
||||
final b4 = offsetCoord(midStart, halfBreach, perpRad + math.pi);
|
||||
|
||||
final breachPolygon = [b1, b2, b3, b4, b1];
|
||||
final breachCenterline = [midStart, midEnd];
|
||||
|
||||
// 4. Estimate Mines Count based on standard doctrine density
|
||||
double densityPerM2;
|
||||
switch (type) {
|
||||
case MinefieldType.antiTank:
|
||||
densityPerM2 = 0.005; // ~1 per 200 m2
|
||||
break;
|
||||
case MinefieldType.antiPersonnel:
|
||||
densityPerM2 = 0.025; // ~1 per 40 m2
|
||||
break;
|
||||
case MinefieldType.mixedBarrier:
|
||||
densityPerM2 = 0.035;
|
||||
break;
|
||||
}
|
||||
final areaM2 = lengthMeters * widthMeters;
|
||||
final estimatedMines = (areaM2 * densityPerM2).roundToDouble();
|
||||
|
||||
return MinefieldZoneResult(
|
||||
startPoint: startPoint,
|
||||
endPoint: endPoint,
|
||||
type: type,
|
||||
widthMeters: widthMeters,
|
||||
lengthMeters: (lengthMeters * 10).round() / 10.0,
|
||||
estimatedMinesCount: estimatedMines,
|
||||
boundaryPolygon: boundary,
|
||||
breachLaneCenterline: breachCenterline,
|
||||
breachLanePolygon: breachPolygon,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user