//
//	Copyright © 2005 Nemetschek North America 
//	All Rights Reserved.
//
// Created by Vladislav Stanev

#include "StdAfx.h"
//#include "VWRectangle2D.h"

using namespace VWFC::Math;

VWCube::VWCube()
{
	bEmpty		= true;
}

VWCube::VWCube(const VWPoint3D& minPoint, const VWPoint3D& maxPoint)
{
	this->SetCube( minPoint, maxPoint );
}

VWCube::VWCube(const VWPoint3D& minPt, double cx, double cy, double cz)
{
	this->SetCube( minPt, cx, cy, cz );
}

VWCube::VWCube(const VWCube& src)
{
	bEmpty			= src.bEmpty;
	m_maxPoint		= src.m_maxPoint;
	m_minPoint	= src.m_minPoint;
}

VWCube::~VWCube()
{
}

VWCube& VWCube::operator=(const VWCube& src)
{
	bEmpty			= src.bEmpty;
	m_maxPoint		= src.m_maxPoint;
	m_minPoint		= src.m_minPoint;
	return *this;
}

void VWCube::Clear()
{
	bEmpty		= true;
	m_minPoint.SetPoint( 0, 0, 0 );
	m_maxPoint.SetPoint( 0, 0, 0 );
}

void VWCube::SetCube(const VWPoint3D& minPoint, const VWPoint3D& maxPoint)
{
	bEmpty				= false;
	m_minPoint.x		= maxPoint.x < minPoint.x ? maxPoint.x : minPoint.x;
	m_minPoint.y		= maxPoint.y < minPoint.y ? maxPoint.y : minPoint.y;
	m_minPoint.z		= maxPoint.z < minPoint.z ? maxPoint.z : minPoint.z;
	m_maxPoint.x		= maxPoint.x > minPoint.x ? maxPoint.x : minPoint.x;
	m_maxPoint.y		= maxPoint.y > minPoint.y ? maxPoint.y : minPoint.y;
	m_maxPoint.z		= maxPoint.z > minPoint.z ? maxPoint.z : minPoint.z;
}

void VWCube::SetCube(const VWPoint3D& minPt, double cx, double cy, double cz)
{
	bEmpty				= false;
	m_minPoint			= minPt;
	m_maxPoint.x		= m_minPoint.x + cx;
	m_maxPoint.y		= m_minPoint.y + cy;
	m_maxPoint.z		= m_minPoint.z + cz;
}

bool VWCube::IsEmpty() const
{
	return bEmpty;
}

double VWCube::GetWidth() const
{
	double	width	= m_maxPoint.x - m_minPoint.x;
	return width > 0 ? width : - width;
}

double VWCube::GetDepth() const
{
	double	depth	= m_maxPoint.y - m_minPoint.y;
	return depth > 0 ? depth : - depth;
}

double VWCube::GetHeight() const
{
	double	height	= m_maxPoint.z - m_minPoint.z;
	return height > 0 ? height : - height;
}

const VWPoint3D& VWCube::GetMinPoint() const
{
	return m_minPoint;
}

const VWPoint3D& VWCube::GetMaxPoint() const
{
	return m_maxPoint;
}

void VWCube::Unite(const VWPolygon2D& poly)
{
	size_t	len		= poly.GetVertexCount();
	for(size_t i=0; i<len; i++) {
		const VWPoint2D&	pt	= poly.GetVertexAt( i );
		this->Unite( pt.x, pt.y, 0 );
	}
}

void VWCube::Unite(const VWPolygon3D& poly)
{
	size_t	len		= poly.GetVertexCount();
	for(size_t i=0; i<len; i++) {
		const VWPoint3D&	pt	= poly.GetVertexAt( i );
		this->Unite( pt.x, pt.y, pt.z );
	}
}

void VWCube::Unite(double x, double y, double z)
{
	if ( bEmpty ) {
		m_minPoint.x		= x;
		m_minPoint.y		= y;
		m_minPoint.z		= z;
		m_maxPoint.x		= x;
		m_maxPoint.y		= y;
		m_maxPoint.z		= z;
		bEmpty				= false;
	}
	else {
		if ( x < m_minPoint.x )		m_minPoint.x		= x;
		if ( y < m_minPoint.y )		m_minPoint.y		= y;
		if ( z < m_minPoint.z )		m_minPoint.z		= z;
		if ( x > m_maxPoint.x )		m_maxPoint.x		= x;
		if ( y > m_maxPoint.y )		m_maxPoint.y		= y;
		if ( z > m_maxPoint.z )		m_maxPoint.z		= z;
	}
}

void VWCube::Unite(const VWPoint3D& pt)
{
	this->Unite( pt.x, pt.y, pt.z );
}

void VWCube::Unite(const VWCube& cube)
{
	this->Unite( cube.m_minPoint.x, cube.m_minPoint.y, cube.m_minPoint.z );
	this->Unite( cube.m_maxPoint.x, cube.m_maxPoint.y, cube.m_maxPoint.z );
}

bool VWCube::IsPtInside(double x, double y, double z) const
{
	return
		m_maxPoint.x < x && x < m_minPoint.x &&
		m_minPoint.y < y && y < m_maxPoint.y &&
		m_minPoint.z < z && z < m_maxPoint.z;
}

bool VWCube::IsPtInside(const VWPoint3D& pt) const
{
	return this->IsPtInside( pt.x, pt.y, pt.z );
}


