Created
October 5, 2023 17:35
-
-
Save JamesBremner/873e02020b369cb55e8b7915ca3d17cd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <fstream> | |
#include <sstream> | |
#include <iostream> | |
#include <vector> | |
#include <algorithm> | |
#include <wex.h> | |
#include "plot2d.h" | |
#include "cStarterGUI.h" | |
class cTrains | |
{ | |
std::vector<std::vector<std::string>> vHourlySchedule; | |
std::vector<std::vector<int>> vSecsSchedule; | |
int maxsecs; | |
public: | |
cTrains() | |
{ | |
generateHourlySchedule(); | |
convertScheduleToSecs(); | |
} | |
void generateHourlySchedule() | |
{ | |
vHourlySchedule = { | |
{":35:00", ":38:18", ":45:06"}, | |
{":55:06", ":59:12", ":06:18"}, | |
{":12:00", ":18:12", ":23:18"}}; | |
} | |
void convertScheduleToSecs() | |
{ | |
maxsecs = 0; | |
for (auto &train : vHourlySchedule) | |
{ | |
std::vector<int> trainSchedule; | |
for (std::string &minsec : train) | |
{ | |
if (!trainSchedule.size()) | |
trainSchedule.push_back(fms2secs(0, minsec)); | |
else | |
{ | |
int secs = fms2secs(trainSchedule[0], minsec); | |
trainSchedule.push_back(secs); | |
if (secs > maxsecs) | |
maxsecs = secs; | |
} | |
} | |
vSecsSchedule.push_back(trainSchedule); | |
} | |
} | |
int trainY(int train, int sec) const | |
{ | |
if (0 > train || train >= trainCount()) | |
throw std::runtime_error("trainY bad train index"); | |
const int stationYinc = 100; | |
const int stopsecs = 42; | |
for (int station = 0; station < vSecsSchedule[train].size() - 1; station++) | |
{ | |
int prev = 0; | |
if (station > 0) | |
prev = vSecsSchedule[train][station - 1]; | |
int arr = vSecsSchedule[train][station]; | |
int nxt = vSecsSchedule[train][station + 1]; | |
int stationY = (station + 1) * stationYinc; | |
// check if train has not left the station yet | |
if (sec < arr + stopsecs) | |
return stationY + train; | |
// check if train on way to next station | |
if (sec < nxt) | |
{ | |
// interpolate between stations | |
double f = ((float)(sec - arr - stopsecs)) / ((float)(nxt - arr - stopsecs)); | |
return stationY + f * stationYinc + train; | |
} | |
} | |
// train has arrived at last station | |
return vSecsSchedule[train].size() * stationYinc + train; | |
} | |
int trainCount() const | |
{ | |
return vHourlySchedule.size(); | |
} | |
std::vector<double> plot(int train) | |
{ | |
const int secinc = 10; | |
if (0 > train || train >= trainCount()) | |
throw std::runtime_error("plot bad train index"); | |
std::vector<double> ret; | |
for (int s = 0; s < maxsecs; s += secinc) | |
ret.push_back(trainY(train, s)); | |
return ret; | |
} | |
private: | |
int fms2secs( | |
int secs1, // secs since epoch at station 1, 0 if not yet available | |
const std::string &minsec) // time at station to be converted | |
{ | |
int s = 60 * atoi(minsec.substr(1, 2).c_str()) + atoi(minsec.substr(4, 2).c_str()); | |
if (s < secs1) // check for hour wrap | |
s = s + 60 * 60; | |
return s; | |
} | |
}; | |
class cGUI : public cStarterGUI | |
{ | |
public: | |
cGUI() | |
: cStarterGUI( | |
"Trains", | |
{50, 50, 1000, 500}), | |
thePlot(wex::maker::make<wex::plot::plot>(fm)) | |
{ | |
thePlot.move({30, 30, 1200, 600}); | |
// construct plot traces | |
wex::plot::trace &t1 = thePlot.AddStaticTrace(); | |
wex::plot::trace &t2 = thePlot.AddStaticTrace(); | |
wex::plot::trace &t3 = thePlot.AddStaticTrace(); | |
t1.color(0x0000FF); | |
t2.color(0xFF0000); | |
t3.color(0xAAFFAA); | |
auto d1 = myTrains.plot(0); | |
t1.set(d1); | |
d1 = myTrains.plot(1); | |
t2.set(d1); | |
d1 = myTrains.plot(2); | |
t3.set(d1); | |
// resize plot when form resizes | |
fm.events().resize( | |
[&](int w, int h) | |
{ | |
thePlot.move({30, 30, w, h}); | |
thePlot.update(); | |
}); | |
show(); | |
run(); | |
} | |
private: | |
cTrains myTrains; | |
wex::plot::plot &thePlot; | |
}; | |
main() | |
{ | |
cGUI theGUI; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment