X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=antikythera;a=blobdiff_plain;f=src%2Fmachine.cc;fp=src%2Fmachine.cc;h=716fc890568810b5e20678d65df950d0ede29e16;hp=0000000000000000000000000000000000000000;hb=a88a9ac53952e1bb3768b147a043c19392e3d5d1;hpb=ae60a8cb1a30e204e7f60969fe6245e510cca0ff diff --git a/src/machine.cc b/src/machine.cc new file mode 100644 index 0000000..716fc89 --- /dev/null +++ b/src/machine.cc @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include "machine.h" + +static float delta_angle(float a, float b); +static float signed_delta_angle(float a, float b); + +Machine::Machine() +{ + meshing = 0; + visited = 0; +} + +Machine::~Machine() +{ + int ngears = (int)gears.size(); + for(int i=0; iget_angular_pitch(); // assumed to be the same for meshing gears + + float frac_i = fmod(gears[i]->init_angle / gears[i]->get_angular_pitch() + 1.0, 1.0); + float frac_j = fmod(gears[j]->init_angle / gears[j]->get_angular_pitch() + 1.0, 1.0); + float delta = frac_j - frac_i; + + float correction = 0.5 - delta; + gears[j]->init_angle += correction * gears[j]->get_angular_pitch(); + } + } + } +} + +void Machine::update_gear(int idx, float angle) +{ + if(visited[idx]) { + if(delta_angle(angle, gears[idx]->angle) > 0.25 / gears[idx]->nteeth) { + fprintf(stderr, "warning: trying to transmit different values to gear %s (%d)\n", + gears[idx]->name.c_str(), idx); + } + return; + } + + gears[idx]->angle = angle; + visited[idx] = true; + + int ngears = (int)gears.size(); + for(int i=0; inteeth / (float)gears[i]->nteeth; + update_gear(i, angle * ratio); + } +} + +void Machine::update(float dt) +{ + int ngears = (int)gears.size(); + + memset(visited, 0, ngears * sizeof *visited); + for(size_t i=0; iangle + dt * motors[i].speed); + } +} + +void Machine::draw() const +{ + for(size_t i=0; idraw(); + } +} + + +static float delta_angle(float a, float b) +{ + float api = fmod(a + M_PI, 2.0 * M_PI); + float bpi = fmod(b + M_PI, 2.0 * M_PI); + return std::min(fabs(a - b), fabs(api - bpi)); +} + + +static float signed_delta_angle(float a, float b) +{ + float api = fmod(a + M_PI, 2.0 * M_PI); + float bpi = fmod(b + M_PI, 2.0 * M_PI); + + if(fabs(a - b) < fabs(api - bpi)) { + return a - b; + } + return api - bpi; +}