summaryrefslogtreecommitdiffstats
path: root/src/atragmx.c
diff options
context:
space:
mode:
authorhybrid <hybrid@hybridlabs.pro>2026-08-08 08:10:17 +0300
committerhybrid <hybrid@hybridlabs.pro>2026-08-08 08:10:17 +0300
commit1d1796c97867ada2211a39b313ef6398297c7b8f (patch)
tree927e9c477d7a974fb219ed9963fced6ea8109b5c /src/atragmx.c
parent884bac2a767bf5bf77413c055a6484a7ea87700c (diff)
downloada3catragmx-1d1796c97867ada2211a39b313ef6398297c7b8f.tar.gz
a3catragmx-1d1796c97867ada2211a39b313ef6398297c7b8f.tar.bz2
a3catragmx-1d1796c97867ada2211a39b313ef6398297c7b8f.zip
upd: tmp
Diffstat (limited to 'src/atragmx.c')
-rw-r--r--src/atragmx.c204
1 files changed, 188 insertions, 16 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;
}