#pragma once


#ifndef _GEOOPERATOR_H
#define _GEOOPERATOR_H

#include "BaseConstVariable.h"
#include <Eigen/Core>
#include <Eigen/Dense>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <iostream>


/// <summary>
/// 将经纬度转换为地固参心坐标系
/// </summary>
/// <param name="XYZP">经纬度点--degree</param>
/// <returns>投影坐标系点</returns>
Landpoint   BASECONSTVARIABLEAPI	  LLA2XYZ(const Landpoint& LLA);
void   BASECONSTVARIABLEAPI	LLA2XYZ(const Landpoint& LLA,Point3& XYZ);
Eigen::MatrixXd    BASECONSTVARIABLEAPI	 LLA2XYZ(Eigen::MatrixXd landpoint);

/// <summary>
/// 将地固参心坐标系转换为经纬度
/// </summary>
/// <param name="XYZ">固参心坐标系</param>
/// <returns>经纬度--degree</returns>
Landpoint   BASECONSTVARIABLEAPI	  XYZ2LLA(const Landpoint& XYZ);


Landpoint   BASECONSTVARIABLEAPI	  operator +(const Landpoint& p1, const Landpoint& p2);

Landpoint     BASECONSTVARIABLEAPI	operator -(const Landpoint& p1, const Landpoint& p2);

bool     BASECONSTVARIABLEAPI	operator ==(const Landpoint& p1, const Landpoint& p2);

Landpoint    BASECONSTVARIABLEAPI	 operator *(const Landpoint& p, double scale);

double    BASECONSTVARIABLEAPI	 getAngle(const Landpoint& a, const Landpoint& b);

double    BASECONSTVARIABLEAPI	 dot(const Landpoint& p1, const Landpoint& p2);

double    BASECONSTVARIABLEAPI	 getlength(const Landpoint& p1);

Landpoint    BASECONSTVARIABLEAPI	 crossProduct(const Landpoint& a, const Landpoint& b);


Landpoint    BASECONSTVARIABLEAPI	 getSlopeVector(const Landpoint& p0, const Landpoint& p1, const Landpoint& p2, const Landpoint& p3, const Landpoint& p4, bool inLBH=true);

double   BASECONSTVARIABLEAPI	getlocalIncAngle(Landpoint& satepoint, Landpoint& landpoint, Landpoint& slopeVector);

float    BASECONSTVARIABLEAPI	 cross2d(Point3 a, Point3 b);

Point3   BASECONSTVARIABLEAPI	  operator -(Point3 a, Point3 b);

Point3    BASECONSTVARIABLEAPI	 operator +(Point3 a, Point3 b);

double   BASECONSTVARIABLEAPI	  operator /(Point3 a, Point3 b);



// 矢量计算 
struct Vector3D {
	double x, y, z;
};

// 计算两点之间的距离
double   BASECONSTVARIABLEAPI	  distance(const Vector3D& p1, const Vector3D& p2);
// 计算点到直线的最短距离
double   BASECONSTVARIABLEAPI	  pointToLineDistance(const Vector3D& point, const Vector3D& linePoint, const Vector3D& lineDirection);

Vector3D   BASECONSTVARIABLEAPI	  operator +(const Vector3D& p1, const Vector3D& p2);

Vector3D   BASECONSTVARIABLEAPI	  operator -(const Vector3D& p1, const Vector3D& p2);

bool   BASECONSTVARIABLEAPI	  operator ==(const Vector3D& p1, const Vector3D& p2);

Vector3D   BASECONSTVARIABLEAPI	  operator *(const Vector3D& p, double scale);

Vector3D   BASECONSTVARIABLEAPI	  operator *(double scale,const Vector3D& p );

double   BASECONSTVARIABLEAPI	  getAngle(const Vector3D& a, const Vector3D& b);

double   BASECONSTVARIABLEAPI	  getCosAngle(const Vector3D& a, const Vector3D& b);

double   BASECONSTVARIABLEAPI	  dot(const Vector3D& p1, const Vector3D& p2);

double   BASECONSTVARIABLEAPI	  getlength(const Vector3D& p1);

Vector3D    BASECONSTVARIABLEAPI	 crossProduct(const Vector3D& a, const Vector3D& b);



/// <summary>
///      n1
///   n4 n0 n2           
///      n3
/// </summary>
/// <param name="n0"></param>
/// <param name="n1"></param>
/// <param name="n2"></param>
/// <param name="n3"></param>
/// <param name="n4"></param>
/// <returns></returns>
Vector3D  BASECONSTVARIABLEAPI	 getSlopeVector(const Vector3D& n0, const Vector3D& n1, const Vector3D& n2, const Vector3D& n3, const Vector3D& n4);


struct CartesianCoordinates {
	double x, y, z;
};

struct SphericalCoordinates {
	double r, theta, phi;
};

SphericalCoordinates    BASECONSTVARIABLEAPI	 cartesianToSpherical(const CartesianCoordinates& cartesian);

CartesianCoordinates   BASECONSTVARIABLEAPI	  sphericalToCartesian(const SphericalCoordinates& spherical);

double   BASECONSTVARIABLEAPI	getlocalIncAngle(Vector3D& satepoint, Vector3D& landpoint, Vector3D& slopeVector);


#endif