/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2017 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * * without restriction, including without limitation the rights to use, copy, modify, * * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to the following * * conditions: * * * * The above copyright notice and this permission notice shall be included in all copies * * or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ #include namespace openspace { namespace globebrowsing { template const T Angle::PI = 3.14159265358979323846264338327950; template const T Angle::EPSILON = 1e-10; // Should depend on the typedef /eb ////////////////////////////////////////////////////////////////////////////////////////// // STATIC CONSTANTS // ////////////////////////////////////////////////////////////////////////////////////////// template const Angle Angle::ZERO = Angle::fromRadians(0); template const Angle Angle::QUARTER = Angle::fromRadians(PI/2); template const Angle Angle::HALF = Angle::fromRadians(PI); template const Angle Angle::FULL = Angle::fromRadians(2*PI); ////////////////////////////////////////////////////////////////////////////////////////// // Constructors // ////////////////////////////////////////////////////////////////////////////////////////// template Angle::Angle(const Angle& other) : _radians(other._radians) { } template Angle::Angle(T radians) : _radians(radians) { } ////////////////////////////////////////////////////////////////////////////////////////// // Factory Methods // ////////////////////////////////////////////////////////////////////////////////////////// template Angle Angle::fromRadians(T rads) { return Angle(rads); } template Angle Angle::fromDegrees(T degrees) { return Angle(degrees * PI / 180.0); } template Angle Angle::fromRevolutions(T revs) { return Angle(revs * 2 * PI); } ////////////////////////////////////////////////////////////////////////////////////////// // Conversions // ////////////////////////////////////////////////////////////////////////////////////////// template T Angle::asRadians() const { return _radians; } template T Angle::asDegrees() const { return _radians * 180.0 / PI; } template T Angle::asRevolutions() const { return _radians / (2 * PI); } ////////////////////////////////////////////////////////////////////////////////////////// // Operators // ////////////////////////////////////////////////////////////////////////////////////////// template Angle Angle::operator+(const Angle& rhs) const{ return Angle(_radians + rhs._radians); } template Angle Angle::operator-(const Angle& rhs) const{ return Angle(_radians - rhs._radians); } template Angle Angle::operator*(T multiplier) const{ return Angle(_radians * multiplier); } template Angle Angle::operator/(T divisor) const{ return Angle(_radians / divisor); } template Angle Angle::operator-() const { return Angle(-_radians); } template void Angle::operator+=(const Angle& rhs){ _radians += rhs._radians; } template void Angle::operator-=(const Angle& rhs){ _radians -= rhs._radians; } template void Angle::operator*=(T multiplier){ _radians *= multiplier; } template void Angle::operator/=(T divisor){ _radians /= divisor; } template bool Angle::operator<(const Angle& rhs) const{ return _radians < rhs._radians; } template bool Angle::operator<=(const Angle& rhs) const{ return _radians <= rhs._radians; } template bool Angle::operator>(const Angle& rhs) const{ return _radians > rhs._radians; } template bool Angle::operator>=(const Angle& rhs) const{ return _radians >= rhs._radians; } template bool Angle::operator==(const Angle& rhs) const{ return _radians == rhs._radians; } template bool Angle::operator!=(const Angle& rhs) const{ return _radians != rhs._radians; } ////////////////////////////////////////////////////////////////////////////////////////// // Chainable Relative Mutators // ////////////////////////////////////////////////////////////////////////////////////////// template Angle& Angle::normalize() { // this will cause _radians to be in value range ]-2pi, 2pi[ _radians = fmod(_radians, 2*PI); // ensure _radians are positive, ie in value range [0, 2pi[ if (_radians < 0.0){ _radians += 2 * PI; } return *this; } template Angle& Angle::normalizeAround(const Angle& center) { _radians -= center._radians + PI; normalize(); _radians += center._radians - PI; return *this; } template Angle& Angle::clamp(const Angle& min, const Angle& max) { _radians = _radians < min._radians ? min._radians : _radians > max._radians ? max._radians : _radians; return *this; } template Angle& Angle::abs(){ _radians = glm::abs(_radians); return *this; } ////////////////////////////////////////////////////////////////////////////////////////// // Chainable Relative Factory Methods // ////////////////////////////////////////////////////////////////////////////////////////// template Angle Angle::getNormalized() const { return Angle(*this).normalize(); } template Angle Angle::getNormalizedAround(const Angle& center) const { return Angle(*this).normalizeAround(center); } template Angle Angle::getClamped(const Angle& min, const Angle& max) const { return Angle(*this).clamp(min, max); } template Angle Angle::getAbs() const { return Angle(*this).abs(); } } // namespace globebrowsing } // namespace openspace