#pragma once
#ifndef GeometriFunction_h
#define GeometriFunction_h
#include "base_head.h"
#include "cartoBaseDef.h"
#include "garray.h"

class UTILES_EXPORT GeometryFunction
{
public:
	//distancia entre 2 ptos
	static double Dist2d(double*p1, double*p2);
	//longitud de la linea
	static double LongLine2d(SetPtsR *line);
	//distancia de un punto p a una linea infinita de puntos l1 y l2
	static double Dpline(double* l1, double *l2, double *p, double *lamb = 0);
	//distancia de punto p a segmento s1-s2
	static double DpSeg(double* s1, double *s2, double *p, double *lamb = 0);
	//interseccion entre lineas (formada por l11-l12) a otra linea (formada por l21-l22)
	static double* intersecLine(double* l11, double *l12, double* l21, double *l22, double *p_inters);
	//distancia entre linea (l1-l2)y segmento(s1,s2)
	static double DLineSeg(double* l1, double *l2, double* s1, double *s2, double *lamdl,double *lambs,  bool*paralelos );
	
	//distancia entre linea (l1-l2)y segmento(s1,s2)
	static double DsegSeg(double* s11, double *s12, double* s21, double *s22, double *lamd1,double *lamb2);
	//distancia de polilinea a segmento
	static double DplineSeg(SetPtsR* line1, double* s1, double *s2,int *n=NULL, double *lamd1=NULL,double *lamb2=NULL);


	//calcula coordenadas minimas y maximas
	static void CompMima(double dst[2][3], SetPtsR* pts);
	//calcula envoltura convexa
	static Cgarray<double[3]>* EnvConvex(SetPtsR* pts, Cgarray<double[3]>* dst);
	//distancia de un punto a una linea
	static double DisPtoLine(SetPtsR* line, double*p, int* idpto=NULL, double *lamb=NULL);
	//distancia media entre dos líneas
	static double DisMedLines( SetPtsR* line1, SetPtsR* line2, double *desv=NULL);
	static double DisMedLines( SetPtsR* line1, SetPtsR* line2, double l_avan, double *desv=NULL);
	//parte una linea en 2
	static bool DivLine(SetPtsR* linesrc, SetPtsW* ldst1, SetPtsW* ldst2,  double dis);
	//dado el ip y el lamb da la distancia desde el principio de la linea
	static double DisInLine(SetPtsR* linesrc, int ip,  double lamb);
	//dado el ip y el lamb da la distancia desde el punto contenido en la línea
	static double *PtInLine( SetPtsR* linesrc, int ip, double lamb , double *pp );
	//devuelve los nptos primeros puntos de line, equiespaciados dis
	//si avanza, los coge del principio, si no, del final
	static SetPtsW *GetNPrimePtos(SetPtsR* line, SetPtsW *ldst,  int nptos, double dis, BOOL avanza);
	
	//divide la linea en partes equidistantes
	static bool DivLine(SetPtsR* line, SetPtsWBuilder *manager,  double dis);

	//devuelve el punto que esta en la polilinea a una distancia dist
	static double* GetPto(SetPtsR* line, double dis, double *dst, double *distTot = NULL);

	static double ang_vect_ptos(double (*ptos1)[][3], double (*ptos2)[][3]);

	//devuelve el angulo que forman los 2 vectores
	static double AngVect(double v1[2], double v2[2]);
	//dice si el punto p esta a la derecha de la linea que forman los puntos ip1 y ip2
	static bool IsDer(SetPtsR* ptos, double *p, int ip1, int ip2);
	static double ProdEscalar(SetPtsR* line1, SetPtsR* line2);

	//funcion auxiliar potencia 
	static inline double Poten(double bas, int exp = 2)
	{
		if(exp<=0)
			return 0;
		double res = bas;
		while(exp>1)
		{
			res = res * bas;
			exp--;
		}
		return res;
	}
};

#endif