#include "StdAfx.h"
#include "beziervec3dapproximation.h"

CBezierVec3dApproximation::CBezierVec3dApproximation()
{
}

CBezierVec3dApproximation::CBezierVec3dApproximation(Vec3d* pData, int nSamples, int nDegree)
{
	init (pData, nSamples, nDegree);
}

void CBezierVec3dApproximation::init(Vec3d* pData, int nSamples, int nDegree)
{
	CDataAdaptor adaptor (pData, nSamples, 0);
	x.init (&adaptor, nDegree);
	adaptor.setCoord(1);
	y.init (&adaptor, nDegree);
	adaptor.setCoord(2);
	z.init (&adaptor, nDegree);

#ifdef _DEBUG
		if (nDegree+1 == nSamples)
		{
			for (int nCoord =0; nCoord< 3; ++nCoord)
				for (int nPoint = 0; nPoint < nSamples; ++nPoint)
					assert ((tabs((*this)[nCoord].getValueAtFrame (nPoint) - pData[nPoint][nCoord])) < 1e-5);
		}
#endif
}

CBezierVec3dApproximation::~CBezierVec3dApproximation(void)
{
}

void CBezierVec3dApproximation::clear()
{
	x.clear();
	y.clear();
	z.clear();
}

// calculates the sum of squares of the errors between the approximated and real values,
// real value array given, of the size of initial data set
double CBezierVec3dApproximation::getError (Vec3d* pData)
{
	CDataAdaptor adaptor (pData, x.numSamples(), 0);
	double fError = x.getError (&adaptor);
	adaptor.setCoord(1);
	fError += y.getError (&adaptor);
	adaptor.setCoord(2);
	fError += z.getError (&adaptor);
	return fError;
}