PositionVector.cpp

#include "PositionVector.h"


#include "Matrix.h"


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


/// [ Constructor ]
PositionVector::PositionVector() :
    Vector( DefaultDimension )
{
    Debug::Assert( IsInOrigin(), "原点に初期化されている" );
}

/// 成分から生成する [ Constructor ]
PositionVector::PositionVector( double x, double y, double z ) :
    Vector( DefaultDimension )
{
    this[ 1 ] = x;
    this[ 2 ] = y;
    this[ 3 ] = z;


    /// @note イベントを発生させないために、プロパティを用いていない
}

/// 成分から生成する [ Constructor ]
PositionVector::PositionVector( System::Decimal x, System::Decimal y, System::Decimal z ) :
    Vector( DefaultDimension )
{
    this[ 1 ] = Decimal::ToDouble( x );
    this[ 2 ] = Decimal::ToDouble( y );
    this[ 3 ] = Decimal::ToDouble( z );
}

/// ベクトルから生成する(次元数を確認するために、オーバーライドしている) [ Constructor ]
PositionVector::PositionVector( Vector^ vector ) :
    Vector( vector )
{
    Debug::Assert( Dimension == DefaultDimension, "既定の次元である" );
}

/// XMLから生成する [ Constructor ]
PositionVector::PositionVector( System::Xml::XmlElement^ element ) :
    Vector( DefaultDimension )
{
    // 要素を取得する
    Xml::XmlElement^ node = element[ "position" ];

    if( node != nullptr )
    {
        // 取得できたならば、属性から設定する
        this[ 1 ] = Double::Parse( node->GetAttribute( "x" ) );
        this[ 2 ] = Double::Parse( node->GetAttribute( "y" ) );
        this[ 3 ] = Double::Parse( node->GetAttribute( "z" ) );
    }
}


/// 和 + [ Operator Overloading ]
PositionVector^ PositionVector::operator+( PositionVector^ left, PositionVector^ right )
{
    PositionVector^ result = gcnew PositionVector( left );
    result += right;

    return result;
}

/// 和 + [ Operator Overloading ]
PositionVector^ PositionVector::operator+( PositionVector^ positionVector, Vector^ vector )
{
    Debug::Assert( vector->Dimension == DefaultDimension, "引数のベクトルは 既定の次元である" );

    PositionVector^ result = gcnew PositionVector( positionVector );
    result += vector;

    return result;
}

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


/// 差 - [ Operator Overloading ]
PositionVector^ PositionVector::operator-( PositionVector^ left, PositionVector^ right )
{
    PositionVector^ result = gcnew PositionVector( left );
    result -= right;

    return result;
}

/// 差 - [ Operator Overloading ]
PositionVector^ PositionVector::operator-( PositionVector^ positionVector, Vector^ vector )
{
    Debug::Assert( vector->Dimension == DefaultDimension, "引数のベクトルは 既定の次元である" );


    PositionVector^ result = gcnew PositionVector( positionVector );
    result -= vector;

    return result;
}

/// 積 * [ Operator Overloading ]
PositionVector^ PositionVector::operator*( PositionVector^ positionVector, double scalar )
{
    PositionVector^ result = gcnew PositionVector( positionVector );
    result *= scalar;

    return result;
}

/// 積 * [ Operator Overloading ]
PositionVector^ PositionVector::operator*( double scalar, PositionVector^ positionVector )
{
    // 引数の順を入れ替えて、オーバーロードしている同一関数を呼び出す
    return positionVector * scalar;
}

/// 積 * (位置ベクトルを回転させる) [ Operator Overloading ]
PositionVector^ PositionVector::operator*( Matrix^ rotationMatrix, PositionVector^ positionVector )
{
    return gcnew PositionVector( rotationMatrix * safe_cast< Vector^ >( positionVector ) );
}


/// 商 / [ Operator Overloading ]
PositionVector^ PositionVector::operator/( PositionVector^ positionVector, double scalar )
{
    PositionVector^ result = gcnew PositionVector( positionVector );
    result /= scalar;

    return result;
}


/// X方向の位置を設定する [ Property ]
void PositionVector::X::set( double value )
{
    if( this[ 1 ] != value )
    {
        // 現在の値と異なるならば、設定する
        this[ 1 ] = value;

        // ... 値の変更イベントを発生する
        ValueChanged( this, gcnew System::EventArgs() );
    }
}

/// Y方向の位置を設定する [ Property ]
void PositionVector::Y::set( double value )
{
    if( this[ 2 ] != value )
    {
        // 現在の値と異なるならば、設定する
        this[ 2 ] = value;

        // ... 値の変更イベントを発生する
        ValueChanged( this, gcnew System::EventArgs() );
    }
}

/// Z方向の位置を設定する [ Property ]
void PositionVector::Z::set( double value )
{
    if( this[ 3 ] != value )
    {
        // 現在の値と異なるならば、設定する
        this[ 3 ] = value;

        // ... 値の変更イベントを発生する
        ValueChanged( this, gcnew System::EventArgs() );
    }
}


/// インスタンスの説明を文字列で返す
String^ PositionVector::ToString()
{
    return String::Format( "{0:0.000} {1:0.000} {2:0.000}", X, Y, Z );
}


/// インスタンスの説明をXMLで返す
System::Xml::XmlElement^ PositionVector::ToXml( System::Xml::XmlDocument^ document )
{
    // ルートを生成する
    Xml::XmlElement^ root = document->CreateElement( "position" );

    // ... フィールドを属性として設定する
    root->SetAttribute( "x", X.ToString() );
    root->SetAttribute( "y", Y.ToString() );
    root->SetAttribute( "z", Z.ToString() );

    return root;
}