#if !defined(AFX_CVECTOR_H__1C4C1B80_02AB_11D4_A040_00105A6EBE46__INCLUDED_)
#define AFX_CVECTOR_H__1C4C1B80_02AB_11D4_A040_00105A6EBE46__INCLUDED_
#pragma once

class cVector  
{
public:
    float x, y, z;

public:
    cVector(float x_, float y_, float z_): x(x_), y(y_), z(z_) {}
    cVector(): x(0), y(0), z(0) {}
    cVector(const cVector &V): x(V.x), y(V.y), z(V.z) {}
    // + -
    cVector operator + (const cVector &V) const
    {
        return cVector(x + V.x, y + V.y, z + V.z);
    }
    cVector &operator += (const cVector &V)
    {
        x += V.x; y += V.y; z += V.z;
        return *this;
    }
    cVector operator - () const
    {
        return cVector(-x, -y, -z);
    }
    cVector operator - (const cVector &V) const
    {
        return cVector(x - V.x, y - V.y, z - V.z);
    }
    cVector &operator -= (const cVector &V)
    {
        x -= V.x; y -= V.y; z -= V.z;
        return *this;
    }
    cVector operator * (float f) const 
    {
        return cVector(x * f, y * f, z * f); 
    }
    cVector &operator *= (float f)
    {
        x *= f; y *= f; z *= f;
        return *this;
    }
    // dot product -  
    cVector operator^(const cVector& V) const
    {
        return cVector(y*V.z - z*V.y, z*V.x - x*V.z, x*V.y - y*V.x);
    }
    // scalar product -  
    float operator | (const cVector &V) const
    {
        // A | B = A.Magnitude() * A.Magnitude() * Cos(AB);
        return x*V.x + y*V.y + z*V.z;
        // NormOfVector | Vector = LengthOfVector
    }

public:
    float Magnitude()
    {
        return sqrtf(x*x + y*y + z*z);
    }
    cVector &Normalize()
    {
        float OneDivMagnitude = 1.0f/Magnitude();
        x *= OneDivMagnitude;
        y *= OneDivMagnitude;
        z *= OneDivMagnitude;
        return *this;
    }
    cVector GetNormalized()
    {
        return cVector(*this).Normalize();
    }
};

typedef cVector cPoint;

#endif // !defined(AFX_CVECTOR_H__1C4C1B80_02AB_11D4_A040_00105A6EBE46__INCLUDED_)
