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;
}