// Copyright (C) 2012 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp #include #include #include #include #include #include #include template T NzApproach(T value, T objective, T increment) { if (value < objective) return std::min(value + increment, objective); else if (value > objective) return std::max(value - increment, objective); else return value; } template T NzClamp(T value, T min, T max) { if (value < min) return min; else if (value > max) return max; else return value; } template T NzDegrees(T degrees) { #if NAZARA_MATH_ANGLE_RADIAN return NzDegreeToRadian(degrees); #else return degrees; #endif } template T NzDegreeToRadian(T degrees) { return degrees * (M_PI/180.0); } unsigned int NzGetNumberLength(signed char number) { if (number == 0) return 1; return static_cast(std::log10(std::abs(number)))+(number < 0 ? 2 : 1); } unsigned int NzGetNumberLength(unsigned char number) { if (number == 0) return 1; return static_cast(std::log10(number))+1; } unsigned int NzGetNumberLength(short number) { if (number == 0) return 1; return static_cast(std::log10(std::abs(number)))+(number < 0 ? 2 : 1); } unsigned int NzGetNumberLength(unsigned short number) { if (number == 0) return 1; return static_cast(std::log10(number))+1; } unsigned int NzGetNumberLength(int number) { if (number == 0) return 1; return static_cast(std::log10(std::abs(number)))+(number < 0 ? 2 : 1); } unsigned int NzGetNumberLength(unsigned int number) { if (number == 0) return 1; return static_cast(std::log10(number))+1; } unsigned int NzGetNumberLength(long number) { if (number == 0) return 1; return static_cast(std::log10(std::abs(number)))+(number < 0 ? 2 : 1); } unsigned int NzGetNumberLength(unsigned long number) { if (number == 0) return 1; return static_cast(std::log10(number))+1; } unsigned int NzGetNumberLength(long long number) { if (number == 0) return 1; return static_cast(std::log10(std::abs(number)))+(number < 0 ? 2 : 1); } unsigned int NzGetNumberLength(unsigned long long number) { if (number == 0) return 1; return static_cast(std::log10(number))+1; } unsigned int NzGetNumberLength(float number, nzUInt8 precision) { // L'imprécision des flottants nécessite un cast (log10(9.99999) = 1) return NzGetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point } unsigned int NzGetNumberLength(double number, nzUInt8 precision) { // L'imprécision des flottants nécessite un cast (log10(9.99999) = 1) return NzGetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point } unsigned int NzGetNumberLength(long double number, nzUInt8 precision) { // L'imprécision des flottants nécessite un cast (log10(9.99999) = 1) return NzGetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point } template T NzNormalizeAngle(T angle) { #if NAZARA_MATH_ANGLE_RADIAN const T limit = M_PI; #else const T limit = 180.0; #endif ///TODO: Trouver une solution sans duplication if (angle > 0.0) { angle += limit; angle -= static_cast(angle/(2.0*limit))*(2.0*limit); angle -= limit; } else { angle -= limit; angle -= static_cast(angle/(2.0*limit))*(2.0*limit); angle += limit; } return angle; } template bool NzNumberEquals(T a, T b) { if (a > b) return (a-b) <= std::numeric_limits::epsilon(); else return (b-a) <= std::numeric_limits::epsilon(); } NzString NzNumberToString(long long number, nzUInt8 radix) { #if NAZARA_MATH_SAFE if (radix < 2 || radix > 36) { NazaraError("Base must be between 2 and 36"); return NzString(); } #endif if (number == 0) return '0'; static const char* symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; bool negative; if (number < 0) { negative = true; number = -number; } else negative = false; NzString str; str.Reserve(NzGetNumberLength(number)); do { str += symbols[number % radix]; number /= radix; } while (number > 0); if (negative) str += '-'; return str.Reversed(); } template T NzRadians(T radians) { #if NAZARA_MATH_ANGLE_RADIAN return radians; #else return NzRadianToDegree(radians); #endif } template T NzRadianToDegree(T radians) { return radians * (180.0/M_PI); } long long NzStringToNumber(NzString str, nzUInt8 radix, bool* ok) { #if NAZARA_MATH_SAFE if (radix < 2 || radix > 36) { NazaraError("Radix must be between 2 and 36"); if (ok) *ok = false; return 0; } #endif str.Simplify(); if (radix > 10) str.ToUpper(); bool negative = str.StartsWith('-'); static const char* symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char* digit = &str[(negative) ? 1 : 0]; unsigned long long total = 0; do { if (*digit == ' ') continue; total *= radix; const char* c = std::strchr(symbols, *digit); if (c && c-symbols < radix) total += c-symbols; else { NazaraError("str is not a valid number"); if (ok) *ok = false; return 0; } } while (*++digit); if (ok) *ok = true; return (negative) ? -static_cast(total) : total; } #include