[Add] Centrifuagal and Coriolis effect in rotating frames.

This commit is contained in:
Rtch90 2018-08-22 21:47:39 +01:00
parent 3e14d9cd5a
commit 392705570c
9 changed files with 63 additions and 13 deletions

View File

@ -99,16 +99,32 @@ vector3d DynamicBody::GetPosition(void) const {
void DynamicBody::TimeStepUpdate(const float timeStep) {
if(m_enabled) {
/* This is for rotating frames. It is reested. */
vector3d angRot = GetFrame()->GetAngVelocity();
{
double omega = angRot.Length();
if(omega) {
/* Centifugal force. */
vector3d perpend = vector3d::Cross(angRot, GetPosition());
perpend = vector3d::Normalize(Vector3d::Corss(perpend, angRot));
double R = vector3d::Dot(perpend, GetPosition());
double centrifugal = m_mass * omega * R;
m_force += centrifuagal * perpend;
/* Coriolis force. */
m_force += -2*m_mass*vector3d::Cross(angRot, GetVelocity());
}
}
m_oldOrient = m_orient;
m_vel += timeStep * m_force * (1.0/m_mass);
m_angVel += timeStep * m_torque * (1.0 / m_angInertia);
vector3d consideredAngVel = m_angVel - angRot;
vector3d pos = GetPosition();
/* Applying angular velocity :/ */
{
double len = m_angVel.Length();
double len = consideredAngVel.Length();
if(len != 0) {
vector3d rotAxis = m_angVel * (1.0 / len);
vector3d rotAxis = consideredAngVel * (1.0 / len);
matrix4x4d rotMatrix = matrix4x4d::RotateMatrix(len * timeStep,
rotAxis.x, rotAxis.y, rotAxis.z);
m_orient = rotMatrix * m_orient;

View File

@ -130,3 +130,20 @@ void Frame::RotateInTimestep(double step) {
m_orient = rotMatrix * m_orient;
}
/*
* For an object in a rotating frame, relative to non-rotating frames it
* must attain this velocity within rotating frame to be stationary.
*/
vector3d Frame::GetStasisVelocityAtPosition(const vector3d& pos) const {
const double omega = m_angVel.Length();
if(omega) {
vector3d perpend = vector3d::Cross(m_angVel, pos);
perpend = vector3d::Normalize(vector3d::Cross(perpend, m_angVel));
double R = vector3d::Dot(perpend, pos);
perpend *= R;
return -vector3d::Cross(m_angVel, perpend);
} else {
return vector3d(0,0,0);
}
}

View File

@ -28,6 +28,7 @@ public:
vector3d GetVelocity(void) const { return m_vel; }
void SetAngVelocity(const vector3d& angvel) { m_angVel = angvel; }
vector3d GetAngVelocity(void) const { return m_angVel; }
vector3d GetStasisVelocityAtPosition(const vector3d& pos) const;
const matrix4x4d& GetOrientation(void) const { return m_orient; }
void SetOrientation(const matrix4x4d& m) { m_orient = m; }
void SetRadius(double radius) { m_radius = radius; }

View File

@ -581,7 +581,7 @@ void TextureFontFace::LayoutString(const char* _str, float maxWidth) {
glPushMatrix();
for(int i = 0; i < num; i++) {
word_t word = words.front();
if(word.word) RenderString(word.word);
if(word.word) RenderMarkup(word.word);
glTranslatef(word.advx + _spaceWidth 0, 0);
words.pop_front();
}

View File

@ -195,11 +195,14 @@ void L3D::HandleEvents(void) {
matrix4x4d m; L3D::player->GetRotMatrix(m);
vector3d dir = m*vector3d(0,0,-1);
if(KeyState(SDLK_LSHIFT)) {
Frame* rotFrame = new Frame(L3D::player->GetFrame(), "Station rot frame");
rotFrame->SetRadius(3000.0); //(1.1*sbody->GetRadius());
rotFrame->SetPosition(L3D::player->GetPosition()+5000.0*dir);
rotFrame->SetAngVelocity(vector3d(0, 2*M_PI/10,0));
SpaceStation* station = new SpaceStation(SpaceStation::JJHOOP);
station->SetLabel("Poemi-chan's Folly");
station->SetFrame(L3D::player->GetFrame());
station->SetFrame(rotFrame);
station->SetRotMatrix(matrix4x4d::RotateZMatrix(M_PI));
station->SetPosition(L3D::player->GetPosition()+5000.0*dir);
Space::AddBody(station);
} else {
Ship* ship = new Ship(ShipType::LADYBIRD);

View File

@ -226,7 +226,9 @@ void Player::DrawHUD(const Frame* cam_frame) {
/* Direction indicator. */
const float sz = HUD_CROSSHAIR_SIZE;
const vector3d vel = GetVelocity();
vector3d vel = GetVelocity();
vel -= GetFrame()->GetStasisVelocityAtPosition(GetPosition());
vector3d loc_v = cam_frame->GetOrientation().InverseOf() * vel;
if(loc_v.z < 0) {
GLdouble pos[3];

View File

@ -77,6 +77,7 @@ void Ship::AIModelCoordsMatchSpeedRelTo(const vector3d v, const Ship* other) {
AIAccelToModelRelativeVelocity(relToVel);
}
#include "frame.h"
/*
* Try to reach this model-relative velocity.
* (0,0,-100) would mean going 100m/s forward.
@ -84,7 +85,16 @@ void Ship::AIModelCoordsMatchSpeedRelTo(const vector3d v, const Ship* other) {
void Ship::AIAccelToModelRelativeVelocity(const vector3d v) {
const ShipType& stype = GetShipType();
vector3d relVel = GetVelocity(); // - enemy->GetVelocity();
/*
* Ok. For rotating frames linked to space stations we want to set speed
* relative to non-rotating frame (so we apply Frame::GetStasisVelocityAtPosition.
* For rotating frames linked to planets we want to set velocity relative to
* surface, so we do not apply Frame::GetStasisVelocityAtPosition.
*/
vector3d relVel = GetVelocity();
if(!GetFrame()->m_astroBody) {
relVel -= GetFrame()->GetStasisVelocityAtPosition(GetPosition());
}
matrix4x4d m; GetRotMatrix(m);
relVel = m.InverseOf() * relVel;

View File

@ -87,7 +87,7 @@ ShipCpanel::ShipCpanel(void) : Gui::Fixed(Gui::Screen::GetWidth(), 64) {
Add(m_clock, 2, 1);
tempMsg = new Gui::Label("");
Add(tempMsg, 170, 44);
Add(tempMsg, 170, 4);
}
void ShipCpanel::SetTemporaryMessage(Body* const sender, std::string msg) {

View File

@ -235,12 +235,11 @@ void Space::UpdateFramesOfReference(void) {
b->GetRotMatrix(rot);
b->SetRotMatrix(m * rot);
b->SetVelocity(oldFrameVel + m_ApplyRotationOnly(b->GetVelocity() -
b->GetFrame()->GetStasisVelocityAtPosition(b->GetPosition())));
b->SetFrame(new_frame);
b->SetPosition(new_pos);
/* Get rid of transforms. */
m.ClearToRotOnly();
b->SetVelocity(m*b->GetVelocity() + oldFrameVel);
} else {
b->SetVelocity(b->GetVelocity() + oldFrameVel);
}
@ -264,7 +263,9 @@ void Space::UpdateFramesOfReference(void) {
/* Get rid of transforms. */
m.ClearToRotOnly();
b->SetVelocity(m*b->GetVelocity()-child->GetVelocity());
b->SetVelocity(m*b->GetVelocity()
- kid->GetVelocity()
+ kid->GetStasisVelocityAtPosition(pos));
break;
}
}