00001 /* ResidualVM - A 3D game interpreter 00002 * 00003 * ResidualVM is the legal property of its developers, whose names 00004 * are too numerous to list here. Please refer to the COPYRIGHT 00005 * file distributed with this source distribution. 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU General Public License 00009 * as published by the Free Software Foundation; either version 2 00010 * of the License, or (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00020 * 00021 */ 00022 00023 #include "common/streamdebug.h" 00024 #include "common/math.h" 00025 00026 #include "math/angle.h" 00027 00028 namespace Math { 00029 00030 Angle::Angle(float degrees) : 00031 _degrees(degrees) { 00032 } 00033 00034 Angle::Angle(const Angle &a) : 00035 _degrees(a._degrees) { 00036 00037 } 00038 00039 Angle &Angle::normalize(float low) { 00040 _degrees = getDegrees(low); 00041 00042 return *this; 00043 } 00044 00045 Angle &Angle::clampDegrees(float mag) { 00046 _degrees = getDegrees(-180.f); 00047 if (_degrees >= mag) 00048 setDegrees(mag); 00049 if (_degrees <= -mag) 00050 setDegrees(-mag); 00051 00052 return *this; 00053 } 00054 00055 Angle &Angle::clampDegrees(float min, float max) { 00056 _degrees = getDegrees(-180.f); 00057 if (_degrees >= max) 00058 setDegrees(max); 00059 if (_degrees <= min) 00060 setDegrees(min); 00061 00062 return *this; 00063 } 00064 00065 void Angle::setDegrees(float degrees) { 00066 _degrees = degrees; 00067 } 00068 00069 void Angle::setRadians(float radians) { 00070 _degrees = Common::rad2deg(radians); 00071 } 00072 00073 float Angle::getDegrees() const { 00074 return _degrees; 00075 } 00076 00077 float Angle::getRadians() const { 00078 return Common::deg2rad(getDegrees()); 00079 } 00080 00081 float Angle::getDegrees(float low) const { 00082 float degrees = _degrees; 00083 if (degrees >= low + 360.f) { 00084 float x = floor((degrees - low) / 360.f); 00085 degrees -= 360.f * x; 00086 } else if (degrees < low) { 00087 float x = floor((degrees - low) / 360.f); 00088 degrees -= 360.f * x; 00089 } 00090 return degrees; 00091 } 00092 00093 float Angle::getRadians(float low) const { 00094 float d = getDegrees(low); 00095 return Common::deg2rad(d); 00096 } 00097 00098 float Angle::getCosine() const { 00099 return cosf(getRadians()); 00100 } 00101 00102 float Angle::getSine() const { 00103 return sinf(getRadians()); 00104 } 00105 00106 float Angle::getTangent() const { 00107 return tanf(getRadians()); 00108 } 00109 00110 Angle &Angle::operator=(const Angle &a) { 00111 _degrees = a._degrees; 00112 00113 return *this; 00114 } 00115 00116 Angle &Angle::operator=(float degrees) { 00117 setDegrees(degrees); 00118 00119 return *this; 00120 } 00121 00122 Angle &Angle::operator+=(const Angle &a) { 00123 setDegrees(_degrees + a._degrees); 00124 00125 return *this; 00126 } 00127 00128 Angle &Angle::operator+=(float degrees) { 00129 setDegrees(_degrees + degrees); 00130 00131 return *this; 00132 } 00133 00134 Angle &Angle::operator-=(const Angle &a) { 00135 setDegrees(_degrees - a._degrees); 00136 00137 return *this; 00138 } 00139 00140 Angle &Angle::operator-=(float degrees) { 00141 setDegrees(_degrees - degrees); 00142 00143 return *this; 00144 } 00145 00146 Angle Angle::fromRadians(float radians) { 00147 return Angle(Common::rad2deg(radians)); 00148 } 00149 00150 Angle Angle::arcCosine(float x) { 00151 Angle a; 00152 a.setRadians(acosf(x)); 00153 return a; 00154 } 00155 00156 Angle Angle::arcSine(float x) { 00157 Angle a; 00158 a.setRadians(asinf(x)); 00159 return a; 00160 } 00161 00162 Angle Angle::arcTangent(float x) { 00163 Angle a; 00164 a.setRadians(atanf(x)); 00165 return a; 00166 } 00167 00168 Angle Angle::arcTangent2(float y, float x) { 00169 Angle a; 00170 a.setRadians(atan2f(y, x)); 00171 return a; 00172 } 00173 00174 Common::Debug &operator<<(Common::Debug &dbg, const Math::Angle &a) { 00175 dbg.nospace() << "Angle(" << a.getDegrees(-180) << ")"; 00176 00177 return dbg.space(); 00178 } 00179 00180 }