class ref name: angle
category-group: math
layer: 1

synopsis.
The angle object ( angle_o ) is simple, standalone class designed to provide basic operations on angles. In addition to adding, subtracting, testing for equality, and assignment, one can convert between the units of measurement (degrees and radians), compute the concave or convex extent, and get the counter-clockwise angle. The value of the angle object is fetched as a type double.

description.
The default units of measurement (degrees or radians) can be set via the static function call angle_o::set_default_units() , so that all angle objects created afterwards will use [by default] the desired units.

Angles are measured in either degrees or radians. If, however, a new form of angle measurement is introduced (perhaps due to extraterrestrials explaining their measurement system), this class will be able to accomodate it.

member functions (primary)

angle_o()
SIGNATURE: angle_o ()
SYNOPSIS:
creates a a new angle object. The value of the angle value is initialized to 0, the units of measurement default to the global units of measurement (degrees, if the application has not set this via angle_o::set_default_units() . The angle is considered "unset", and hence cannot be [successfully] used [yet] in angular operations.
 

angle_o(angle_o)
SIGNATURE: angle_o (const angle_o &that)
SYNOPSIS:
copy constructor: creates a a new angle object which is an exact image of the copied angle object "that". If "that"'s angle has not been set prior, the current object will also be unset. This constructor is exactly equivalent to calling "reset()", then calling the "=" operator.
 

operator = (angle_o)
SIGNATURE: const angle_o &operator = (const angle_o &rhs)
SYNOPSIS:
copies exactly the RHS object ("rhs"), to the existing angle object instance. If the "rhs" object is not initialized, the current object will be set to a "not set" state, and the "last operation OK" flag will be unset (indicating that the last operation was not OK).
RETURNS: a reference to the current object
 

destructor
SIGNATURE: ~angle_o ()
SYNOPSIS: virtual destructor. The angle value is unset. All object contents are reinitialized to the at-construction state.
 

angle_o(<args>)
SIGNATURE: angle_o (double dv)
SYNOPSIS:
create a new angle object. The angle is set to the value given by "dv". The units of measurement is set to the default units, according to the global variable "g_default_units".
 

is_set()
SIGNATURE: boolean is_set () const
SYNOPSIS: tells if the object's angle value has been set or not. setting an angle can be accomplished by
RETURNS:
TRUE: the angle is set, its value can be used
FALSE: the angle is not set. fetching its value or using it is erronous.
 

is_lastop_ok()
SIGNATURE: boolean is_lastop_ok () const
SYNOPSIS: returns TRUE or FALSE, depending if last operation succeeded
DESCRIPTION:
Since many of the member functions of the angle object return a TRUE / FALSE indication, or the value of an angle, finding if an error occured must be done through another means. After an operation, call this routine to check if the operation succeeded.
The functions that set the flag used by this function include:

set_angle()
chek_angleset()
operator =()
clockwise_angle()
counterclockwise_angle()
concave_extent()
convex_extent()
All arithmetic operators (+, -, +=, -=) also set the flag. These operators also check the right-hand-side object, and if either object is uninitialized, both objects are set to an error state.
 

mode_is_radians()
SIGNATURE: boolean mode_is_radians () const
SYNOPSIS: if TRUE, then the unit of measurement of the angle is in radians.
RETURNS:
TRUE: the angle is set to be measured in radians.
FALSE: the angle is set to be measured in degrees.
 

mode_is_degrees()
SIGNATURE: boolean mode_is_degrees () const
SYNOPSIS: if TRUE, then the unit of measurement of the angle is in degrees.
RETURNS:
TRUE: the angle is set to be measured in degrees.
FALSE: the angle is set to be measured in radians.
 

value()
SIGNATURE: double value () const
SYNOPSIS:
returns the numerical value of the angle in the angle object. the value must be set, else the "last operation" flag is set to error and 0 is returned.
RETURNS: n: the angle value of the object. If 0, it may indicate an error, that the object angle value has not been set.
 

counterclockwise_angle()
SIGNATURE: double counterclockwise_angle (double other) const
SYNOPSIS:
this function returns the "extent" between the given angle and the object's value. The object's value must be set [prior] in order for this function to succeed.
DESCRIPTION:
This returns the difference between two angles. There are two possible answers, depending on which way you go: clockwise or counter-clockwise. This function handles the counter-clockwise case; "clockwise_angle()" handles the other case.
Example: if the units are in degrees, the angle is set to 90, and you provide an angle of 120, the difference in the counter-clockwise direction is 120 - 90, or 30 degrees. For the clockwise direction, it is (360 - 120) + 90, or, (240 + 90) = 330 degrees.
RETURNS: Value of the [counterclockwise] difference between "other" and the current object.
 

clockwise_angle()
SIGNATURE: double clockwise_angle (double) const
SYNOPSIS:
This function returns the difference between two angles, measured clockwise. See member function "counterclockwise_angle()" for a complete description. The object's value must be set [prior] in order for this function to succeed.
RETURNS: Value of the [clockwise] difference between "other" and the current object.
 

concave_extent()
SIGNATURE: double concave_extent (double other) const
SYNOPSIS:
This function returns the "larger range" between the angles "other" and the current object. The object's value must be set [prior] in order for this function to succeed. This function is the converse of "convex_extent()".
 

convex_extent()
SIGNATURE: double convex_extent (double) const
SYNOPSIS:
This function returns the "smaller range" between the angles "other" and the current object. The answer is no greater than 180 degrees (or its radian equivalent). The object's value must be set [prior] in order for this function to succeed. This function is the converse of "concave_extent()".
 

setunits_degrees()
SIGNATURE: int setunits_degrees ()
SYNOPSIS: sets the units of measurement for the object to degrees.
RETURNS: 0
 

setunits_radians()
SIGNATURE: int setunits_radians ()
SYNOPSIS: sets the units of measurement for the object to radians.
RETURNS: 0
 

toggle_degrad()
SIGNATURE: boolean toggle_degrad ()
SYNOPSIS: This changes the current output unit-of-measure mode, toggling it to degrees if it is set to radians, and vice-versa.
RETURNS:
TRUE: the angle object units is now set to radians (after this call)
FALSE: the angle object units is now set to degrees
 

set_angle()
SIGNATURE: int set_angle (double da)
SYNOPSIS: sets the object's angle to "da".
PARAMETERS

  • da: double-type variable, it's value is the angle to set the angle object to. The units for "da" must match that of the object.
  • RETURNS: 0
     

    set_default_units()
    SIGNATURE: int set_default_units (angle_flag, int * = NULL)
    SYNOPSIS:
    this is a static function (ie, call it like so:

    angle_o::set_default_units (angle_o::Units_Degrees);
    /* OR */
    angle_o::set_default_units (angle_o::Units_Radians);
    
    This sets the default units of measurement for all angle objects created subsequent to this call. If the application does not invoke this function, the default units will be in degrees.
    RETURNS:
    0: the default units of measurement was successfully set.
    -1: an error ocurred - you used a 'angle_flag' enumerated type that is not either 'Units_Degrees' or 'Units_Radians'.
     

    operator +()
    SIGNATURE: double operator + (double da)
    SYNOPSIS: This adds the extent given by input parameter "da" to the object's angle value, and returns the result
    RETURNS: double-type value, result of sum of [object value] + [da]
     

    operator -()
    SIGNATURE: double operator - (double da)
    SYNOPSIS: This subtracts the extent given by input parameter "da" from the object's angle value, and returns the result.
    RETURNS: double-type value, result of difference of [object value] - [da]
     

    operator +()
    SIGNATURE: double operator + (angle_o &rhs)
    SYNOPSIS:
    This returns the sum of the angles of two angle objects (as type double). Both angle objects must have valid values, or else the 'last operation failed' flag is marked in both objects (and 0.0 is returned). Its usage (and likewise for the corresponding "-" operator is like so:

    angle_o lhs (90), rhs (45);
    double answer = lhs + rhs;      // returns 135
    

    RETURNS: Value of the sum of two angle objects. Units used is that of the first (left) object.
     

    operator -()
    SIGNATURE: double operator - (angle_o &rhs)
    SYNOPSIS:
    This returns the difference of the angles of two angle objects (as type double). Both angle objects must have valid values. Example:

    double answer;
    angle_o lhs (90), rhs (50);
    answer = lhs - rhs;             // returns 40
    answer = rhs - lhs;             // returns -40
    

    RETURNS: Value of the difference of two angle objects. Units used is that of the first (left) object.
     

    operator +=()
    SIGNATURE: void operator += (double da)
    SYNOPSIS:
    Adds the value of input parameter "da" to the current value of the object. "da" should be a valid angle value, in the same units as the current object.
     

    operator -=()
    SIGNATURE: void operator -= (double da)
    SYNOPSIS:
    Subtracts the value of input parameter "da" from the current value of the object. "da" should be a valid angle value, in the same units as the current object.
     

    operator +=()
    SIGNATURE: void operator += (angle_o &rhs)
    SYNOPSIS:
    Adds the value of input parameter angle object "rhs" to the current value of the object. "rhs" must have been set prior in order for this operation to succeed.
     

    operator -=()
    SIGNATURE: void operator -= (angle_o &rhs)
    SYNOPSIS:
    Subtracts the value of input parameter angle object "rhs" from the current value of the object. "rhs" must have been set prior in order for this operation to succeed.
     

    reset()
    SIGNATURE: int reset ()
    SYNOPSIS: resets the angle object to its at-construction, default state. The angle value is unset.
    RETURNS: 0
     

    note.
    This class object is one of the older classes in the Z Directory, dating back to 1993-1994. The implementation of angular operations inside a class was rather experimental, but has been retained. This is admittedly an extremely simple class.

    examples.
    The following example is part of the class "validation" code, and should be sufficient to fully understand how to use the angle object. It applies an operation to angle object "A", then checks the result against what is expected. This process is repeated many times.

    Note that this is also a good example of how to write a validation function for the testdriver object.

    #include "stdafx.h"
    #include 
    #include "z_angle.h"
    #include "z_string.h"
    
    static int show_error (const string_o &where, const string_o &s);
    
    int main (int argc, char **argv)
    {
        int ie = 0;
    
        double val;
        angle_o::set_default_units (angle_o::Units_Radians);
        angle_o A, B(1.57), C;
        A.set_angle (1.57);
    
        if (A.value() != 1.57)              // [A = 1.57, B = 1.57]
            return show_error ("set_angle", "UNEXPECTED RADIAN VALUE");
    
        A -= B;                             // test: [A{1.57} - B{1.57} = 0]
        if (A.value() != 0)
            return show_error ("-=", "A -= B: RADIAN VALUE SHOULD BE 0");
    
        A += B;                             // [A -> 1.57]
        if (A.value() != 1.57)
            return show_error ("+=", "A += B: RADIAN VALUE SHOULD BE 1.57");
    
        if ((A + B) != 3.14)
            return show_error ("+=", "A{1.57} + B{1.57} != 3.14");
    
        A.toggle_degrad();                   // switch to degrees now
    
        std::cout << "counterclockwise A value = " << A.counterclockwise_angle(0);
        std::cout << std::endl;
        std::cout << "clockwise A value = " << A.clockwise_angle(0) << "\n";
    
        A.set_angle(30);
        std::cout << "convex  of 30 degrees = " << A.convex_extent(0)  << "\n";
        std::cout << "concave of 30 degrees = " << A.concave_extent(0) << "\n";
    
        return 0;
    }
    
    static int show_error (const string_o &where, const string_o &s)
    {
        std::cerr << "angle_o::" << where << "();" << s << std::endl;
        return -1;
    }
    

    bugs.
    The usage of checking for an error by calling a function such as "is_lastop_ok()" is similar to the unix technique of checking the global 'errno' variable. This class provides "is_lastop_ok()" for doing exactly that. This method of error handling has fallen into disfavor in the Z Directory. In the future, an "int *" error indicator parameter may be added to most of the functions, obviating the need for this function.

    history:   ??? 03/20/1994: code clean-up: canonical format {--GeG}