/****************************************************************************************************

		Interpolator2D.h
		Copyright: (c) 2007 Daz Productions Inc. All rights reserved.

		Author:	Mathieu
		Date:	4/26/2007

****************************************************************************************************/

#ifndef __Interpolator2D__
#define __Interpolator2D__

#if CP_PRAGMA_ONCE
#pragma once
#endif


#include "MCBasicTypes.h"
#include "MCArray.h"
#include "MCClassArray.h"
#include "ParamHolder.h"
#include "IExParamType.h"
#include "MatrixMN.h"
#include "VectorN.h"
#include "Vector2.h"
#include "MCPoint.h"
#include "MatrixTriangulator.h"
#include "math.h"
#include "PointsMerger.h"


// **********************************************************************************************
//										Interpolator 2D Class
// **********************************************************************************************
// Carries out a linear interpolation between a set of parameters values associated to a set of 
// points (TMCPoint type) in a 2D plan.
//
// HOW TO USE THIS CLASS:
// - Feed the new points list to the "Init" function that will build the interpolation matrix.
// - Use "Interpolate" function with the point you want to interpolate at and a vector of real 
// values that correspond in the right order to the points list. It will return the interpolated 
// real value. 
//
// SPECIAL CASES HANDLED:
// - 2 or more points aligned in the 2D plan. Sets a new coordinate system with points 
// line as x-axis and neglect the y-coordinates in the inteprolation. 
// - Points in the 2D plan are all on the same spot. Calculates the mean ot all the associated 
// values and displays it.
// - When the interpolator is given a list of points in the 2D plan where lots of them are the same,  
// the interpolation matrix will contain a lot of 0 and the system might not be resolved properly.
// In that case, points that are the same are merged into one (see PointsMerger.h in MCUtils)
// and the value associated to it is the mean of all the values associated with the points 
// on the same spot.
//
// ARTICLE REFERENCE: "Spatial Keyframing for Performance Driven Animation", Section 4.
// (Eurographics/ACMSIGGRAPH, Symposium on Computer Animation (2005), K. Anjyo, P. Faloutsos (Editors))
// **********************************************************************************************

class TInterpolator2D : public TMCObject
{
public:
	// Possibilities for the points alignement
	enum EAlignement
	{
		kAligned,
		kNotAligned,
		kAllOntheSameSpot
	};

public:
	TInterpolator2D();
	~TInterpolator2D();

	void Init(const TMCArray<TVector2f>& pointList);
	real64 Interpolate(TVector2f clickpoint, TVectorN<real64>& paramValues);
	EAlignement GetAlignmentMode() {return fAlignement;}
	int32 GetDimension();

protected:
	EAlignement PointsAlignementTest(const TMCArray<TVector2f>& pointList);
	void ChangeCoordinateSystem(const TMCArray<TVector2f>& pointList, TMCArray<TVector2f>& newPointList); 										
	void BuildInterpolationMatrix(const TMCArray<TVector2f>& pointList, 
								  TMatrixMN<real64>&        interpolationMatrix, 
								  EAlignement               alignment
								  );
	void BuildTriangularMatrix(const TMatrixMN<real64>& interpolationMatrix, 
							   TMatrixTriangulator&     triangulator
							   );

protected:
	TMatrixTriangulator	fTriangulator;
	TMatrixMN<real64>	fInterpolationMatrix;
	TMCArray<TVector2f>	fPointList; 
	EAlignement			fAlignement;
	TVector2d		    fRefVector; // base vector of the new coordinate system when points are aligned
	TVector2f           fFirstPoint; // useful to calculate the coordinates of the clickPoint in the new coordinate system when point are aligned
	TPointsMerger		fPointsMerger;
};



#endif










