Commit b45f895d authored by Chae Ho Shin's avatar Chae Ho Shin

Working version(with inertial movement)

parent 4e42a919
#include <iostream> #include <iostream>
#include <Windows.h> #include <Windows.h>
#include "mainobserver.h"
int main(void) int main(void)
{ {
auto dummyobserver = Flatland::Mainworldobserver();
auto x = std::make_tuple(Flatland::INERTIAL, 0.0, 0.0, 0.0, 0.0, 0);
auto player = Flatland::Player(x);
Flatland::Flatlandobject * wow = &player;
dummyobserver.objectlist.push_back(std::make_tuple(wow,std::get<3>(x)));
auto object1 = Flatland::Object1();
wow = &object1;
dummyobserver.objectlist.push_back(std::make_tuple(wow, std::get<3>(object1.objecthistory[0])));
while (true)
{
int x;
std::cin >> x;
//dummyobserver.updatebytick(1.0);
dummyobserver.currenttime += 1.0;
player.changestate(dummyobserver.currenttime);
wow->changestate(dummyobserver.currenttime);
//dummyobserver.objectlist[1] =
player.updatepastlightcone(&dummyobserver);
std::cout << player.pastlightcone << std::endl;
}
} }
\ No newline at end of file
#include <string> #include "mainobserver.h"
#include <vector>
#include <cmath>
#include <algorithm>
#include <functional>
#define LIGHTSPEED 10
#define GAMMA(v) (1.0/sqrt(1.0 - (v*v)/(LIGHTSPEED * LIGHTSPEED)))
typedef std::vector<double> Vec; typedef std::vector<double> Vec;
typedef std::vector<Vec> Mat; typedef std::vector<Vec> Mat;
#define LORENTZ_BOOST(v) (Mat{{GAMMA(v), -GAMMA(v) * (v/LIGHTSPEED)},{-GAMMA(v) * (v/LIGHTSPEED), GAMMA(v)}})
Vec operator*(const Mat &a, const Vec &x) { Vec operator*(const Mat &a, const Vec &x) {
int i, j; int i, j;
...@@ -29,173 +22,245 @@ Vec operator*(const Mat &a, const Vec &x) { ...@@ -29,173 +22,245 @@ Vec operator*(const Mat &a, const Vec &x) {
} }
namespace flatland { auto Flatland::Player::updatepastlightcone(Mainworldobserver* mainobserver) -> void
{
enum State for (auto x = 0; x < 80; ++x)
{ {
INERTIAL, pastlightcone[x] = '-';
ACCELERATING, }
};
auto hmm = std::vector<std::tuple<Flatlandobject*, double>>(mainobserver->objectlist.begin() + 1, mainobserver->objectlist.end());
class Flatlandobject for (auto object : hmm)
{ {
auto theobject = std::get<0>(object);
Flatlandobject(/*std::vector<std::tuple<Flatlandobject, double>> theparts,*/ std::tuple<State, double, double, int, double, int> initialstate, Mainworldobserver* thegame) for (auto it = theobject->objecthistory.begin(); it != theobject->objecthistory.end(); ++it)
{ {
//parts = theparts; auto objectstate = *it;
objecthistory.push_back(initialstate);
thegame->objectlist.push_back(std::make_tuple(*this, std::get<3>(initialstate)));
}
public: auto mainclocktimeatstatechange = std::get<1>(objectstate);
bool isPlayer = false; auto propertimeclockatstatechange = std::get<2>(objectstate);
//std::vector<std::tuple<Flatlandobject, double>> parts = {}; auto maincoordinatelocationatstatechange = std::get<3>(objectstate);
std::vector<std::tuple<State, double, double, int, double, int>> objecthistory = {}; auto mainrelativevelocity = std::get<4>(objectstate);
// state, time(in main observer clock) at statechange, proper time clock at state change, location(in main observer coordinates) at state change, auto properacceleration = std::get<5>(objectstate);
// velocity(if inertial) relative to mainobserver, proper acceleration(if accelerating)
double propertime;
double currentvelocity;
int currentproperacceleration;
char name;
auto changestate(double maintime) -> void if (std::get<0>(objectstate) == INERTIAL)
{ {
return; auto lightconeeq1 = std::vector<double>{ 1.0, (mainobserver->currenttime*LIGHTSPEED - std::get<1>(mainobserver->objectlist[0])) };
} auto lightconeeq2 = std::vector<double>{ -1.0, (mainobserver->currenttime*LIGHTSPEED + std::get<1>(mainobserver->objectlist[0])) };
auto worldlineeq = std::vector<double>{ LIGHTSPEED/ mainrelativevelocity , (mainclocktimeatstatechange*LIGHTSPEED - maincoordinatelocationatstatechange* (LIGHTSPEED / mainrelativevelocity))};
}; //get intersection points(always exists since v<c)
auto intersection1 = std::vector<double>{
(lightconeeq1[0] * worldlineeq[1] - worldlineeq[0] * lightconeeq1[1]) / (lightconeeq1[0] - worldlineeq[0]),
(worldlineeq[1] - lightconeeq1[1]) / (lightconeeq1[0] - worldlineeq[0]),
};
auto intersection2 = std::vector<double>{
(lightconeeq2[0] * worldlineeq[1] - worldlineeq[0] * lightconeeq2[1]) / (lightconeeq2[0] - worldlineeq[0]),
(worldlineeq[1] - lightconeeq2[1]) / (lightconeeq2[0] - worldlineeq[0]),
};
class Player : public Flatlandobject //auto & nextobjectstate = *(std::next(it));
{
public:
bool isPlayer = true;
std::vector<std::tuple<Flatlandobject, double>> world = {};
char pastlightcone[81] = "--------------------------------------------------------------------------------";
auto updatepastlightcone(Mainworldobserver* mainobserver) -> void auto lasttime = mainobserver->currenttime;
{
for (auto object : world) if (std::next(it) != theobject->objecthistory.end())
{
auto & nextobjectstate = *(std::next(it));
lasttime = std::get<1>(nextobjectstate);
}
if (mainclocktimeatstatechange <= intersection1[0] / LIGHTSPEED && intersection1[0] / LIGHTSPEED < lasttime)
{
intersection1 = std::vector<double>{ intersection1[0] - LIGHTSPEED * mainobserver->currenttime, intersection1[1] - std::get<1>(mainobserver->objectlist[0]) };
intersection1 = LORENTZ_BOOST(-currentvelocity)*intersection1;
intersection1[0] = intersection1[0] / LIGHTSPEED;
if (-40.0 < intersection1[1] && intersection1[1] < 40.0)
{
pastlightcone[(int)round(intersection1[1])] = theobject->name;
}
}
if (mainclocktimeatstatechange <= intersection2[0] / LIGHTSPEED && intersection2[0] / LIGHTSPEED < lasttime)
{
intersection2 = std::vector<double>{ intersection2[0] - LIGHTSPEED * mainobserver->currenttime, intersection2[1] - std::get<1>(mainobserver->objectlist[0]) };
intersection2 = LORENTZ_BOOST(-currentvelocity)*intersection2;
intersection2[0] = intersection2[0] / LIGHTSPEED;
if (-40.0 < intersection2[1] && intersection2[1] < 40.0)
{
pastlightcone[(int)round(intersection2[1])+40] = theobject->name;
}
}
}
else
{ {
auto theobject = std::get<0>(object); auto lightconeeq1 = std::vector<double>{ 1.0, (mainobserver->currenttime*LIGHTSPEED - std::get<1>(mainobserver->objectlist[0])) };
auto lightconeeq2 = std::vector<double>{ -1.0, (mainobserver->currenttime*LIGHTSPEED + std::get<1>(mainobserver->objectlist[0])) };
auto intersection1 = std::vector<double>{ 0,0 };
auto intersection2 = std::vector<double>{ 0,0 };
// point at which mainrelativevelocity is tangent to the acceleration hyperbola (t', x') with (0,0) being v=0
// so (t', x') -> (mainclocktimeatstatechange, maincoordinatelocationatstatechange)
auto accelerationeqoffset = std::vector<double>{
(LIGHTSPEED*GAMMA(mainrelativevelocity)*mainrelativevelocity / properacceleration) - LIGHTSPEED * mainclocktimeatstatechange,
((LIGHTSPEED*LIGHTSPEED / properacceleration)*(sqrt((GAMMA(mainrelativevelocity)*mainrelativevelocity / LIGHTSPEED)*(GAMMA(mainrelativevelocity)*mainrelativevelocity / LIGHTSPEED) + 1.0) - 1.0)) - maincoordinatelocationatstatechange };
//change lightcones eq. coord. so that they share (0,0) with acceleration hyperbola with (0,0) being v=0
lightconeeq1[1] += accelerationeqoffset[0] - accelerationeqoffset[1];
lightconeeq2[1] += accelerationeqoffset[0] + accelerationeqoffset[1];
//change lightcones eq. coord. such that they now share (0,0) with shifted acceleration hyperbola with (0,c^2/a) being v=0
lightconeeq1[1] += (LIGHTSPEED * LIGHTSPEED / properacceleration);
lightconeeq2[1] += (-LIGHTSPEED * LIGHTSPEED / properacceleration);
auto lasttime = mainobserver->currenttime;
for (auto objectstate : theobject.objecthistory) if (std::next(it) != theobject->objecthistory.end())
{
auto & nextobjectstate = *(std::next(it));
lasttime = std::get<1>(nextobjectstate);
}
if (lightconeeq1[1]*lightconeeq1[1] > 0.0) // determinant for intersection
{ {
auto mainclocktimeatstatechange = std::get<1>(objectstate);
auto propertimeclockatstatechange = std::get<2>(objectstate);
auto maincoordinatelocationatstatechange = std::get<3>(objectstate);
auto mainrelativevelocity = std::get<4>(objectstate);
auto properacceleration = std::get<5>(objectstate);
if (std::get<0>(objectstate) == INERTIAL) intersection1[1] = ((LIGHTSPEED*LIGHTSPEED*LIGHTSPEED*LIGHTSPEED) / (properacceleration*properacceleration) + (lightconeeq1[1] * lightconeeq1[1])) / (2 * lightconeeq1[1]);
intersection1[0] = intersection1[1] + lightconeeq1[1];
//shift intersection point x back to main observer coordinates
intersection1[1] -= (accelerationeqoffset[1]) + ((LIGHTSPEED * LIGHTSPEED) / properacceleration);
//shift intersection point y back to main observer coordinates
intersection1[0] -= (accelerationeqoffset[0]);
if (mainclocktimeatstatechange <= intersection1[0] / LIGHTSPEED && intersection1[0] / LIGHTSPEED < lasttime)
{ {
auto lightconeeq1 = std::vector<double>{ LIGHTSPEED, mainobserver->currenttime - std::get<1>(mainobserver->objectlist[0]) }; intersection1 = std::vector<double>{ intersection1[0] - LIGHTSPEED * mainobserver->currenttime, intersection1[1] - std::get<1>(mainobserver->objectlist[0]) };
auto lightconeeq2 = std::vector<double>{ -LIGHTSPEED, mainobserver->currenttime - std::get<1>(mainobserver->objectlist[0]) }; intersection1 = LORENTZ_BOOST(-currentvelocity)*intersection1;
auto worldlineeq = std::vector<double>{ mainrelativevelocity, mainclocktimeatstatechange - maincoordinatelocationatstatechange};
intersection1[0] = intersection1[0] / LIGHTSPEED;
auto intersection1 = std::vector<double>{
(lightconeeq1[0] * worldlineeq[1] - worldlineeq[0] * lightconeeq1[1]) / (lightconeeq1[0] - worldlineeq[0]),
(worldlineeq[1] - lightconeeq1[1])/(lightconeeq1[0]-worldlineeq[0]),
};
auto intersection2 = std::vector<double>{
(lightconeeq2[0] * worldlineeq[1] - worldlineeq[0] * lightconeeq2[1]) / (lightconeeq2[0] - worldlineeq[0]),
(worldlineeq[1] - lightconeeq2[1]) / (lightconeeq2[0] - worldlineeq[0]),
};
if (mainclocktimeatstatechange < intersection1[0] && intersection1[0] < mainobserver->currenttime)
{
intersection1 = std::vector<double>{intersection1[0] - mainobserver->currenttime, intersection1[1] - std::get<1>(mainobserver->objectlist[0]) };
intersection1 = LORENTZ_BOOST(-currentvelocity)*intersection1;
if (-40.0 < intersection1[1] && intersection1[1] < 40.0)
{
pastlightcone[(int)round(intersection1[1])] = name;
}
}
if (mainclocktimeatstatechange < intersection2[0] && intersection2[0] < mainobserver->currenttime)
{
intersection2 = std::vector<double>{ intersection2[0] - mainobserver->currenttime, intersection2[1] - std::get<1>(mainobserver->objectlist[0]) };
intersection2 = LORENTZ_BOOST(-currentvelocity)*intersection2;
if (-40.0 < intersection2[1] && intersection2[1] < 40.0) if (-40.0 < intersection1[1] && intersection1[1] < 40.0)
{ {
pastlightcone[(int)round(intersection2[1])] = name; pastlightcone[(int)round(intersection1[1])] = theobject->name;
}
} }
} }
else
{
auto lightconeeq1 = std::vector<double>{ LIGHTSPEED, mainobserver->currenttime - std::get<1>(mainobserver->objectlist[0]) };
auto lightconeeq2 = std::vector<double>{ -LIGHTSPEED, mainobserver->currenttime - std::get<1>(mainobserver->objectlist[0]) };
auto accelerationeq = std::vector<double>{}; }
else if (lightconeeq2[1] * lightconeeq2[1] > 0.0)
{
intersection2[1] = ((LIGHTSPEED*LIGHTSPEED*LIGHTSPEED*LIGHTSPEED) / (properacceleration*properacceleration) + (lightconeeq2[1] * lightconeeq2[1])) / (2.0 * lightconeeq2[1]);
intersection2[0] = intersection2[1] + lightconeeq2[1];
//shift intersection point x back to main observer coordinates
intersection2[1] -= (accelerationeqoffset[1]) - ((LIGHTSPEED * LIGHTSPEED) / properacceleration);
//shift intersection point y back to main observer coordinates
intersection2[0] -= (accelerationeqoffset[0]);
if (mainclocktimeatstatechange <= intersection2[0] / LIGHTSPEED && intersection2[0] / LIGHTSPEED < lasttime)
{
intersection2 = std::vector<double>{ intersection2[0] - LIGHTSPEED * mainobserver->currenttime, intersection2[1] - std::get<1>(mainobserver->objectlist[0]) };
intersection2 = LORENTZ_BOOST(-currentvelocity)*intersection2;
intersection2[0] = intersection2[0] / LIGHTSPEED;
if (-40.0 < intersection2[1] && intersection2[1] < 40.0)
{
pastlightcone[(int)round(intersection2[1])] = theobject->name;
}
} }
} }
} }
} }
}; //for (auto objectstate : theobject.objecthistory)
//{
//
//}
}
return;
}
class Mainworldobserver
{
public:
std::vector<std::tuple<Flatlandobject, double>> objectlist = {}; // first object is always player auto Flatland::Player::changestate(double maintime) -> void
//int playervelocity; {
double currenttime = 0.0; return;
}
auto updatebytick(double tick) -> void;
};
auto Mainworldobserver::updatebytick(double tick) -> void auto Flatland::Object1::changestate(double maintime) -> void
{
if (maintime / 5.0 >= cnt)
{ {
this->currenttime += tick; for (auto i = cnt; i <= (maintime / 5.0); ++i)
for (std::tuple<Flatlandobject, double> a: this->objectlist)
{ {
auto theobject = std::get<0>(a); auto v = 2.5 / sqrt(1.0+(2.5/LIGHTSPEED)*(2.5/LIGHTSPEED));
auto objectstate = theobject.objecthistory.back(); Flatlandobject::objecthistory.push_back(std::make_tuple(ACCELERATING, cnt*5, GAMMA(5.0) * 5.0 * i, 5.0, (toggle)? -v:v, (toggle) ? 1 : -1));
auto mainclocktimeatstatechange = std::get<1>(objectstate); toggle = !toggle;
auto propertimeclockatstatechange = std::get<2>(objectstate); cnt++;
auto maincoordinatelocationatstatechange = std::get<3>(objectstate);
auto mainrelativevelocity = std::get<4>(objectstate);
auto properacceleration = std::get<5>(objectstate);
double newx;
if (std::get<0>(objectstate) == INERTIAL)
{
newx = maincoordinatelocationatstatechange + mainrelativevelocity * (this->currenttime - mainclocktimeatstatechange);
std::tuple<Flatlandobject, double> newobjectinfo = std::make_tuple(theobject, newx);
a.swap(newobjectinfo);
free(&newobjectinfo);
auto a = std::vector<double>{this->currenttime - mainclocktimeatstatechange, newx- maincoordinatelocationatstatechange};
a = LORENTZ_BOOST(theobject.currentvelocity) * a;
theobject.propertime = propertimeclockatstatechange + a[0];
theobject.currentproperacceleration = 0;
}
else
{
}
/*for (std::tuple<Flatlandobject, double> apart : (theobject.parts))
{
auto thepart = std::get<0>(apart);
auto relativelocationtoCoM = std::get<1>(apart);
auto partstate = thepart.objecthistory.back();
if (std::get<0>(partstate) == INERTIAL)
{
auto a = std::vector<double>{ theobject.propertime, (double)relativelocationtoCoM };
a = LORENTZ_BOOST(-theobject.currentvelocity) * a;
a = std::vector<double>{ a[0] + this->currenttime , a[1] + newx };
thepart.currentvelocity = theobject.currentvelocity;
}
}*/
theobject.changestate(this->currenttime);
} }
} }
return;
}
auto Flatland::Mainworldobserver::updatebytick(double tick) -> void
{
currenttime += tick;
auto cnt = 0;
for (std::tuple<Flatlandobject*, double> a : objectlist)
{
auto theobject = std::get<0>(a);
auto objectstate = theobject->objecthistory.back();
auto mainclocktimeatstatechange = std::get<1>(objectstate);
auto propertimeclockatstatechange = std::get<2>(objectstate);
auto maincoordinatelocationatstatechange = std::get<3>(objectstate);
auto mainrelativevelocity = std::get<4>(objectstate);
auto properacceleration = std::get<5>(objectstate);
double newx;
/*if (std::get<0>(objectstate) == INERTIAL)
{
newx = maincoordinatelocationatstatechange + mainrelativevelocity * (this->currenttime - mainclocktimeatstatechange);
std::tuple<Flatlandobject, double> newobjectinfo = std::make_tuple(theobject, newx);
a.swap(newobjectinfo);
free(&newobjectinfo);
auto a = std::vector<double>{this->currenttime - mainclocktimeatstatechange, newx- maincoordinatelocationatstatechange};
a = LORENTZ_BOOST(theobject.currentvelocity) * a;
theobject.propertime = propertimeclockatstatechange + a[0];
theobject.currentproperacceleration = 0;
}
else
{
}
/*for (std::tuple<Flatlandobject, double> apart : (theobject.parts))
{
auto thepart = std::get<0>(apart);
auto relativelocationtoCoM = std::get<1>(apart);
auto partstate = thepart.objecthistory.back();
if (std::get<0>(partstate) == INERTIAL)
{
auto a = std::vector<double>{ theobject.propertime, (double)relativelocationtoCoM };
a = LORENTZ_BOOST(-theobject.currentvelocity) * a;
a = std::vector<double>{ a[0] + this->currenttime , a[1] + newx };
thepart.currentvelocity = theobject.currentvelocity;
}
}*/
theobject->changestate(currenttime);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment