// 3DPoint.cpp : implementation of the C3DPoint class
//

#include "stdafx.h"

#include <math.h>

#include "3DPoint.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define MAX_DELTA		0.035

/////////////////////////////////////////////////////////////////////////////
// C3DPoint construction/destruction

C3DPoint::C3DPoint()
{
	// TODO: add one-time construction code here
	m_x = 0;
	m_y = 0;
	m_z = 0;

}

C3DPoint::C3DPoint(C3DPoint* point)
{
	// TODO: add one-time construction code here
	m_x = point->m_x;
	m_y = point->m_y;
	m_z = point->m_z;

}

C3DPoint::C3DPoint(double x, double y, double z)
{
	// TODO: add one-time construction code here
	m_x = x;
	m_y = y;
	m_z = z;

}

C3DPoint::~C3DPoint()
{
}


/////////////////////////////////////////////////////////////////////////////
// C3DPoint serialization

void C3DPoint::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

//return the magnitude of this point.  Its dot product with itself
//sqrt
double C3DPoint::Magnitude(void)
{
	return sqrt(DotProduct(this));
}

//normalize it-divide it by its magnitude
void C3DPoint::Normalize(void)
{
	double Length = Magnitude();

	if(Length)
	{
		m_x /= Length;
		m_y /= Length;
		m_z /= Length;	
	}
	else
		m_x = m_y = m_z = 0.0;
}


double C3DPoint::DotProduct(C3DPoint Pnt) 
{
	return m_x * Pnt.m_x + m_y * Pnt.m_y + m_z * Pnt.m_z;
}


C3DPoint C3DPoint::CrossProduct(C3DPoint Pnt)
{
	C3DPoint Result;

	Result.m_x = m_y * Pnt.m_z - m_z * Pnt.m_y;
	Result.m_y = m_z * Pnt.m_x - m_x * Pnt.m_z;
	Result.m_z = m_x * Pnt.m_y - m_y * Pnt.m_x;

	return Result;
}


BOOL C3DPoint::operator==(C3DPoint Pnt)
{
	C3DPoint Result = *this - Pnt;

	return (MAX_DELTA >= Result.Magnitude());
}

C3DPoint C3DPoint::operator+(C3DPoint Pnt)
{
	C3DPoint Result;

	Result.m_x = m_x + Pnt.m_x;
	Result.m_y = m_y + Pnt.m_y;
	Result.m_z = m_z + Pnt.m_z;
	
	return Result;
};

C3DPoint C3DPoint::operator-(C3DPoint Pnt) 
{
	C3DPoint Result;

	Result.m_x = m_x - Pnt.m_x;
	Result.m_y = m_y - Pnt.m_y;
	Result.m_z = m_z - Pnt.m_z;
	
	return Result;
};

//return the point in between us and testPoint
C3DPoint C3DPoint::MidPointWith(C3DPoint testPoint)
{
	C3DPoint Result;

	Result.m_x = (m_x + testPoint.m_x) / 2;
	Result.m_y = (m_y + testPoint.m_y) / 2;
	Result.m_z = (m_z + testPoint.m_z) / 2;
	
	return Result;
}

//return a point consisting of the minumum
//between us and the given point
C3DPoint C3DPoint::MinimumWith(C3DPoint testPoint)
{
	C3DPoint Result;
	if (m_x <= testPoint.m_x)
		Result.m_x = m_x;
	else
		Result.m_x = testPoint.m_x;
	if (m_y <= testPoint.m_y)
		Result.m_y = m_y;
	else
		Result.m_y = testPoint.m_y;
	if (m_z <= testPoint.m_z)
		Result.m_z = m_z;
	else
		Result.m_z = testPoint.m_z;
	
	return Result;
}

//return a point consisting of the maximum
//between us and the given point
C3DPoint C3DPoint::MaximumWith(C3DPoint testPoint)
{
	C3DPoint Result;
	if (m_x >= testPoint.m_x)
		Result.m_x = m_x;
	else
		Result.m_x = testPoint.m_x;
	if (m_y >= testPoint.m_y)
		Result.m_y = m_y;
	else
		Result.m_y = testPoint.m_y;
	if (m_z >= testPoint.m_z)
		Result.m_z = m_z;
	else
		Result.m_z = testPoint.m_z;
	
	return Result;
}

C3DPoint C3DPoint::operator*(double dNum) 
{
	C3DPoint Result;
	Result.m_x = m_x * dNum;
	Result.m_y = m_y * dNum;
	Result.m_z = m_z * dNum;
	return Result;
}

