GY-63_MS5611/libraries/Angle/Angle.cpp

202 lines
3.8 KiB
C++
Raw Normal View History

2015-08-01 14:36:28 -04:00
//
// FILE: Angle.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.02
2015-08-01 14:36:28 -04:00
// PURPOSE: library for Angle math for Arduino
2015-08-01 14:44:45 -04:00
// URL:
2015-08-01 14:36:28 -04:00
//
// Released to the public domain
//
// 0.1.02 - added toRadians() + fix compare()
2015-08-01 14:44:45 -04:00
// 0.1.01 - cleanup a bit
2015-08-01 14:36:28 -04:00
// 0.1.00 - initial version
// ideas: - http://forum.arduino.cc/index.php?topic=94507.0
// wind directions
// bandit at 12 hr
// more precise sin(a + b) ?
// a = degrees, b = minutes+sec+thou?
//
2015-08-01 14:36:28 -04:00
#include "Angle.h"
Angle::Angle(const double alpha)
{
double a = alpha;
bool neg = (alpha < 0);
if (neg) a = -a;
2015-08-01 14:44:45 -04:00
2015-08-01 14:36:28 -04:00
d = int(a);
a = a - d;
2015-08-01 14:44:45 -04:00
// unsigned long p = a * 3600000L;
// 3600 000 = 2^7 • 3^2 • 5^5 = 128 * 28125
// 2^7 = 128 will only affect exponent - no loss precision
// 28125 is less digits so less loss of significant digits.
a = a * 128;
unsigned long p = round(a * 28125);
2015-08-01 14:36:28 -04:00
t = p % 1000UL;
p = (p - t)/1000UL;
s = p % 60UL;
m = (p - s)/60UL;
2015-08-01 14:44:45 -04:00
2015-08-01 14:36:28 -04:00
if (neg) d = -d;
}
// PRINTING
size_t Angle::printTo(Print& p) const
{
size_t n = 0;
n += p.print(d);
n += p.print('.');
2015-08-01 14:44:45 -04:00
if (m < 10) n += p.print('0');
n += p.print(m);
2015-08-01 14:36:28 -04:00
n += p.print('\'');
2015-08-01 14:44:45 -04:00
if (s < 10) n += p.print('0');
n += p.print(s);
2015-08-01 14:36:28 -04:00
n += p.print('\"');
2015-08-01 14:44:45 -04:00
if (t < 100) n += p.print('0');
if (t < 10) n += p.print('0');
2015-08-01 14:36:28 -04:00
n += p.print(t);
2015-08-01 14:44:45 -04:00
2015-08-01 14:36:28 -04:00
return n;
};
double Angle::toDouble(void)
{
2015-08-01 14:44:45 -04:00
long v = t + s * 1000UL + m * 60000UL;
2015-08-01 14:36:28 -04:00
double val = ((1.0 / 28125.0) / 128) * v + d;
return val;
}
// BASIC MATH
2015-08-01 14:44:45 -04:00
Angle Angle::operator + (const Angle &a)
2015-08-01 14:36:28 -04:00
{
2015-08-01 14:44:45 -04:00
return addHelper(a);
2015-08-01 14:36:28 -04:00
}
2015-08-01 14:44:45 -04:00
Angle& Angle::operator += (const Angle &a)
2015-08-01 14:36:28 -04:00
{
2015-08-01 14:44:45 -04:00
*this = addHelper(a);
return *this;
2015-08-01 14:36:28 -04:00
}
2015-08-01 14:44:45 -04:00
Angle Angle::addHelper(const Angle &a)
2015-08-01 14:36:28 -04:00
{
Angle temp = *this;
if (sign(temp.d) == sign(a.d))
{
temp.d += a.d;
temp.m += a.m;
temp.s += a.s;
temp.t += a.t;
}
2015-08-01 14:44:45 -04:00
else
2015-08-01 14:36:28 -04:00
{
temp.d = sign(temp.d) * (abs(temp.d) - abs(a.d));
2015-08-01 14:36:28 -04:00
temp.m -= a.m;
temp.s -= a.s;
temp.t -= a.t;
}
temp.normalize();
2015-08-01 14:44:45 -04:00
return temp;
2015-08-01 14:36:28 -04:00
}
Angle Angle::operator - (const Angle &a)
{
return subHelper(a);
2015-08-01 14:36:28 -04:00
}
Angle& Angle::operator -= (const Angle &a)
{
*this = subHelper(a);
return *this;
}
Angle Angle::subHelper(const Angle &a)
2015-08-01 14:36:28 -04:00
{
Angle temp = *this;
if (sign(temp.d) == sign(a.d))
{
temp.d -= a.d;
temp.m -= a.m;
temp.s -= a.s;
temp.t -= a.t;
}
2015-08-01 14:44:45 -04:00
else
2015-08-01 14:36:28 -04:00
{
temp.d = sign(temp.d) * (abs(temp.d) + abs(a.d));
temp.m += a.m;
temp.s += a.s;
temp.t += a.t;
}
temp.normalize();
return temp;
}
Angle Angle::operator * (const double dd)
{
return Angle(this->toDouble() * dd);
}
Angle Angle::operator / (const double dd)
{
return Angle(this->toDouble() / dd);
}
Angle& Angle::operator *= (const double dd)
{
*this = this->toDouble() * dd;
2015-08-01 14:36:28 -04:00
return *this;
}
Angle& Angle::operator /= (const double dd)
{
*this = this->toDouble() / dd;
2015-08-01 14:36:28 -04:00
return *this;
}
double Angle::operator / (Angle& a)
{
double f = this->toDouble();
double g = a.toDouble();
return f/g;
}
2015-08-01 14:36:28 -04:00
///////////////////////////////////////////////////////////
//
// PRIVATE
//
int Angle::compare(const Angle &a, const Angle &b)
{
if (a.d > b.d) return 1;
if (a.d < b.d) return -1;
if (a.m > b.m) return 1;
if (a.m < b.m) return -1;
if (a.s > b.s) return 1;
if (a.s < b.s) return -1;
if (a.t > b.t) return 1;
if (a.t < b.t) return -1;
2015-08-01 14:36:28 -04:00
return 0;
}
void Angle::normalize()
{
bool neg = (d < 0);
if (neg) d = -d;
while (t < 0) { s--; t += 1000; }
while (t >= 1000) { s++; t -= 1000; }
while (s < 0) { m--; s += 60; }
while (s >= 60) { m++; s -= 60; }
while (m < 0) { d--; m += 60; }
while (m >= 60) { d++; m -= 60; }
if (neg) d = -d;
}
2015-08-01 14:44:45 -04:00
int Angle::sign(int d)
2015-08-01 14:36:28 -04:00
{
return (d < 0?-1:1);
}
// --- END OF FILE ---