I want to do a angle class to be initialized in radians or degrees but i don't know if it is a good idea. I'm thinking about something like this:
class Radian;
class Degree;
/**
* My angle class.
**/
class Angle
{
private:
float m_radian;
public:
explicit Angle(const Radian& rad);
explicit Angle(const Degree& deg);
float GetRadian(void) const
{
return this->m_radian;
}
float GetDegree(void) const
{
return ToDegree(this->m_radian);
}
bool IsEqual(const Angle& angle, float epsilon = 0.001f) const
{
return Abs<float>(this->m_radian - angle.m_radian) < epsilon;
}
void Set(const Angle& ang);
protected:
Angle(void) : m_radian(0.0f)
{}
Angle(float rad) : m_radian(rad)
{}
};
class Radian : public Angle
{
public:
Radian(void)
{}
Radian(float r) : Angle(r)
{}
};
class Degree : public Angle
{
public:
Degree(void)
{}
Degree(float d) : Angle(ToRadian(d))
{}
};
/// Trigonometric functions.
float Sin(const Angle& angle);
...
This way i won't confuse radian and degrees in my code. But, is this a good idea or i should use other design?
or angle in radians (theta) is arc length (s) divided by radius (r). A circle has 360 degrees or 2pi radians — going all the way around is 2 * pi * r / r. So a radian is about 360 /(2 * pi) or 57.3 degrees.
One radian is defined as the angle subtended from the centre of a circle which intercepts an arc equal in length to the radius of the circle.
If we draw two straight lines that cross at the centre of a circle such that the length of the circumference between them (an arc) equals the radius, then the angle between these lines is 1 radian. The angular circumference of a circle is 2π radians, or 360 degrees, so that: 1 radian = 360/2π degrees = 57o 17' 44.8”.
You don't need any inheritance at all here. Once the objects are constructed, you don't care about the difference anymore - they behave exactly the same. So the only problem you've got to solve is how to make constructing Angle
objects in a readable way.
The usual solution to this is to use named constructors:
class Angle
{
public:
static Angle fromRadians( float v );
static Angle fromDegrees( float v );
// ...
private:
Angle( float rad );
// ...
};
Instead of invoking the constructor directly, you provide factory functions which expressive names. So you write:
void f( Angle::fromDegrees( 3.0 ), Angle::fromRadians( 17.0 ) );
I don't see the need for inheritance here. As far as using your class is concerned, all that matters is that you get an angle - whether it was in degrees or radians to start with is irrelevant.
Disclaimer: I've done this before. Exactly the same use case. My solution was to make the constructor take two arguments: a number and a unit enum. I'd use my class like so:
Angle a(1.2345, Angle::Radians);
std::cout << a.radians() << a.degrees() << sin(a);
If you want convenience methods to create angles from common units, they could be just that: helper methods. No need for separate classes.
Angle r = Radians(2.3);
Angle d = Degrees(180);
Anyway - just what I've been happy using in the past. Hope it helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With