You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
358 lines
11 KiB
358 lines
11 KiB
/**
|
|
* \file movable.h
|
|
*
|
|
* \brief Definition eines Templates für bewegte Objekte
|
|
*
|
|
* Organisiert, verwaltet und steuert die Bewegung bewegter Objekte.
|
|
*
|
|
* \author Georg Steffers <georg@steffers.org> [gs]
|
|
*
|
|
* \date 19.12.2003
|
|
*
|
|
* \version 19.12.2003 [gs]: erste Implementation aus gra_app gezogen.
|
|
* \version 21.12.2003 [gs]: Bug in rotate_im_axis(double, vertex, vertex)
|
|
* gefixt. Dort wurden immer die Objektkoordinaten
|
|
* auf den Weltursprung verschoben und nicht die
|
|
* Vektorbasis wie es eigentlich sein sollte.
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C)2003 Georg Steffers
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#ifndef __movable_h__
|
|
#define __movable_h__
|
|
|
|
#include "vertex.h"
|
|
#include "../math/Mmn.h"
|
|
|
|
/**
|
|
* \brief Ein Interface für bewegte Objekte
|
|
*
|
|
* alle Objektklassen, die auch Kind dieses komplett öffentlichen
|
|
* Interfaces sind lassen sich dadurch rotieren und bewegen, das man die
|
|
* Rotations- und Bewegungsgeschwindigkeit bezüglich der lokalen,
|
|
* bzw. der Weltkoordinaten angibt.
|
|
* jeder Aufruf der Methode update aktualisiert dann die Positionen der
|
|
* Vektoren dieses Objekts.
|
|
*/
|
|
class movable {
|
|
protected:
|
|
vertex vrp; //!< \brief \<Punkt\> (view reference point)
|
|
//! das Zentrum des Objekts
|
|
vertex vfw_t; //!< \<Punkt\> Spitze von \ref vfw
|
|
vertex vup_t; //!< \<Punkt\> Spitze von \ref vup
|
|
vertex vri_t; //!< \<Punkt\> Spitze von \ref vri
|
|
vertex vfw; //!< \brief \<Vektor\> (vektor forward)
|
|
//! Objektkoordinatensystem z
|
|
vertex vup; //!< \brief \<Vektor\> (vektor up)
|
|
//! Objektkoordinatensystem y
|
|
vertex vri; //!< \brief \<Vektor\> (vektor right)
|
|
//! Objektkoordinatensystem x
|
|
|
|
Mmn<double> t_mat; //!< Die aktuelle Transformationsmatrize
|
|
|
|
//! \brief Geschwinidigkeiten
|
|
//! relativ zu Weltkoordinaten
|
|
double speed_x, speed_y, speed_z, rot_speed_x, rot_speed_y, rot_speed_z;
|
|
//! \brief Geschwinidigkeiten
|
|
//! relativ zu Objekt
|
|
double speed_vfw, speed_vri, speed_vup,
|
|
rot_speed_vfw, rot_speed_vri, rot_speed_vup;
|
|
|
|
|
|
time_t last_transform; //!<\brief Zeitpunkt der letzten Transformation
|
|
//!
|
|
//! Damit läßt sich der genaue
|
|
//! Zeitraum seit der letzten Transformation
|
|
//! berechnen und in alle Transformations
|
|
//! Berechnungen mit einfügen, so das
|
|
//! wir wirkliche Echtzeit bekommen.
|
|
|
|
//! Speed-Falloffs pro Sekunde
|
|
double speed_x_falloff,
|
|
speed_y_falloff,
|
|
speed_z_falloff,
|
|
rot_speed_x_falloff,
|
|
rot_speed_y_falloff,
|
|
rot_speed_z_falloff;
|
|
double speed_vfw_falloff,
|
|
speed_vri_falloff,
|
|
speed_vup_falloff,
|
|
rot_speed_vfw_falloff,
|
|
rot_speed_vri_falloff,
|
|
rot_speed_vup_falloff;
|
|
|
|
//! \brief Konstruktor
|
|
//!
|
|
//! privater Kontruktor, da man von dem Interface
|
|
//! keinen Eigenen Instanzen bilden können soll.
|
|
movable() {
|
|
vrp=vertex(0,0,0,1);
|
|
vfw_t=vertex(0,0,1,1);
|
|
vup_t=vertex(0,1,0,1);
|
|
vri_t=vertex(1,0,0,1);
|
|
vfw=vfw_t-vrp;
|
|
vup=vup_t-vrp;
|
|
vri=vri_t-vrp;
|
|
t_mat=Mmn<double>(4);
|
|
}
|
|
|
|
public:
|
|
virtual const Mmn<double>& get_t_mat(void) { return t_mat; }
|
|
|
|
virtual void reset(void) {
|
|
vrp.reset();
|
|
vfw_t.reset();
|
|
vup_t.reset();
|
|
vri_t.reset();
|
|
vfw=vfw_t-vrp;
|
|
vup=vup_t-vrp;
|
|
vri=vri_t-vrp;
|
|
|
|
t_mat=Mmn<double>(4);
|
|
}
|
|
|
|
/**
|
|
* \param t_st Transformationsstufe
|
|
*/
|
|
virtual void transform(unsigned t_st) {
|
|
vrp.transform(t_mat, t_st);
|
|
vfw_t.transform(t_mat, t_st);
|
|
vup_t.transform(t_mat, t_st);
|
|
vri_t.transform(t_mat, t_st);
|
|
vfw=vfw_t-vrp;
|
|
vup=vup_t-vrp;
|
|
vri=vri_t-vrp;
|
|
}
|
|
|
|
void print(void) {
|
|
t_mat.print();
|
|
}
|
|
|
|
const vertex& get_vrp(void) {
|
|
return vrp;
|
|
}
|
|
|
|
const vertex& get_vfw_t(void) {
|
|
return vfw_t;
|
|
}
|
|
|
|
const vertex& get_vup_t(void) {
|
|
return vup_t;
|
|
}
|
|
|
|
const vertex& get_vri_t(void) {
|
|
return vri_t;
|
|
}
|
|
|
|
const vertex& get_vfw(void) {
|
|
return vfw;
|
|
}
|
|
|
|
const vertex& get_vup(void) {
|
|
return vup;
|
|
}
|
|
|
|
const vertex& get_vri(void) {
|
|
return vri;
|
|
}
|
|
|
|
/**
|
|
* \brief direkte Veränderung der Position über eine
|
|
* vorberechnete Matrize.
|
|
* \param trans_mat Eine komplette vorberechnete Transformationsmatrix
|
|
*/
|
|
void move_im(const Mmn<double>& trans_mat) {
|
|
t_mat=trans_mat%t_mat;
|
|
}
|
|
/**
|
|
* \brief Verschiebung über (lokale) Objekkoordinaten
|
|
* \param axe Achse entlang der verschoben wird
|
|
* \param step wie weit verschoben wird
|
|
*/
|
|
void translate_im_axe(vertex axe, double step) {
|
|
axe=axe.norm()*step;
|
|
t_mat=mat_translate(axe[X], axe[Y], axe[Z])%t_mat;
|
|
}
|
|
/**
|
|
* \brief Verschiebung über (globale) Weltkoordinaten
|
|
* \param x Verschiebung in VRI
|
|
* \param y Verschiebung in VUP
|
|
* \param z Verschiebung in VFW
|
|
*/
|
|
void translate_im_global(double x, double y, double z) {
|
|
t_mat=mat_translate(x, y, z)%t_mat;
|
|
}
|
|
/**
|
|
* \brief Drehung über (lokale) Objekkoordinaten vfw
|
|
* \param angle Wieviel Grad soll gedreht werden
|
|
*/
|
|
void rotate_im_vfw(double angle) {
|
|
vfw_t.transform(t_mat, 1);
|
|
vrp.transform(t_mat, 1);
|
|
|
|
rotate_im_axis(angle, vfw_t, vrp);
|
|
|
|
vfw_t.reset();
|
|
vrp.reset();
|
|
}
|
|
/**
|
|
* \brief Drehung über (lokale) Objekkoordinaten vup
|
|
* \param angle Wieviel Grad soll gedreht werden
|
|
*/
|
|
void rotate_im_vup(double angle) {
|
|
vup_t.transform(t_mat, 1);
|
|
vrp.transform(t_mat, 1);
|
|
|
|
rotate_im_axis(angle, vup_t, vrp);
|
|
|
|
vup_t.reset();
|
|
vrp.reset();
|
|
}
|
|
/**
|
|
* \brief Drehung über (lokale) Objekkoordinaten vri
|
|
* \param angle Wieviel Grad soll gedreht werden
|
|
*/
|
|
void rotate_im_vri(double angle) {
|
|
vri_t.transform(t_mat, 1);
|
|
vrp.transform(t_mat, 1);
|
|
|
|
rotate_im_axis(angle, vri_t, vrp);
|
|
|
|
vri_t.reset();
|
|
vrp.reset();
|
|
}
|
|
/**
|
|
* \brief Drehung um X-Achse im Weltkoordinaten-Zentrum
|
|
* \param angle Wieviel Grad soll gedreht werden
|
|
*/
|
|
void rotate_im_g_x(double angle) {
|
|
t_mat=mat_rot_x(angle)%t_mat;
|
|
}
|
|
/**
|
|
* \brief Drehung um Y-Achse im Weltkoordinaten-Zentrum
|
|
* \param angle Wieviel Grad soll gedreht werden
|
|
*/
|
|
void rotate_im_g_y(double angle) {
|
|
t_mat=mat_rot_y(angle)%t_mat;
|
|
}
|
|
/**
|
|
* \brief Drehung um Z-Achse im Weltkoordinaten-Zentrum
|
|
* \param angle Wieviel Grad soll gedreht werden
|
|
*/
|
|
void rotate_im_g_z(double angle) {
|
|
t_mat=mat_rot_z(angle)%t_mat;
|
|
}
|
|
/**
|
|
* \brief Drehung um X-Achse im Objektkoordinaten-Zentrum
|
|
* \param angle Wieviel Grad soll gedreht werden
|
|
*/
|
|
void rotate_im_l_x(double angle) {
|
|
Mmn<double> mat_center(4);
|
|
Mmn<double> mat_reset(4);
|
|
|
|
mat_center.a(0,3)=-t_mat.a(0,3);
|
|
mat_center.a(1,3)=-t_mat.a(1,3);
|
|
mat_center.a(2,3)=-t_mat.a(2,3);
|
|
|
|
mat_reset.a(0,3)=t_mat.a(0,3);
|
|
mat_reset.a(1,3)=t_mat.a(1,3);
|
|
mat_reset.a(2,3)=t_mat.a(2,3);
|
|
|
|
t_mat=mat_reset%mat_rot_x(angle)%mat_center%t_mat;
|
|
}
|
|
/**
|
|
* \brief Drehung um Y-Achse im Objektkoordinaten-Zentrum
|
|
* \param angle Wieviel Grad soll gedreht werden
|
|
*/
|
|
void rotate_im_l_y(double angle) {
|
|
Mmn<double> mat_center(4);
|
|
Mmn<double> mat_reset(4);
|
|
|
|
mat_center.a(0,3)=-t_mat.a(0,3);
|
|
mat_center.a(1,3)=-t_mat.a(1,3);
|
|
mat_center.a(2,3)=-t_mat.a(2,3);
|
|
|
|
mat_reset.a(0,3)=t_mat.a(0,3);
|
|
mat_reset.a(1,3)=t_mat.a(1,3);
|
|
mat_reset.a(2,3)=t_mat.a(2,3);
|
|
|
|
t_mat=mat_reset%mat_rot_y(angle)%mat_center%t_mat;
|
|
}
|
|
/**
|
|
* \brief Drehung um Z-Achse im Objektkoordinaten-Zentrum
|
|
* \param angle Wieviel Grad soll gedreht werden
|
|
*/
|
|
void rotate_im_l_z(double angle) {
|
|
Mmn<double> mat_center(4);
|
|
Mmn<double> mat_reset(4);
|
|
|
|
mat_center.a(0,3)=-t_mat.a(0,3);
|
|
mat_center.a(1,3)=-t_mat.a(1,3);
|
|
mat_center.a(2,3)=-t_mat.a(2,3);
|
|
|
|
mat_reset.a(0,3)=t_mat.a(0,3);
|
|
mat_reset.a(1,3)=t_mat.a(1,3);
|
|
mat_reset.a(2,3)=t_mat.a(2,3);
|
|
|
|
t_mat=mat_reset%mat_rot_z(angle)%mat_center%t_mat;
|
|
}
|
|
/**
|
|
* \brief Drehung um eine beliebige Achse
|
|
* \param angle Wieviel Grad soll gedreht werden
|
|
* \param axe Die Achse um die gedreht werden soll als
|
|
* Ursprungsvektor (also einer der in WC(0,0,0) beginnt)
|
|
*/
|
|
void rotate_im_axis(double angle, const vertex& axe) {
|
|
t_mat=mat_rot_axe(angle, axe.get_t())%t_mat;
|
|
}
|
|
|
|
/**
|
|
* \brief Drehung um Z-Achse im Objektkoordinaten-Zentrum
|
|
* \param angle Wieviel Grad soll gedreht werden
|
|
* \param tip Vertexspitze der Rotationsachse
|
|
* \param base Vertexbasis der Rotationsachse
|
|
*/
|
|
void rotate_im_axis(double angle, vertex tip, vertex base) {
|
|
Mmn<double> mat_center(4);
|
|
Mmn<double> mat_reset(4);
|
|
|
|
mat_center.a(0,3)=-base[X];
|
|
mat_center.a(1,3)=-base[Y];
|
|
mat_center.a(2,3)=-base[Z];
|
|
|
|
mat_reset.a(0,3)=base[X];
|
|
mat_reset.a(1,3)=base[Y];
|
|
mat_reset.a(2,3)=base[Z];
|
|
|
|
// if(angle==0 || angle==180) {
|
|
// cout << "------------------------------\n";
|
|
// cout << "Winkel: " << angle << "Grad\n";
|
|
// t_mat.print();
|
|
// }
|
|
t_mat=mat_reset%mat_rot_axe(angle, (tip-base).get_t())%mat_center%t_mat;
|
|
// if(angle==0 || angle==180) {
|
|
// t_mat.print();
|
|
// cout << "------------------------------\n";
|
|
// }
|
|
}
|
|
// sowohl für translatio, als auch für Rotation sollte ich denke
|
|
// ich eigene Methoden für jede Richtung schreiben.!!!
|
|
};
|
|
|
|
#endif // __movable_h__
|