#pragma once

#include "cvcls.h"

//#include "..\incs\sst\ucut.h"



 //最小二乘法精度
#define LMS_OFFSET_ERR0  1.f
#define LMS_OFFSET_ERR1  0.1f      //1/10
#define LMS_OFFSET_ERR2  0.05f     //1/20
#define LMS_OFFSET_ERR3  0.025f    //1/40

#define LMS_OFFSET_ERR0_I  1 
#define LMS_OFFSET_ERR1_I  10
#define LMS_OFFSET_ERR2_I  20
#define LMS_OFFSET_ERR3_I  40

#define LMS_ROT_ERR0  1.f
#define LMS_ROT_ERR1  0.08f     //  1/12.5
#define LMS_ROT_ERR2  0.04f    //  1/25
#define LMS_ROT_ERR3  0.02f    //  1/50

#define LMS_ROT_ERR0_I  10
#define LMS_ROT_ERR1_I  125
#define LMS_ROT_ERR2_I  250
#define LMS_ROT_ERR3_I  500


//所有点最少保证4个
class CVCLS_API CAutoAlign
{
public:
	CAutoAlign(void);
	~CAutoAlign(void);

	
	//逐步求精，到指定精度
	//不旋转，
	BOOL  Brute(RvPoint_f* pPattArr, int nPattSize, const RvPoint_f* pSceneArr, int nSceneSize, int transReso, RvPoint_f* pTargetPos, double* pScore);
	
	//逐步求精，到指定精度
	//旋转，
	BOOL  Brute(RvPoint_f* pPattArr, int nPattSize, const RvPoint_f* pSceneArr, int nSceneSize, int transReso, int angleReso, RvPoint_f* pTargetPos, double* curAngle, double* pScore);

	//Icp和IcpR目前还有问题。
	//逐步求精，到指定精度，不旋转
	BOOL  Icp(RvPoint_f* pPattArr, int nPattSize, const RvPoint_f* pSceneArr, int nSceneSize, int transReso, RvPoint_f* pTargetPos, double* pScore);
	
	//逐步求精，到指定精度，旋转
	BOOL  Icp(RvPoint_f* pPattArr, int nPattSize, const RvPoint_f* pSceneArr, int nSceneSize, int transReso, int angleReso, RvPoint_f* pTargetPos, double* curAngle, double* pScore);


//utilities
public:
	//直接求角度，像素为单位精度。
	static BOOL Do(RvPoint* pSourceArr, int nSourceSize,  const RvPoint* pTargetArr, int nTargetSize, RvDiff_f* pOffset, double* pAngle);
	static BOOL FindParams(const RvPoint* pSourceArr, int nSourceSize,  const  RvPoint* pTargetArr, int nTargetSize, RvDiff_f* pOffset, double* pAngle);

	//计算最小距离
	//返回符合条件的数量，
	//pResult为总距离
	static int Lms(const RvPoint_f* pSourceArr, int nSourceSize,  const RvPoint_f* pTargetArr, int nTargetSize, double maxDist, double* pResult);


	   
public:

	float m_nOffsetExtent;
	float m_nAngleExtent;
	int   m_nnRadius;
	float m_nMinScore;
	float m_nMaxDist;

	
protected:
	

	
	//int Lms(CFlannMatch& fm,  const RvPoint_f* pSourceArr, int nSourceSize, float offsetX, float offsetY, double maxDist, double* pResult);
	//int LmsF(CFlannMatch& fm,  const RvPoint_f* pSourceArr, int nSourceSize, float offsetX, float offsetY, float centerX, float centerY, double angle, double maxDist, double* pResult);
	//int LmsR(CFlannMatch& fm,  const RvPoint_f* pSourceArr, int nSourceSize,  float centerX, float centerY,  double angle, double maxDist, double* pResult);


	//非旋转
	//BOOL Refine(RvPoint* pPattArr, int nPattSize, const RvPoint* pSceneArr, int nSceneSize, struct __lms_params_& lp , RvDiff_f*  pOffset  );
	//BOOL Refine(RvPoint_f* pPattArr, int nPattSize, const RvPoint_f* pSceneArr, int nSceneSize, struct __lms_params_& lp , RvDiff_f*  pOffset  );
	//BOOL Refine(RvPoint_f64* pPattArr, int nPattSize, const RvPoint_f64* pSceneArr, int nSceneSize, struct __lms_params_& lp , RvDiff_f64*  pOffset  );

	//旋转
	//BOOL Refine(RvPoint* pPattArr, int nPattSize, const RvPoint* pSceneArr, int nSceneSize, struct __lms_params_& lp , RvDiff_f*  pOffset , float* pAngle );
	//BOOL Refine(RvPoint_f* pPattArr, int nPattSize, const RvPoint_f* pSceneArr, int nSceneSize, struct __lms_params_& lp , RvDiff_f*  pOffset , float* pAngle );
	//BOOL Refine(RvPoint_f64* pPattArr, int nPattSize, const RvPoint_f64* pSceneArr, int nSceneSize, struct __lms_params_& lp , RvDiff_f64*  pOffset, double* pAngle  );



};

