diff options
| author | hybrid <hybrid@hybridlabs.pro> | 2026-08-08 08:10:17 +0300 |
|---|---|---|
| committer | hybrid <hybrid@hybridlabs.pro> | 2026-08-08 08:10:17 +0300 |
| commit | 1d1796c97867ada2211a39b313ef6398297c7b8f (patch) | |
| tree | 927e9c477d7a974fb219ed9963fced6ea8109b5c /src | |
| parent | 884bac2a767bf5bf77413c055a6484a7ea87700c (diff) | |
| download | a3catragmx-1d1796c97867ada2211a39b313ef6398297c7b8f.tar.gz a3catragmx-1d1796c97867ada2211a39b313ef6398297c7b8f.tar.bz2 a3catragmx-1d1796c97867ada2211a39b313ef6398297c7b8f.zip | |
upd: tmp
Diffstat (limited to '')
| -rw-r--r-- | src/atragmx.c | 204 | ||||
| -rw-r--r-- | src/misc.c | 23 | ||||
| -rw-r--r-- | src/vector.c | 27 |
3 files changed, 211 insertions, 43 deletions
diff --git a/src/atragmx.c b/src/atragmx.c index 07cd580..c797505 100644 --- a/src/atragmx.c +++ b/src/atragmx.c @@ -8,6 +8,7 @@ #include "atragmx.h" #include "ace.h" #include "vector.h" +#include "misc.h" ATragMXSolution *ATragMXCalcSolution(ATragMXContext *ctx, ace_config *ace) { @@ -24,14 +25,6 @@ ATragMXSolution *ATragMXCalcSolution(ATragMXContext *ctx, ace_config *ace) { // local data - struct { - double speed1; - double speed2; - } wind = { - .speed1 = ctx->atmosphere.wind_speed[0], - .speed2 = ctx->atmosphere.wind_speed[1], - }; - struct { double tx; double tz; @@ -69,14 +62,19 @@ ATragMXSolution *ATragMXCalcSolution(ATragMXContext *ctx, ace_config *ace) { } local_solution = {0}; struct { + size_t n; double range; double true_range; double range_factor; - double *range_card; + RangeCard range_card; } ctx_range = { + .n = 0, .range_factor = ctx->store_range_card ? 1.0936133 : 1, - .range_card = NULL, + .range_card.records = (size_t) (rangeCardEndRange / rangeCardIncrement), + .range_card.card = calloc(ctx_range.range_card.records, + sizeof(RangeCardRecord)), }; + Vec3 wind1 = { .x = cos(270 - ctx->atmosphere.wind_dir * 30) @@ -122,6 +120,7 @@ ATragMXSolution *ATragMXCalcSolution(ATragMXContext *ctx, ace_config *ace) { while (local_solution.time_of_flight < 15 && bullet.pos.y < ctx->target.range) { + // calculate magnitude of bullet.velocity bullet.speed = vec3_magnitude(bullet.velocity); local_solution.true_velocity = vec3_diff(bullet.velocity, wind1); @@ -133,13 +132,186 @@ ATragMXSolution *ATragMXCalcSolution(ATragMXContext *ctx, ace_config *ace) { ctx->gun.ballistic_coef, ctx->gun.muzzle_velocity, ctx->atmosphere.temperature); - /* memcpy(bullet.accel, */ - /* (double[3]){bullet.accel[0] != 0 ? -data : 0, */ - /* bullet.accel[1] != 0 ? -data : 0, */ - /* bullet.accel[2] != 0 ? -data : 0}, */ - /* ); */ + + bullet.accel = vec3_mul(local_solution.true_velocity, + (-1.0 * data)); + } else { + bullet.accel = vec3_mul(local_solution.true_velocity, + local_solution.true_speed + * ctx->gun.air_friction); } + + bullet.accel = vec3_add(bullet.accel, bullet.gravity); + + bullet.last_pos = bullet.pos; + + bullet.pos = vec3_add(bullet.pos, + vec3_mul(bullet.velocity, bullet.deltaT * 0.5)); + + bullet.velocity = vec3_add(bullet.velocity, + vec3_mul(bullet.accel, bullet.deltaT)); + + bullet.pos = vec3_add(bullet.pos, + vec3_mul(bullet.velocity, bullet.deltaT * 0.5)); + + sln->time_of_flight = sln->time_of_flight + bullet.deltaT; + + // continue here + if (ctx->store_range_card) { + ctx_range.range = rangeCardStartRange + + ctx_range.n + * rangeCardIncrement; + + if (bullet.pos.x * ctx_range.range_factor >= ctx_range.range + && ctx_range.range <= rangeCardEndRange) { + + ctx_range.true_range = ctx_range.range / ctx_range.range_factor; + + if (ctx_range.true_range != 0) { + bullet.tx = linearConversion(bullet.last_pos.y, + bullet.pos.y, + ctx_range.true_range, + bullet.last_pos.x, + bullet.pos.x, false); + + bullet.tz = linearConversion(bullet.last_pos.y, + bullet.pos.y, + ctx_range.true_range, + bullet.last_pos.z, + bullet.pos.z, false); + + local_solution.elevation = - atan(bullet.tz + / ctx_range.true_range); + + local_solution.windage.w1 = - atan(bullet.tx + / ctx_range.true_range); + + wind_drift = wind2.x * (sln->time_of_flight + - ctx_range.true_range + / ctx->gun.muzzle_velocity); + + local_solution.windage.w2 = - atan(wind_drift + / ctx_range.true_range); + + sln->lead = (ctx->target.speed * sln->time_of_flight) + / (tan(MRAD_TO_DEG(1)) + * bullet.speed * bullet.speed); + } + double kinetic_energy = 0.5 * (ctx->gun.bullet_mass / 1000.0 + * (bullet.speed * bullet.speed)); + + kinetic_energy *= 0.737562149; + + if (ace->ballistics->enabled && bullet.pos.y > 0) { + // Coriolis + local_solution.h_coriolis_deflection = + 0.0000729 * bullet.pos.y * local_solution.time_of_flight + * sin(ctx->target.latitude); + + local_solution.h_coriolis = + - atan(local_solution.h_coriolis_deflection + / bullet.pos.y); + + local_solution.windage.w1 += local_solution.h_coriolis; + local_solution.windage.w2 += local_solution.h_coriolis; + + // Eoetvoes + local_solution.v_coriolis_deflection = + bullet.pos.z * eoetvoes_multiplier; + + local_solution.v_coriolis = + - atan(local_solution.v_coriolis_deflection + / bullet.pos.y); + + local_solution.elevation += local_solution.v_coriolis; + + // Spin drift + local_solution.spin_deflection = + ctx->gun.twist_dir * 0.0254 * 1.25 + * (ctx->stability_factor + 1.2) + * pow(local_solution.time_of_flight, 1.83); + + local_solution.spin_drift = + - atan(local_solution.spin_deflection / bullet.pos.y); + + local_solution.windage.w1 += local_solution.spin_drift; + local_solution.windage.w2 += local_solution.spin_drift; + } + + if (ctx_range.n < ctx_range.range_card.records) { + + ctx_range.range_card.card->n = ctx_range.n; + ctx_range.range_card.card->range = ctx_range.range; + + ctx_range.range_card.card->elevation + = local_solution.elevation; + + ctx_range.range_card.card->windage.w1 + = local_solution.windage.w1 * 60.0; + + ctx_range.range_card.card->windage.w2 + = local_solution.windage.w2 * 60.0; + + ctx_range.range_card.card->lead = sln->lead; + + ctx_range.range_card.card->time_of_flight + = local_solution.time_of_flight; + + ctx_range.range_card.card->bullet_speed = bullet.speed; + ctx_range.range_card.card->kinetic_energy = kinetic_energy; + } + ctx_range.n++; + } + } } + + double kinetic_energy = 0.5 * (ctx->gun.bullet_mass / 1000.0 * + (bullet.speed * bullet.speed)); + kinetic_energy *= 0.737562149; + + if (ace->ballistics->enabled && bullet.pos.y > 0) { + // Coriolis + local_solution.h_coriolis_deflection = 0.0000729 * bullet.pos.y * + local_solution.time_of_flight * + sin(ctx->target.latitude); + + local_solution.h_coriolis = + -atan(local_solution.h_coriolis_deflection / bullet.pos.y); + + local_solution.windage.w1 += local_solution.h_coriolis; + local_solution.windage.w2 += local_solution.h_coriolis; + + // Eoetvoes + local_solution.v_coriolis_deflection = + bullet.pos.z * eoetvoes_multiplier; + + local_solution.v_coriolis = + -atan(local_solution.v_coriolis_deflection / bullet.pos.y); + + local_solution.elevation += local_solution.v_coriolis; + + // Spin drift + local_solution.spin_deflection = + ctx->gun.twist_dir * 0.0254 * 1.25 * (ctx->stability_factor + 1.2) * + pow(local_solution.time_of_flight, 1.83); + + local_solution.spin_drift = + -atan(local_solution.spin_deflection / bullet.pos.y); + + local_solution.windage.w1 += local_solution.spin_drift; + local_solution.windage.w2 += local_solution.spin_drift; + } + + sln->elev = local_solution.elevation * 60.0; + sln->windage.w1 = local_solution.windage.w1 * 60.0; + sln->windage.w2 = local_solution.windage.w2 * 60.0; + sln->lead = local_solution.lead; + sln->time_of_flight = local_solution.time_of_flight; + sln->remaining_velocity = bullet.speed; + sln->remaining_energy = kinetic_energy; + sln->coriolis_vdrift = local_solution.v_coriolis * 60.0; + sln->coriolis_hdrift = local_solution.h_coriolis * 60.0; + sln->spin_drift = local_solution.spin_drift * 60.0; - return sln; + return sln; } diff --git a/src/misc.c b/src/misc.c new file mode 100644 index 0000000..a01a70d --- /dev/null +++ b/src/misc.c @@ -0,0 +1,23 @@ +#include "misc.h" + +double linearConversion(double min_from, double max_from, double value, + double min_to, double max_to, bool clip) { + // prevent division by zero + if (max_from == min_from) { + return min_to; + } + + // main formula + double result = min_to + (value - min_from) * (max_to - min_to) / (max_from - min_from); + + // check clipping + if (clip) { + if (result < min_to) { + result = min_to; + } else if (result > max_to) { + result = max_to; + } + } + + return result; +} diff --git a/src/vector.c b/src/vector.c deleted file mode 100644 index 7274cbb..0000000 --- a/src/vector.c +++ /dev/null @@ -1,27 +0,0 @@ -#include <math.h> - -#include "vector.h" - -static inline double vec3_magnitude(Vec3 v) { - return hypot(v.x, hypot(v.y, v.z)); -} - -static inline Vec3 vec3_diff(Vec3 a, Vec3 b) { - return (Vec3){.x = a.x - b.x, - .y = a.y - b.y, - .z = a.z - b.z}; -} - -static inline Vec3 vec3_normalize(Vec3 v) { - double len = sqrt(v.x * v.x - + v.y * v.y - + v.z * v.z); - if (len != 0.0) - return (Vec3){.x = v.x / len, - .y = v.y / len, - .z = v.z / len}; -} - -static inline Vec3 vec3_mul(Vec3 v, double n) { - -} |
