Changeset 7421 for sandbox_qt/src/libraries/util/Math.cc
- Timestamp:
- Sep 12, 2010, 12:47:30 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sandbox_qt/src/libraries/util/Math.cc
r7401 r7421 34 34 #include "Math.h" 35 35 36 #include <OgrePlane.h>37 38 #include "MathConvert.h"39 #include "SubString.h"40 // Do not remove this include, it avoids linker errors.41 #include "mbool.h"42 43 36 namespace orxonox 44 37 { 45 #if OGRE_VERSION < 0x01060346 /**47 @brief Function for writing a Radian to a stream.48 */49 std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian)50 {51 out << radian.valueRadians();52 return out;53 }54 55 /**56 @brief Function for writing a Degree to a stream.57 */58 std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree)59 {60 out << degree.valueDegrees();61 return out;62 }63 #endif64 65 /**66 @brief Function for reading a Radian from a stream.67 */68 std::istream& operator>>(std::istream& in, orxonox::Radian& radian)69 {70 float temp;71 in >> temp;72 radian = temp;73 return in;74 }75 76 /**77 @brief Function for reading a Degree from a stream.78 */79 std::istream& operator>>(std::istream& in, orxonox::Degree& degree)80 {81 float temp;82 in >> temp;83 degree = temp;84 return in;85 }86 87 88 /**89 @brief Gets the angle between my viewing direction and the direction to the position of the other object.90 @param myposition My position91 @param mydirection My viewing direction92 @param otherposition The position of the other object93 @return The angle in radian94 95 Examples:96 - If the other object is exactly in front of me, the function returns 0.97 - If the other object is exactly behind me, the function returns pi.98 - If the other object is exactly right/left to me (or above/below), the function returns pi/2.99 */100 float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition)101 {102 orxonox::Vector3 distance = otherposition - myposition;103 float distancelength = distance.length();104 if (distancelength == 0)105 return 0;106 else107 return acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1));108 }109 110 /**111 @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object.112 @param myposition My position113 @param mydirection My viewing direction114 @param myorthonormal My orthonormalvector (pointing upwards through my head)115 @param otherposition The position of the other object116 @return The viewing direction117 118 Examples:119 - If the other object is exactly in front of me, the function returns <tt>Vector2(0, 0)</tt>.120 - If the other object is exactly at my left, the function returns <tt>Vector2(-1, 0)</tt>.121 - If the other object is exactly at my right, the function returns <tt>Vector2(1, 0)</tt>.122 - If the other object is only a bit at my right, the function still returns <tt>Vector2(1, 0)</tt>.123 - If the other object is exactly above me, the function returns <tt>Vector2(0, 1)</tt>.124 */125 orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)126 {127 orxonox::Vector3 distance = otherposition - myposition;128 129 // project difference vector on our plane130 orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);131 132 float projectionlength = projection.length();133 if (projectionlength == 0)134 {135 if (myposition.dotProduct(otherposition) >= 0)136 return orxonox::Vector2(0, 0);137 else138 return orxonox::Vector2(0, 1);139 }140 141 float cos_value = clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1);142 float sin_value = sqrt( 1 - cos_value*cos_value );143 144 if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)145 return orxonox::Vector2( sin_value, cos_value );146 else147 return orxonox::Vector2( -sin_value, cos_value );148 }149 150 /**151 @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).152 @param myposition My position153 @param mydirection My viewing direction154 @param myorthonormal My orthonormalvector (pointing upwards through my head)155 @param otherposition The position of the other object156 @return The viewing direction157 158 Examples:159 - If the other object is exactly in front of me, the function returns <tt>Vector2(0, 0)</tt>.160 - If the other object is exactly at my left, the function returns <tt>Vector2(-0.5, 0)</tt>.161 - If the other object is exactly at my right, the function returns <tt>Vector2(0.5, 0)</tt>.162 - If the other object is only a bit at my right, the function still returns <tt>Vector2(0.01, 0)</tt>.163 - If the other object is exactly above me, the function returns <tt>Vector2(0, 0.5)</tt>.164 */165 orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)166 {167 orxonox::Vector3 distance = otherposition - myposition;168 169 // project difference vector on our plane170 orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);171 172 float projectionlength = projection.length();173 if (projectionlength == 0)174 {175 if (myposition.dotProduct(otherposition) >= 0)176 return orxonox::Vector2(0, 0);177 else178 return orxonox::Vector2(0, 1);179 }180 //float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1));181 182 float cos_value = clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1);183 float sin_value = sqrt( 1 - cos_value*cos_value );184 185 float distancelength = distance.length();186 if (distancelength == 0) return orxonox::Vector2(0, 0);187 float radius = acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1)) / math::pi;188 189 if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)190 return orxonox::Vector2( sin_value * radius, cos_value * radius);191 else192 return orxonox::Vector2( -sin_value * radius, cos_value * radius);193 }194 195 /**196 @brief Returns the predicted position I have to aim at, if I want to hit a moving target with a moving projectile.197 @param myposition My position198 @param projectilespeed The speed of my projectile199 @param targetposition The position of my target200 @param targetvelocity The velocity of my target201 @return The predicted position202 203 The function predicts the position based on a linear velocity of the target. If the target changes speed or direction, the projectile will miss.204 */205 orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity)206 {207 float squaredProjectilespeed = projectilespeed * projectilespeed;208 orxonox::Vector3 distance = targetposition - myposition;209 float a = distance.squaredLength();210 float b = 2 * (distance.x + distance.y + distance.z) * (targetvelocity.x + targetvelocity.y + targetvelocity.z);211 float c = targetvelocity.squaredLength();212 213 float temp = 4*squaredProjectilespeed*c + a*a - 4*b*c;214 if (temp < 0)215 return orxonox::Vector3::ZERO;216 217 temp = sqrt(temp);218 float time = (temp + a) / (2 * (squaredProjectilespeed - b));219 return (targetposition + targetvelocity * time);220 }221 222 38 /** 223 39 @brief Returns a unique number. This function will never return the same value twice. … … 228 44 return aNumber++; 229 45 } 230 231 232 //////////////////////////233 // Conversion functions //234 //////////////////////////235 236 // std::string to Vector2237 bool ConverterFallback<std::string, orxonox::Vector2>::convert(orxonox::Vector2* output, const std::string& input)238 {239 size_t opening_parenthesis, closing_parenthesis = input.find('}');240 if ((opening_parenthesis = input.find('{')) == std::string::npos)241 opening_parenthesis = 0;242 else243 opening_parenthesis++;244 245 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),246 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');247 if (tokens.size() >= 2)248 {249 if (!convertValue(&(output->x), tokens[0]))250 return false;251 if (!convertValue(&(output->y), tokens[1]))252 return false;253 254 return true;255 }256 return false;257 }258 259 // std::string to Vector3260 bool ConverterFallback<std::string, orxonox::Vector3>::convert(orxonox::Vector3* output, const std::string& input)261 {262 size_t opening_parenthesis, closing_parenthesis = input.find('}');263 if ((opening_parenthesis = input.find('{')) == std::string::npos)264 opening_parenthesis = 0;265 else266 opening_parenthesis++;267 268 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),269 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');270 if (tokens.size() >= 3)271 {272 if (!convertValue(&(output->x), tokens[0]))273 return false;274 if (!convertValue(&(output->y), tokens[1]))275 return false;276 if (!convertValue(&(output->z), tokens[2]))277 return false;278 279 return true;280 }281 return false;282 }283 284 // std::string to Vector4285 bool ConverterFallback<std::string, orxonox::Vector4>::convert(orxonox::Vector4* output, const std::string& input)286 {287 size_t opening_parenthesis, closing_parenthesis = input.find('}');288 if ((opening_parenthesis = input.find('{')) == std::string::npos)289 opening_parenthesis = 0;290 else291 opening_parenthesis++;292 293 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),294 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');295 if (tokens.size() >= 4)296 {297 if (!convertValue(&(output->x), tokens[0]))298 return false;299 if (!convertValue(&(output->y), tokens[1]))300 return false;301 if (!convertValue(&(output->z), tokens[2]))302 return false;303 if (!convertValue(&(output->w), tokens[3]))304 return false;305 306 return true;307 }308 return false;309 }310 311 // std::string to Quaternion312 bool ConverterFallback<std::string, orxonox::Quaternion>::convert(orxonox::Quaternion* output, const std::string& input)313 {314 size_t opening_parenthesis, closing_parenthesis = input.find('}');315 if ((opening_parenthesis = input.find('{')) == std::string::npos)316 opening_parenthesis = 0;317 else318 opening_parenthesis++;319 320 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');321 if (tokens.size() >= 4)322 {323 if (!convertValue(&(output->w), tokens[0]))324 return false;325 if (!convertValue(&(output->x), tokens[1]))326 return false;327 if (!convertValue(&(output->y), tokens[2]))328 return false;329 if (!convertValue(&(output->z), tokens[3]))330 return false;331 332 return true;333 }334 return false;335 }336 337 // std::string to ColourValue338 bool ConverterFallback<std::string, orxonox::ColourValue>::convert(orxonox::ColourValue* output, const std::string& input)339 {340 size_t opening_parenthesis, closing_parenthesis = input.find('}');341 if ((opening_parenthesis = input.find('{')) == std::string::npos)342 opening_parenthesis = 0;343 else344 opening_parenthesis++;345 346 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');347 if (tokens.size() >= 3)348 {349 if (!convertValue(&(output->r), tokens[0]))350 return false;351 if (!convertValue(&(output->g), tokens[1]))352 return false;353 if (!convertValue(&(output->b), tokens[2]))354 return false;355 if (tokens.size() >= 4)356 {357 if (!convertValue(&(output->a), tokens[3]))358 return false;359 }360 else361 output->a = 1.0;362 363 return true;364 }365 return false;366 }367 46 }
Note: See TracChangeset
for help on using the changeset viewer.