#include "Arith_CoordModule.h"

//#include "Arith_SysVar.h"
#include <cmath>
#include "Arith_Utils.h"



// 从惯性系（建航坐标系）到  像坐标系
POINT32F getImagePosFromStablePole(Pole stablePole, CameraParam cam, ServoParam servoInfo, EulerRPY att, DeviceSetupError err)
{
	POINT32F imgPos = { 0 };

	// 从稳定性到设备系
	Pole devicePole = getDevicePoleFromStablePole(stablePole, att, err);

	// 从设备系到像方
	imgPos = getImagePosFromDevicePole(devicePole, cam, servoInfo);

	return imgPos;

}

// 从像坐标系 到 惯性系（建航坐标系）
Pole getStablePoleFromImagePos(POINT32F imagePos, CameraParam cam, ServoParam servoInfo, EulerRPY att, DeviceSetupError err)
{
	Pole StablePole = { 0 };

	// 从像方到设备系
	Pole devicePole = getDevicePoleFromImagePos(imagePos, cam, servoInfo);

	// 从设备系到惯性系
	StablePole = getStablePoleFromDevicePole(devicePole, att, err);

	return StablePole;
}



BBOOL bTargetInScanFov(ANGLE32F targetPos, Pole scanNueRange1, Pole scanNueRange2)
{
	BBOOL AzInScan = TRUE;
	BBOOL PtInScan = TRUE;
	// 俯仰扫描区间有效
	if (scanNueRange1.alpha != 0 && scanNueRange2.alpha != 0)
	{
		if (targetPos.fPt < scanNueRange1.alpha || targetPos.fPt > scanNueRange2.alpha)
		{
			PtInScan = FALSE;
		}

	}

	// 方位扫描区间有效
	if (scanNueRange1.beta != 0 && scanNueRange2.beta != 0)
	{
		if (targetPos.fAz < scanNueRange1.beta || targetPos.fAz > scanNueRange2.beta)
		{
			AzInScan = FALSE;
		}
	}

	return (AzInScan && PtInScan);

}

Pole getDevicePoleFromStablePole(Pole stablePole, EulerRPY att, DeviceSetupError err)
{
	Pole targetCarNUEPole = stablePole;

	// 地理极坐标 转 地理直角坐标
	PointXYZ targetCarNUEXYZ = getXYZFromPole(targetCarNUEPole);

	// 地理直角坐标 转 平台直角坐标
	PointXYZ targetCarXYZ = getCarXYZFromCarNUEXYZ(targetCarNUEXYZ, att.fYaw, att.fPitch, att.fRoll);

	// 平台直角 转 光电基准系直角
	PointXYZ targetEOBaseXYZ = getEOBaseXYZFromCarXYZ(targetCarXYZ, err.g_XBias, err.g_YBias, err.g_ZBias);

	// 光电基准系直角 转 光电伺服直角
	PointXYZ targetEOServoXYZ = getEOServoXYZFromEOBaseXYZ(targetEOBaseXYZ, err.g_YawBias, err.g_PitchBias, err.g_RollBias);

	// 光电伺服直角 转 光电伺服极坐标
	Pole targetEOServoPole = getPoleFromXYZ(targetEOServoXYZ);

	return targetEOServoPole;

}

Pole getStablePoleFromDevicePole(Pole devicePole, EulerRPY att, DeviceSetupError err)
{
	// 设备系转伺服直角坐标
	PointXYZ targetServoXYZ = getXYZFromPole(devicePole);

	// 光电伺服直角坐标 转 光电基准直角坐标
	PointXYZ targetEOBaseXYZ = getEOBaseXYZFromEOServoXYZ(targetServoXYZ, err.g_YawBias, err.g_PitchBias, err.g_RollBias);

	// 光电基准直角坐标 转 平台直角坐标
	PointXYZ targetCarXYZ = getCarXYZFromEOBaseXYZ(targetEOBaseXYZ, err.g_XBias, err.g_YBias, err.g_ZBias);

	// 平台直角坐标 转 平台地理直角坐标
	PointXYZ targetCarNUEXYZ = getCarNUEXYZFromCarXYZ(targetCarXYZ, att.fYaw, att.fPitch, att.fRoll);

	// 平台地理直角坐标 转 平台地理极坐标
	Pole targetCarNUEPole = getPoleFromXYZ(targetCarNUEXYZ);

	return targetCarNUEPole;

}



// 像方转设备系
Pole getDevicePoleFromImagePos(POINT32F imagePos, CameraParam cam, ServoParam servoInfo)
{
	Pole targetDevicePole = { 0 };

	if(cam.bImageRataSys)
	{
		double refmat[9] = { 0 };
		PMS_MultiRefMat(servoInfo.fAz, servoInfo.fPt, servoInfo.fFSMAz, servoInfo.fFSMPt, refmat);

		targetDevicePole = PMS_ProjectPixelToWorld((int)imagePos.x, (int)imagePos.y, refmat, 
			cam.f / cam.dSize * 1000, cam.dx + cam.ImageWidth / 2, cam.dy + cam.ImageHeight / 2);
	}
	else
	{
		// 像方转相机坐标系
		Pole targetCamPole = { 0 };
		float fAglRes = FLOAT32(ANGLE(cam.dSize / cam.f / 1000));
		SINT32 cx = cam.dx + cam.ImageWidth / 2;
		SINT32 cy = cam.dy + cam.ImageHeight / 2;
		targetCamPole.beta = (imagePos.x - cx) * fAglRes;
		targetCamPole.alpha = (cy - imagePos.y) * fAglRes;

		// 1:一般旋转矩阵方法
		// 光电镜面极坐标 转 光电镜面直角坐标
		PointXYZ targetCamXYZ = getXYZFromPole(targetCamPole);

		// 光电镜面直角坐标 转 光电伺服直角坐标
		PointXYZ targetServoXYZ = getEOServoXYZFromEOCamXYZ(targetCamXYZ, servoInfo.fPt, servoInfo.fAz);

		// 2:正割补偿方法
			// 光电镜面极坐标 转 光电伺服极坐标
		// 	Pole targetEOServoPOLE;
		// 	targetEOServoPOLE.alpha = alaph + targetCamPole.alpha;
		// 	targetEOServoPOLE.beta = beta + targetCamPole.beta/cos(RADIAN(alaph));
		// 	targetEOServoPOLE.distance = targetCamPole.distance;
		// 	// 光电伺服极坐标 转 光电伺服直角坐标
		// 	targetServoXYZ = getXYZFromPole(targetEOServoPOLE);

		targetDevicePole = getPoleFromXYZ(targetServoXYZ);
	}


	return targetDevicePole;
}


// 设备系转像方坐标
POINT32F getImagePosFromDevicePole(Pole devicePole, CameraParam cam, ServoParam servoInfo)
{
	POINT32F imgpos = { 0 };

	// 常规光电成像模型
	if(cam.bImageRataSys)
	{
		double refmat[9] = { 0 };
		double refmat_inv[9] = { 0 };
		PMS_MultiRefMat(servoInfo.fAz, servoInfo.fPt, servoInfo.fFSMAz, servoInfo.fFSMPt, refmat);
		//invMat3(refmat, refmat_inv);
		TransposeMat(refmat, 3, 3, refmat_inv);//等价

		PointXYZ imgPosition = 
			PMS_ProjectWorldToPixel((float)devicePole.beta, (float)devicePole.alpha, refmat_inv, 
				cam.f / cam.dSize * 1000, cam.dx + cam.ImageWidth/2, cam.dy + cam.ImageHeight/2);

		imgpos.x = (float)imgPosition.X;
		imgpos.y = (float)imgPosition.Y;

	}
	else
	{
		// 设备极坐标转直角坐标
		PointXYZ targetEOServoXYZ = getXYZFromPole(devicePole);

		// 光电伺服直角 转 光电镜面直角坐标(相机系)
		PointXYZ targetEOCamXYZ = getEOCamXYZFromEOServoXYZ(targetEOServoXYZ, servoInfo.fPt, servoInfo.fAz);

		//  光电镜面极坐标
		Pole targetEOCamPole = getPoleFromXYZ(targetEOCamXYZ);

		float fAglRes = FLOAT32(ANGLE(cam.dSize / cam.f / 1000.0f));
		SINT32 cx = cam.dx + cam.ImageWidth / 2;
		SINT32 cy = cam.dy + cam.ImageHeight / 2;
		imgpos.x = FLOAT32(targetEOCamPole.beta / fAglRes + cx);
		imgpos.y = FLOAT32(cy - targetEOCamPole.alpha / fAglRes);
	}

	return imgpos;
}





void PMS_MultiRefMat(float fMainAz, float fMainAPt, float fFSMAz, float fFSMPt, double* mat)
{
	// 反射镜1
	// fa -- 方位角输出-外框
	// fb -- 俯仰角输出-内框
	PointXYZ N1_0;
	N1_0.X = 1 / sqrt(2.0);
	N1_0.Y = 1 / sqrt(2.0);
	N1_0.Z = 0;

	// n1绕z轴旋转fb（向上为正）
	double Sz[9] = { cosd(fMainAPt),sind(fMainAPt),0,
	-sind(fMainAPt),cosd(fMainAPt),0,
	0,0,1 };

	// 再绕y轴旋转fa（向右为正）
	double Sy[9] = { cosd(fMainAz),0,-sind(fMainAz),
		0,1,0,
		sind(fMainAz),0,cosd(fMainAz) };

	// 反射镜1法向量  %% 前两个法向量在XOY面里
	//N1_F = Sy *  Sz * N1_0;
	PointXYZ N1_F = RtPoint(Sy, RtPoint(Sz, N1_0));

	// 反射镜1反射矩阵
	//R1 = eye(3) - (2 * N1_F * N1_F');
	double R1[9] = { 0 };
	RMirror(N1_F, R1);


	// 反射镜23，没有动  %%注意：第3、4面镜子已经在XOZ面里了，注意空间关系
	PointXYZ N2_0;
	N2_0.X = -1 / sqrt(2.0);
	N2_0.Y = -1 / sqrt(2.0);
	N2_0.Z = 0;
	double R2[9] = { 0 };
	RMirror(N2_0, R2);

	PointXYZ N3_0;
	N3_0.X = 1 / sqrt(2.0);
	N3_0.Y = 0;
	N3_0.Z = 1 / sqrt(2.0);
	double R3[9] = { 0 };
	RMirror(N3_0, R3);

	// 反射镜4是快反
	// Qa -- 方位角输出-外框,向右偏转为正
	// Qb -- 俯仰角输出-内框，抬头为正
	PointXYZ N4_0;
	N4_0.X = 1 / sqrt(2.0);
	N4_0.Y = 0;
	N4_0.Z = -1 / sqrt(2.0);

	// 外框扫描轴为y轴，内框扫描轴L0为x=z 即(1,0,1)'
	double Sy2[9] = { cosd(fFSMAz),0,-sind(fFSMAz),
		0,1,0,
		sind(fFSMAz),0,cosd(fFSMAz) };

	// 内框旋转向量,注意左手系，会引入负号
	PointXYZ L0;
	L0.X = 1;
	L0.Y = 0;
	L0.Z = 1;
	double SL2[9] = { 0 };
	rotationVectorToMatrix(L0, -fFSMPt, SL2);

	//快反镜法向量，经过内框和外框旋转
	// N4_F = Sy2 *  SL2 * N4_0;
	PointXYZ N4_F = RtPoint(Sy2, RtPoint(SL2, N4_0));

	// 快反的反射矩阵
	double R4[9] = { 0 };
	RMirror(N4_F, R4);

	// 整个光路的反射模型,从像方到物方
	double tmp[9] = { 0 };
	MultiMat333(R2, R3, R4, tmp);
	MultiMat33(R1, tmp, mat);


}

// 像方到物方的映射,转到方位俯仰角
Pole PMS_ProjectPixelToWorld(int x, int y, float fMainAz, float fMainAPt, float fFSMAz, float fFSMPt, float f_px, int cx, int cy)
{
	// 计算反射矩阵
 	double mat[9] = { 0 };
 	PMS_MultiRefMat(fMainAz, fMainAPt, fFSMAz, fFSMPt, mat);
 	return PMS_ProjectPixelToWorld(x, y, mat, f_px, cx, cy);
}

Pole PMS_ProjectPixelToWorld(int x, int y, double* mat, float f_px, int cx, int cy)
{
	Pole worldPole = { 0 };
	// 内参信息
	// const int nWidth = 860;
	// const int nHeight = 715;
	// const float f = 350;
	// const int piexlSize = 7.5;
	// float fpiexl = f/piexlSize * 1000; //像素焦距

	// 从靶面出射的矢量
	PointXYZ PO;
	PO.X = -f_px;
	PO.Y = -(y - cy);
	PO.Z = -(x - cx);

	//%%猜测y方向设置了-Y，否则成像应该是倒着的，所以这里
	PO.Y = -PO.Y;

	// 出射矢量
	PointXYZ OQ;
	OQ = RtPoint(mat, PO);



	// 物方角度
	double len = sqrt(PO.X * PO.X + PO.Y * PO.Y + PO.Z * PO.Z);


	worldPole.alpha = ANGLE(asin(-OQ.Y / len));
	worldPole.beta = ANGLE(atan2(OQ.Z, OQ.X));

	return worldPole;
}

// PointXYZ PMS_ProjectPixelToWorldVec(int x, int y, double* mat, float f_px, int cx, int cy)
// {
// 	Pole worldPole = { 0 };
// 	// 内参信息
// 	// const int nWidth = 860;
// 	// const int nHeight = 715;
// 	// const float f = 350;
// 	// const int piexlSize = 7.5;
// 	// float fpiexl = f/piexlSize * 1000; //像素焦距

// 	// 从靶面出射的矢量
// 	PointXYZ PO;
// 	PO.X = -f_px;
// 	PO.Y = -(y - cy);
// 	PO.Z = -(x - cx);

// 	//%%猜测y方向设置了-Y，否则成像应该是倒着的，所以这里
// 	PO.Y = -PO.Y;

// 	// 出射矢量
// 	PointXYZ OQ;
// 	OQ = RtPoint(mat, PO);

// 	return OQ;

// }
//物方到像方的映射,转到像素位置
PointXYZ PMS_ProjectWorldToPixel(float fAz, float fPt, double* refmat, float f_px, int cx, int cy)
{
	PointXYZ pxPos = { 0 };

	// 物方直角系出射矢量
	PointXYZ OQ = { 0 };
	float Dep = 1000;//单位向量
	OQ.Y = -Dep * sind(fPt);
	OQ.X = Dep * cosd(fPt) * cosd(fAz);
	OQ.Z = Dep * cosd(fPt) * sind(fAz);


	// 投影,得到靶面出射矢量
	PointXYZ PO = RtPoint(refmat, OQ);

	PointXYZ OP = { 0 };//射向靶面
	OP.X = -PO.X;
	OP.Y = -PO.Y;
	OP.Z = -PO.Z;


	// 内参矩阵
	pxPos.X = f_px * OP.Z / OP.X + cx;
	pxPos.Y = -f_px * OP.Y / OP.X + cy;


	return pxPos;
}

// PointXYZ PMS_ProjectWorldVecToPixel(PointXYZ worldVec, double* refmat, float f_px, int cx, int cy)
// {
// 	PointXYZ pxPos = { 0 };
// 	// 投影,得到靶面出射矢量
// 	PointXYZ PO = RtPoint(refmat, worldVec);

// 	PointXYZ OP = { 0 };//射向靶面
// 	OP.X = -PO.X;
// 	OP.Y = -PO.Y;
// 	OP.Z = -PO.Z;


// 	// 内参矩阵
// 	pxPos.X = f_px * OP.Z / OP.X + cx;
// 	pxPos.Y = -f_px * OP.Y / OP.X + cy;


// 	return pxPos;
// }


// // S726像方到物方转换
// Pole getPointMirrorServoPoleFromImageXY(int Col,int Row,int nWidth,int nHeight,
// 										float fServoA,float fServoB,float fLen,float pxSizeOfum)
// {
// 	// by wcw04046 @ 2021/12/04
// 	// 注意:在通常成像系统中，伺服读数基本等价于伺服系下角度（需要考虑正割补偿）
// 	// 在指向镜成像系统中，伺服读数与伺服系下角度完全不等价 fServoAz fServoPt 与目标在伺服系位置非线性 
// 	// 伺服坐标系角度
// 	Pole ServoPole;

// 	// 像素焦距
// 	float f_0 = fLen/pxSizeOfum * 1000;

// 	// 等效像方入射矢量
// 	PointXYZ CamVec;
// 	CamVec.X = f_0;
// 	CamVec.Y = -nHeight/2 + Row;
// 	CamVec.Z = (-nWidth/2 + Col);

// 	// 反射镜能将正前方(x轴)的目标反射到成像系统光轴(y轴)上时，角编码器为零位

// 	// 平面镜1零位的法向量
// 	PointXYZ N_01;
// 	N_01.X = 1/sqrt(2.0);
// 	N_01.Y = 1/sqrt(2.0);
// 	N_01.Z = 0;

// 	double Sx[9] = {1,0,0,
// 	0,cos(RADIAN(fServoA)),-sin(RADIAN(fServoA)),
// 	0,sin(RADIAN(fServoA)),cos(RADIAN(fServoA))};

// 	double Sy[9] = {cos(RADIAN(fServoB)),0,-sin(RADIAN(fServoB)),
// 	0,1,0,
// 	sin(RADIAN(fServoB)),0,cos(RADIAN(fServoB))};

// 	PointXYZ N_1 = RtPoint(Sx,RtPoint(Sy,N_01));
// 	// 镜面反射矩阵
// 	//	M = eye(3)-(2*N*N');
// 	double M1[9] = {0};
// 	RMirror(N_1,M1);


// 	// 平面镜2零位的法向量
// 	PointXYZ N_02;
// 	N_02.X = -1/sqrt(2.0);
// 	N_02.Y = -1/sqrt(2.0);
// 	N_02.Z = 0;
// 	PointXYZ N_2 = RtPoint(Sx,N_02);
// 	double M2[9] = {0};
// 	RMirror(N_2,M2);

// 	// 平面镜3零位的法向量
// 	PointXYZ N_03;
// 	N_03.X = 1/sqrt(2.0);
// 	N_03.Y = -1/sqrt(2.0);
// 	N_03.Z = 0;
// 	PointXYZ N_3 = RtPoint(Sx,N_03);
// 	double M3[9] = {0};
// 	RMirror(N_3,M3);

// 	// 平面镜4零位的法向量
// 	PointXYZ N_04;
// 	N_04.X = -1/sqrt(2.0);
// 	N_04.Y = 1/sqrt(2.0);
// 	N_04.Z = 0;
// 	PointXYZ N_4 = RtPoint(Sx,N_04);
// 	double M4[9] = {0};
// 	RMirror(N_4,M4);

// 	// 等效物方出射矢量
// 	PointXYZ worldPosVec = RtPoint(M1,RtPoint(M2,RtPoint(M3,RtPoint(M4,CamVec))));
// 	PointXYZ worldPosVec_1 = NormPoint(worldPosVec);

//     ServoPole.alpha = ANGLE(asin(worldPosVec_1.Y));
// 	ServoPole.beta = ANGLE(atan2(worldPosVec_1.Z,worldPosVec_1.X));
// 	ServoPole.distance = 1000;

// 	return ServoPole;

// }

// // S726物方到像方转换
// void getPointMirrorImageXYFromServoPole(int* Col,int* Row,int nWidth,int nHeight,float WAlaph,float WBeta,
// 										float fServoA,float fServoB,float fLen,float pxSizeOfum)
// {
// 	//物方
// 	int dep = 1000;
// 	PointXYZ WorldVec;
// 	WorldVec.Y = -dep * sin(RADIAN(WAlaph));
// 	WorldVec.X = -dep * cos(RADIAN(WAlaph)) * cos(RADIAN(WBeta));
// 	WorldVec.Z = -dep * cos(RADIAN(WAlaph)) * sin(RADIAN(WBeta));

// 	// 内参矩阵
// 	float f_0 = fLen/pxSizeOfum * 1000;

// 	double K[9] = 
// 	{f_0,0,nWidth/2,
// 	0,f_0,nHeight/2,
// 	0,0,1};

// 	// 平面镜1零位的法向量
// 	PointXYZ N_01;
// 	N_01.X = 1/sqrt(2.0);
// 	N_01.Y = 1/sqrt(2.0);
// 	N_01.Z = 0;

// 	double Sx[9] = {1,0,0,
// 		0,cos(RADIAN(fServoB)),-sin(RADIAN(fServoB)),
// 		0,sin(RADIAN(fServoB)),cos(RADIAN(fServoB))};

// 	double Sy[9] = {cos(RADIAN(fServoA)),0,-sin(RADIAN(fServoA)),
// 		0,1,0,
// 		sin(RADIAN(fServoA)),0,cos(RADIAN(fServoA))};

// 	PointXYZ N_1 = RtPoint(Sx,RtPoint(Sy,N_01));
// 	// 镜面反射矩阵
// 	//	M = eye(3)-(2*N*N');
// 	double M1[9] = {0};
// 	RMirror(N_1,M1);


// 	// 平面镜2零位的法向量
// 	PointXYZ N_02;
// 	N_02.X = -1/sqrt(2.0);
// 	N_02.Y = -1/sqrt(2.0);
// 	N_02.Z = 0;
// 	PointXYZ N_2 = RtPoint(Sx,N_02);
// 	double M2[9] = {0};
// 	RMirror(N_2,M2);

// 	// 平面镜3零位的法向量
// 	PointXYZ N_03;
// 	N_03.X = 1/sqrt(2.0);
// 	N_03.Y = -1/sqrt(2.0);
// 	N_03.Z = 0;
// 	PointXYZ N_3 = RtPoint(Sx,N_03);
// 	double M3[9] = {0};
// 	RMirror(N_3,M3);

// 	// 平面镜4零位的法向量
// 	PointXYZ N_04;
// 	N_04.X = -1/sqrt(2.0);
// 	N_04.Y = 1/sqrt(2.0);
// 	N_04.Z = 0;
// 	PointXYZ N_4 = RtPoint(Sx,N_04);
// 	double M4[9] = {0};
// 	RMirror(N_4,M4);

// 	PointXYZ camPosVec = RtPoint(M4,RtPoint(M3,RtPoint(M2,RtPoint(M1,WorldVec))));

// 	double m_adjust[9] = {0,0,1,0,1,0,1,0,0};

// 	PointXYZ pixPos = RtPoint(K,RtPoint(m_adjust,camPosVec));

// 	*Col = pixPos.X / float(pixPos.Z);
// 	*Row = pixPos.Y / float(pixPos.Z);



// }




PointXYZ getEOServoXYZFromEOCamXYZ(PointXYZ targetCamXYZ,double alaph,double beta)
{
	// 先绕Z轴俯仰角旋转-alaph，后绕Y轴方位角旋转-beta
	double oppRz[9];
	double oppRy[9];
	double oppRyz[9];

	// 计算旋转矩阵
	Rz(-alaph, oppRz);
	Ry(-beta, oppRy);
	MultiMat33(oppRy,oppRz, oppRyz);

	// 坐标转换
	return RtPoint(oppRyz, targetCamXYZ);
}

PointXYZ getEOBaseXYZFromEOServoXYZ(PointXYZ targetServoXYZ, double eYaw, double ePitch, double eRoll)
{
	// 先绕x轴横滚旋转 -eRoll，再绕z轴俯仰旋转 -ePitch，再绕y轴方位旋转-eYaw

	double oppRx[9];
	double oppRy[9];
	double oppRz[9];
	double oppRyzx[9];

	// 计算旋转矩阵
	Rx(-eRoll, oppRx);
	Rz(-ePitch, oppRz);
	Ry(-eYaw, oppRy);
	
	MultiMat333(oppRy,oppRz, oppRx, oppRyzx);

	// 坐标转换
	return RtPoint(oppRyzx, targetServoXYZ);

}

PointXYZ getCarXYZFromEOBaseXYZ(PointXYZ targetEOBaseXYZ, double deltaX, double deltaY, double deltaZ)
{
	//平台坐标系下目标坐标
	PointXYZ targetCarXYZ;


	targetCarXYZ.X = targetEOBaseXYZ.X + deltaX;
	targetCarXYZ.Y = targetEOBaseXYZ.Y + deltaY;
	targetCarXYZ.Z = targetEOBaseXYZ.Z + deltaZ;

	return targetCarXYZ;
}

PointXYZ getCarNUEXYZFromCarXYZ(PointXYZ targetCarXYZ, double mYaw, double mPitch, double mRoll)
{
	// 先绕x轴横滚旋转 -mRoll，再绕z轴俯仰旋转 -mPitch，再绕y轴方位旋转-mYaw

	double oppRx[9];
	double oppRy[9];
	double oppRz[9];
	double oppRyzx[9];

	// 计算旋转矩阵
	Rx(-mRoll, oppRx);
	Rz(-mPitch, oppRz);
	Ry(-mYaw, oppRy);

	MultiMat333(oppRy,oppRz, oppRx, oppRyzx);

	// 坐标转换
	return RtPoint(oppRyzx, targetCarXYZ);

}

PointXYZ getCarXYZFromCarNUEXYZ(PointXYZ targetCarNUEXYZ, double mYaw, double mPitch, double mRoll)
{
	// 先绕y轴方位旋转mYaw -> 再绕z轴俯仰旋转 mPitch -> 绕x轴横滚旋转 mRoll
	double oppRx[9];
	double oppRy[9];
	double oppRz[9];
	double oppRxzy[9];

	// 计算旋转矩阵
	Ry(mYaw, oppRy);
	Rz(mPitch, oppRz);
	Rx(mRoll, oppRx);

	MultiMat333(oppRx, oppRz, oppRy, oppRxzy);

	// 坐标转换
	return RtPoint(oppRxzy, targetCarNUEXYZ);

}

PointXYZ getEOBaseXYZFromCarXYZ(PointXYZ targetCarXYZ, double deltaX, double deltaY, double deltaZ)
{
	//平台坐标系下目标坐标
	PointXYZ targetEOBaseXYZ;

	targetEOBaseXYZ.X = targetCarXYZ.X - deltaX;
	targetEOBaseXYZ.Y = targetCarXYZ.Y - deltaY;
	targetEOBaseXYZ.Z = targetCarXYZ.Z - deltaZ;

	return targetEOBaseXYZ;
}

PointXYZ getEOServoXYZFromEOBaseXYZ(PointXYZ targetEOBaseXYZ, double eYaw, double ePitch, double eRoll)
{
	// 先绕y轴方位旋转eYaw,再绕z轴俯仰旋转 ePitch,再绕x轴横滚旋转 eRoll
	double oppRx[9];
	double oppRy[9];
	double oppRz[9];
	double oppRxzy[9];

	// 计算旋转矩阵
	Rx(eRoll, oppRx);
	Rz(ePitch, oppRz);
	Ry(eYaw, oppRy);

	MultiMat333(oppRx, oppRz, oppRy, oppRxzy);

	// 坐标转换
	return RtPoint(oppRxzy, targetEOBaseXYZ);

}

PointXYZ getEOCamXYZFromEOServoXYZ(PointXYZ targetEOServoXYZ, double alaph, double beta)
{
	// 先绕Y轴方位角旋转beta,后绕Z轴俯仰角旋转alaph
	double oppRz[9];
	double oppRy[9];
	double oppRzy[9];

	// 计算旋转矩阵
	Rz(alaph, oppRz);
	Ry(beta, oppRy);
	MultiMat33(oppRz, oppRy, oppRzy);

	// 坐标转换
	return RtPoint(oppRzy, targetEOServoXYZ);

}

Pole getPoleFromXYZ(PointXYZ targetXYZ)
{
	double x = targetXYZ.X;
	double y = targetXYZ.Y;
	double z = targetXYZ.Z;

	Pole result;
	result.distance = sqrt(x*x + y*y + z*z);
	result.alpha = ANGLE(asin(y / result.distance));

	//if (x < 0)
	//{
	//	result.alpha = -180-result.alpha;
	//}


	result.beta = (ANGLE(atan2(z , x)));
// 	if (x < 0 && z >= 0) // 90 - 180
// 	{
// 		result.beta = 180 - result.beta;
// 	}
// 	else if (x < 0 && z < 0) // 180 - 270
// 	{
// 		result.beta = result.beta + 180;
// 	}
// 	else if (x >= 0 && z < 0) // 270 - 360
// 	{
// 		result.beta = 360 - result.beta;
// 	}

	return result;

}

PointXYZ getXYZFromPole(Pole targetPole)
{
	// 距离未知时，异原点坐标系之间不能转换
	// 但由于同车坐标系的原点差一般远小于目标距离，故距离较大时误差较小，误差量级可以用线偏差/距离获得的弧度进行估计
	// 如线偏差1米，目标3000米，则转换误差为(1/1000-1/3000)约为0.04°

	// 吊舱无源定位允许最低高度10米
	if (targetPole.distance < 10)
	{
		targetPole.distance = 10000;
	}

	PointXYZ result;
	double aa, bb, cc;
	//double ac = sqrt(targetPole.distance*targetPole.distance-bb*bb);    
	bb = sin(RADIAN(targetPole.alpha)) * targetPole.distance;
	double ac = sqrt(targetPole.distance*targetPole.distance - bb*bb);
	aa = cos(RADIAN(targetPole.beta)) * ac;
	cc = sin(RADIAN(targetPole.beta)) * ac;

	result.X = aa;
	result.Y = bb;
	result.Z = cc;

	return result;

}


//大地坐标转地球空间直角坐标
PointXYZ getXYZFromBLH(PointBLH BLH)
{
	double B = BLH.B;
	double L = BLH.L;
	double H = BLH.H;

	double W = sqrt(1 - ee * pow(sin(RADIAN(B)), 2));
	double N = a / W;          // 椭球的卯酉圈曲率

	// 将地理坐标变换到空间直角坐标
	double X = (N + H) * cos(RADIAN(B)) * cos(RADIAN(L));
	double Y = (N + H) * cos(RADIAN(B)) * sin(RADIAN(L));
	double Z = (N * (1 - ee) + H) * sin(RADIAN(B));

	PointXYZ pointXYZ;
	pointXYZ.X = X;
	pointXYZ.Y = Y;
	pointXYZ.Z = Z;

	return pointXYZ;
}

//地球空间直角坐标-->大地坐标
PointBLH getBLHFromXYZ(PointXYZ pointXYZ)
{
	double X = pointXYZ.X;
	double Y = pointXYZ.Y;
	double Z = pointXYZ.Z;

	double U = atan(Z * a / (sqrt(X * X + Y * Y) * b));
	double B0 = atan((Z + b * epep * pow(sin(U), 3)) / (sqrt(X*X + Y*Y) - a*ee*pow(cos(U), 3)));
	double N = a / sqrt(1 - ee * pow(sin(B0), 2));
	//double L = atan(Y /X);
	double L = atan2(Y, X); // 修改为全球范围计算          by wcw04046 @ 2021/02/18

	double H = sqrt(X*X + Y*Y + pow(Z + N*ee*sin(B0), 2)) - N;
	double B = atan(Z / sqrt(X*X + Y*Y) / (1 - ee*N / (N + H)));

	PointBLH pointBLH;
	pointBLH.B = ANGLE(B);
	pointBLH.H = H;
// 	// 此处仅考虑东经
// 	pointBLH.L = ANGLE(L) > 0 ? ANGLE(L) : ANGLE(L) + 180;

	// 修改为全球范围计算          by wcw04046 @ 2021/02/18
	pointBLH.L = ANGLE(L);

	return pointBLH;
}

//*********************************************************************************************
//  由NUE直角坐标变换到CGCS直角坐标
//  targetPointXYZ：NUE下的目标坐标
//  selfPointXYZ：测站在CGCS下的直角坐标
//  返回CGCS下的目标坐标
//*********************************************************************************************
PointXYZ getCGCSXYZFromNUEXYZ(PointXYZ targetPointXYZ, PointXYZ selfPointXYZ)
{
	// 将测站所在位置的CGCS直角坐标变换到地理坐标
	PointBLH selfPointBLH = getBLHFromXYZ(selfPointXYZ);

	/* 由NUE直角坐标变换到CGCS直角坐标*/
	double A[3];
	double G[3];
	double OppRx[9];
	double OppRy[9];
	double OppRz[9];
	double OppRzx[9];
	double OppRzxy[9];

	// 1、计算旋转矩阵
	Rx(-selfPointBLH.B, OppRx);
	Ry(-90, OppRy);
	Rz(90 - selfPointBLH.L, OppRz);

	MultiMat(OppRz, OppRx, OppRzx, 3, 3, 3);
	MultiMat(OppRzx, OppRy, OppRzxy, 3, 3, 3);

	// 2、将NUE直角坐标变换到CGCS直角坐标
	A[0] = targetPointXYZ.X;
	A[1] = targetPointXYZ.Y;
	A[2] = targetPointXYZ.Z;
	MultiMat(OppRzxy, A, G, 3, 3, 1);

	PointXYZ result;
	result.X = G[0] + selfPointXYZ.X;
	result.Y = G[1] + selfPointXYZ.Y;
	result.Z = G[2] + selfPointXYZ.Z;
	return result;
}

//*********************************************************************************************
// 由CGCS直角坐标变换到NUE直角坐标
// targetPointXYZ：CGCS下的目标坐标
// selfPointXYZ：测站在CGCS下的直角坐标
// 返回NUE下的目标坐标
//*********************************************************************************************
PointXYZ getNUEXYZFromCGCSXYZ(PointXYZ targetPointXYZ, PointXYZ selfPointXYZ)
{
	// 将测站所在位置的CGCS直角坐标变换到地理坐标
	PointBLH selfPointBLH = getBLHFromXYZ(selfPointXYZ);

	// 计算中间值
	double dx = targetPointXYZ.X - selfPointXYZ.X;
	double dy = targetPointXYZ.Y - selfPointXYZ.Y;
	double dz = targetPointXYZ.Z - selfPointXYZ.Z;

	/* 由CGCS直角坐标变换到NUE直角坐标 */
	double A[3];
	double G[3];
	double OppRx[9];
	double OppRy[9];
	double OppRz[9];
	double OppRyx[9];
	double OppRyxz[9];

	// 1、计算旋转矩阵
	Rx(selfPointBLH.B, OppRx);
	Ry(90, OppRy);
	Rz(-90 + selfPointBLH.L, OppRz);

	MultiMat(OppRy, OppRx, OppRyx, 3, 3, 3);
	MultiMat(OppRyx, OppRz, OppRyxz, 3, 3, 3);

	// 2、将CGCS直角坐标变换到NUE直角坐标
	A[0] = dx;
	A[1] = dy;
	A[2] = dz;
	MultiMat(OppRyxz, A, G, 3, 3, 1);

	PointXYZ result;
	result.X = G[0];
	result.Y = G[1];
	result.Z = G[2];
	return result;
}


