Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/util/Math.cc @ 1791

Last change on this file since 1791 was 1791, checked in by landauf, 16 years ago

added comments to all my classes in util

  • Property svn:eol-style set to native
File size: 7.6 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file Math.cc
31    @brief Implementation of several math-functions.
32*/
33
34#include <OgrePlane.h>
35
36#include "Math.h"
37#include "Convert.h"
38
39/**
40    @brief Function for writing a Radian to a stream.
41*/
42std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian)
43{
44    out << radian.valueRadians();
45    return out;
46}
47
48/**
49    @brief Function for reading a Radian from a stream.
50*/
51std::istream& operator>>(std::istream& in, orxonox::Radian& radian)
52{
53    float temp;
54    in >> temp;
55    radian = temp;
56    return in;
57}
58
59/**
60    @brief Function for writing a Degree to a stream.
61*/
62std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree)
63{
64    out << degree.valueDegrees();
65    return out;
66}
67
68/**
69    @brief Function for reading a Degree from a stream.
70*/
71std::istream& operator>>(std::istream& in, orxonox::Degree& degree)
72{
73    float temp;
74    in >> temp;
75    degree = temp;
76    return in;
77}
78
79
80/**
81    @brief Gets the angle between my viewing direction and the direction to the position of the other object.
82    @param myposition My position
83    @param mydirection My viewing direction
84    @param otherposition The position of the other object
85    @return The angle
86
87    @example
88    If the other object is exactly in front of me, the function returns 0.
89    If the other object is exactly behind me, the function returns pi.
90    If the other object is exactly right/left to me (or above/below), the function returns pi/2.
91*/
92float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition)
93{
94    orxonox::Vector3 distance = otherposition - myposition;
95    float distancelength = distance.length();
96    if (distancelength == 0)
97        return 0;
98    else
99        return acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1));
100}
101
102/**
103    @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object.
104    @param myposition My position
105    @param mydirection My viewing direction
106    @param myorthonormal My orthonormalvector (pointing upwards through my head)
107    @param otherposition The position of the other object
108    @return The viewing direction
109
110    @example
111    If the other object is exactly in front of me, the function returns Vector2(0, 0).
112    If the other object is exactly at my left, the function returns Vector2(-1, 0).
113    If the other object is exactly at my right, the function returns Vector2(1, 0).
114    If the other object is only a bit at my right, the function still returns Vector2(1, 0).
115    If the other object is exactly above me, the function returns Vector2(0, 1).
116*/
117orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)
118{
119    orxonox::Vector3 distance = otherposition - myposition;
120
121    // project difference vector on our plane
122    orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);
123
124    float projectionlength = projection.length();
125    if (projectionlength == 0) return orxonox::Vector2(0, 0);
126    float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1));
127
128    if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)
129        return orxonox::Vector2(sin(angle), cos(angle));
130    else
131        return orxonox::Vector2(-sin(angle), cos(angle));
132}
133
134/**
135    @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object, multiplied with the viewing distance to the object (0° = 0, 180° = 1).
136    @param myposition My position
137    @param mydirection My viewing direction
138    @param myorthonormal My orthonormalvector (pointing upwards through my head)
139    @param otherposition The position of the other object
140    @return The viewing direction
141
142    @example
143    If the other object is exactly in front of me, the function returns Vector2(0, 0).
144    If the other object is exactly at my left, the function returns Vector2(-0.5, 0).
145    If the other object is exactly at my right, the function returns Vector2(0.5, 0).
146    If the other object is only a bit at my right, the function still returns Vector2(0.01, 0).
147    If the other object is exactly above me, the function returns Vector2(0, 0.5).
148*/
149orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)
150{
151    orxonox::Vector3 distance = otherposition - myposition;
152
153    // project difference vector on our plane
154    orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);
155
156    float projectionlength = projection.length();
157    if (projectionlength == 0) return orxonox::Vector2(0, 0);
158    float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1));
159
160    float distancelength = distance.length();
161    if (distancelength == 0) return orxonox::Vector2(0, 0);
162    float radius = acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1)) / Ogre::Math::PI;
163
164    if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)
165        return orxonox::Vector2(sin(angle) * radius, cos(angle) * radius);
166    else
167        return orxonox::Vector2(-sin(angle) * radius, cos(angle) * radius);
168}
169
170/**
171    @brief Returns the predicted position I have to aim at, if I want to hit a moving target with a moving projectile.
172    @param myposition My position
173    @param projectilespeed The speed of my projectile
174    @param targetposition The position of my target
175    @param targetvelocity The velocity of my target
176    @return The predicted position
177
178    The function predicts the position based on a linear velocity of the target. If the target changes speed or direction, the projectile will miss.
179*/
180orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity)
181{
182    float squaredProjectilespeed = projectilespeed * projectilespeed;
183    orxonox::Vector3 distance = targetposition - myposition;
184    float a = distance.squaredLength();
185    float b = 2 * (distance.x + distance.y + distance.z) * (targetvelocity.x + targetvelocity.y + targetvelocity.z);
186    float c = targetvelocity.squaredLength();
187
188    float temp = 4*squaredProjectilespeed*c + a*a - 4*b*c;
189    if (temp < 0)
190        return orxonox::Vector3::ZERO;
191
192    temp = sqrt(temp);
193    float time = (temp + a) / (2 * (squaredProjectilespeed - b));
194    return (targetposition + targetvelocity * time);
195}
196
197unsigned long getUniqueNumber()
198{
199    static unsigned long aNumber = 135;
200    return aNumber++;
201}
202
203std::string getUniqueNumberStr()
204{
205    return convertToString(getUniqueNumber());
206}
Note: See TracBrowser for help on using the repository browser.