feat: Very broken trigonometry but planes turn

This commit is contained in:
2026-04-23 17:51:22 +01:00
parent ef716b7425
commit 2920749387
6 changed files with 55 additions and 7 deletions

View File

@@ -9,6 +9,7 @@
typedef struct vec2 { float x, y; } vec2; typedef struct vec2 { float x, y; } vec2;
typedef struct vec2i { int x, y; } vec2i; typedef struct vec2i { int x, y; } vec2i;
typedef struct polar_t { float angle, length; } polar_t;
static const vec2 vec2_zero = { 0, 0 }; static const vec2 vec2_zero = { 0, 0 };
static const vec2 vec2_one = { 1, 1 }; static const vec2 vec2_one = { 1, 1 };
@@ -102,8 +103,29 @@ static vec2 max2(vec2 const &a, vec2 const &b)
static vec2 polar_to_vec2(const float angle, const float len) static vec2 polar_to_vec2(const float angle, const float len)
{ {
// 0 (north) up
return { return {
.x = len * sinf(angle), .x = len * sinf(angle),
.y = len * cosf(angle) .y = len * cosf(angle)
}; };
} }
static polar_t vec2_to_polar(const vec2 v)
{
// 0 (north) up
if (v.x == 0)
return {
.angle = (v.y > 0) ? 0 : M_PIf,
.length = abs(v.y)
};
polar_t ret = {
.angle = atanf(v.x / v.y) + (v.y > 0 ? 0 : M_PIf),
.length = norm(v)
};
if (ret.angle < 0)
ret.angle += 2 * M_PIf;
return ret;
}

View File

@@ -1,5 +1,7 @@
#include "af_spawner.hpp" #include "af_spawner.hpp"
#include <math.h>
void dxd::sim::AFSpawner::tick(float timestep, World *world) void dxd::sim::AFSpawner::tick(float timestep, World *world)
{ {
(void)timestep; (void)timestep;
@@ -11,7 +13,7 @@ void dxd::sim::AFSpawner::tick(float timestep, World *world)
//Pos should spawn in a grid, check if free, and offset random from grid coord to look natural //Pos should spawn in a grid, check if free, and offset random from grid coord to look natural
vec2 pos = {(SDL_randf()-.5f)*2*60.0f, (SDL_randf()-.5f)*2*60.0f}; vec2 pos = {(SDL_randf()-.5f)*2*60.0f, (SDL_randf()-.5f)*2*60.0f};
Airfield *af = new Airfield(pos, _MIN_AF_TTL + SDL_rand(_MAX_AF_TTL)); Airfield *af = new Airfield(pos, _MIN_AF_TTL + SDL_rand(_MAX_AF_TTL), SDL_randf()*2*M_PIf);
world->add_obj(af); world->add_obj(af);
_airfields.push_back(af); _airfields.push_back(af);
} }

View File

@@ -5,6 +5,16 @@ void dxd::sim::Aircraft::tick(float timestep, World *world)
{ {
(void)world; (void)world;
float target_direction = vec2_to_polar(_target - _position).angle;
float target_deviation = target_direction - _direction;
//TODO: Fix this normalization mess
if (target_deviation > M_PIf)
{
target_deviation -= 2 * M_PIf;
}
printf("%0.2f %.2f %0.2f\n", target_direction, target_deviation, target_direction - _direction);
_direction += SDL_clamp(target_deviation, -_MAX_TURN_RATE, _MAX_TURN_RATE) * timestep;
_position = _position + polar_to_vec2(_direction, _speed) * timestep; _position = _position + polar_to_vec2(_direction, _speed) * timestep;
if (--_trail_cooldown == 0) if (--_trail_cooldown == 0)

View File

@@ -12,14 +12,16 @@ private:
vec2 _position; vec2 _position;
float _direction; float _direction;
float _speed; float _speed;
vec2 _target;
int _trail_cooldown; int _trail_cooldown;
const int _TRAIL_DELAY = 60; const int _TRAIL_DELAY = 60;
const int _TRAIL_DURATION = 420; const int _TRAIL_DURATION = 420;
const float _MAX_TURN_RATE = 0.5f;
public: public:
Aircraft(vec2 position, float direction, float speed) Aircraft(vec2 position, float direction, float speed, vec2 target)
: _position(position), _direction(direction), _speed(speed) : _position(position), _direction(direction), _speed(speed), _target(target)
{ {
_trail_cooldown = _TRAIL_DELAY; _trail_cooldown = _TRAIL_DELAY;
} }

View File

@@ -13,9 +13,13 @@ void dxd::sim::Airfield::tick(float timestep, World *world)
if (--_next_spawn == 0) if (--_next_spawn == 0)
{ {
Aircraft *af = new Aircraft(_position, SDL_randf() * 2 * M_PIf, 5.0f); vec2 pos = _position + polar_to_vec2(_rw_heading, _WR_LENGTH+0.5);
//vec2 tgt = _position + polar_to_vec2(SDL_randf()*2*M_PIf, 30);
vec2 tgt = _position + polar_to_vec2(0, 80);
Aircraft *af = new Aircraft(pos, _rw_heading, 5.0f, tgt);
world->add_obj(af); world->add_obj(af);
_next_spawn = _MIN_TAKEOFF_DELAY + SDL_rand(_MAX_TAKEOFF_DELAY - _MIN_TAKEOFF_DELAY); //_next_spawn = _MIN_TAKEOFF_DELAY + SDL_rand(_MAX_TAKEOFF_DELAY - _MIN_TAKEOFF_DELAY);
_next_spawn = 99999999;
} }
} }
@@ -24,4 +28,9 @@ void dxd::sim::Airfield::draw(Renderer *rend)
rend->color(127, 127, 127, 255); rend->color(127, 127, 127, 255);
rend->rect(_position, 5); rend->rect(_position, 5);
rend->diamond(_position, 5); rend->diamond(_position, 5);
rend->color(64, 64, 255, 255);
vec2 a = _position + polar_to_vec2(_rw_heading, +_WR_LENGTH);
vec2 b = _position + polar_to_vec2(_rw_heading, -_WR_LENGTH);
rend->line(a, b);
} }

View File

@@ -14,14 +14,17 @@ private:
vec2 _position; vec2 _position;
int _ttl; int _ttl;
int _next_spawn; int _next_spawn;
float _rw_heading;
const int _MIN_TAKEOFF_DELAY = 240; const int _MIN_TAKEOFF_DELAY = 240;
const int _MAX_TAKEOFF_DELAY = 600; const int _MAX_TAKEOFF_DELAY = 600;
const int _WR_LENGTH = 6;
public: public:
Airfield(vec2 position, int ttl) : _position(position), _ttl(ttl) Airfield(vec2 position, int ttl, float rw_heading)
: _position(position), _ttl(ttl), _rw_heading(rw_heading)
{ {
_next_spawn = 30; _next_spawn = _MIN_TAKEOFF_DELAY;
} }
void tick(float timestep, World *world) override; void tick(float timestep, World *world) override;