Angle.cpp

#include "Angle.h"


using namespace Robotics;
using namespace System;
using namespace System::Diagnostics;


/// 初期値を与えて生成する [ Constructor ]
Angle::Angle( double angle ) :
    m_angle( angle )
{
}

/// 初期値を与えて生成する [ Constructor ]
Angle::Angle( System::Decimal angle ) :
    m_angle( Decimal::ToDouble( angle ) )
{
}

/// XMLから生成する [ Constructor ]
Angle::Angle( System::Xml::XmlElement^ element )
{
    if( element != nullptr )
    {
        // 有効な要素ならば、属性から取得する
        double value = Double::Parse( element->GetAttribute( "initial" ) );

        // ... Radian に変換して設定する
        m_angle = CalculateRadian( value );
    }
    else
    {
        m_angle = 0.0;
    }
}


/// 符号を反転して返す [ Operator Overloading ]
Angle Angle::operator-()
{
    return Angle( -m_angle );
}


/// 等価演算子 == [ Operator Overloading ]
bool Angle::operator==( Angle% left, Angle% right )
{
    // 精度を 計算機イプシロンとして比較する
    return left.Equals( right, Double::Epsilon );
}

/// 不等価演算子 != [ Operator Overloading ]
bool Angle::operator!=( Angle% left, Angle% right )
{
    // 等価演算の否定を返す
    return !( left == right );
}

/// 値の等価を確認する
bool Angle::Equals( Angle% obj )
{
    // 精度を 計算機イプシロンとして比較する
    return Equals( obj, Double::Epsilon );
}

/// 値の等価を確認する
bool Angle::Equals( Angle% obj, double precision )
{
    // 差の絶対値を求める
    double remainder = Math::Abs( m_angle - obj.m_angle );

    // ... それが指定された精度以下ならば、等しいとみなす
    return ( remainder <= precision );
}


/// 和 += [ Operator Overloading ]
Angle Angle::operator+=( double value )
{
    m_angle += value;

    return *this;
}

/// 差 -= [ Operator Overloading ]
Angle Angle::operator-=( double value )
{
    m_angle -= value;

    return *this;
}


/// 積 *= [ Operator Overloading ]
Angle Angle::operator*=( double value )
{
    m_angle *= value;

    return *this;
}

/// 商 /= [ Operator Overloading ]
Angle Angle::operator/=( double value )
{
    m_angle /= value;

    return *this;
}


/// 和 + [ Operator Overloading ]
Angle Angle::operator+( Angle% obj, double value )
{
    Angle result( obj );
    result += value;

    return result;
}

/// 和 + [ Operator Overloading ]
Angle Angle::operator+( double value, Angle% obj )
{
    // 引数の順を入れ替えて、オーバーロードしている同一関数を呼び出す
    return( obj + value );
}

/// 和 + [ Operator Overloading ]
Angle Angle::operator+( Angle% left, Angle% right )
{
    Angle result( left );
    result += right;

    return result;
}


/// 差 - [ Operator Overloading ]
Angle Angle::operator-( Angle% obj, double value )
{
    Angle result( obj );
    result -= value;

    return result;
}

/// 差 - [ Operator Overloading ]
Angle Angle::operator-( double value, Angle% obj )
{
    // 引数の順を入れ替えて、オーバーロードしている同一関数を呼び出す
    Angle result( obj - value );

    // ... 符号を反転させて返す
    return( -result );
}

/// 差 - [ Operator Overloading ]
Angle Angle::operator-( Angle% left, Angle% right )
{
    Angle result( left );
    result -= right;

    return result;
}


/// 自身に近い方を返す
Angle% Angle::Near( Angle% reference1, Angle% reference2 )
{
    // 参照するそれぞれについて、自身との差を求める
    double difference1 = Math::Abs( reference1.m_angle - m_angle );
    double difference2 = Math::Abs( reference2.m_angle - m_angle );

    // ... 差が小さいほうを返す
    return( difference1 < difference2 )? reference1 : reference2;
}


/// Radian で表されているか?
bool Angle::IsExpressedByRadian( double angle )
{
    return ( angle >= -Math::PI )
        && ( angle <= +Math::PI );
}


/// Radian からDegree を求める
double Angle::CalculateDegree( double radian )
{
    return radian * ( 180.0 / Math::PI );
}

/// Degree からRadian を求める
double Angle::CalculateRadian( double degree )
{
    return degree * ( Math::PI / 180.0 );
}

/// Degree からRadian を求める
double Angle::CalculateRadian( System::Decimal degree )
{
    // double型で取得して 同一関数を呼び出す
    return CalculateRadian( Decimal::ToDouble( degree ) );
}


/// インスタンスの説明を文字列で返す
System::String^ Angle::ToString()
{
    return Degree.ToString( "0.0" );
}