//---------------------------------------------------------------------------
#ifndef mathToolsH
#define mathToolsH
//---------------------------------------------------------------------------
#include "structs.h"
//---------------------------------------------------------------------------
#ifndef PI
#define PI 3.1415926535897932384626433832795
#endif
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
//---------------------------------------------------------------------------
	typedef unsigned int uint4;
	typedef unsigned char uint1;
//---------------------------------------------------------------------------
	int hexCharToInt(char input); //Шеснадцатеричный символ в число
	bool testBit(const unsigned char *mas,const unsigned char pos); //проверка значения бита
	void setBit(unsigned char *mas,const unsigned char pos,bool val);//установить заданный бит в 1 или в 0

	uint1 setBitVal(uint1 bit,uint1 pos,bool val); //<Установит знначение бита в заданную позицию
	bool getBitVal(uint1 bit,uint1 pos); //<Вернёт значение бита на заданной позиции
	long getBaudRate(long s);
	int MaxI4(int v1,int v2);

	//Побайтное шифрование
	void Encrypt(unsigned char* key, unsigned short keylen, unsigned char* data, unsigned short datalen); //Шифровать
	void Decrypt(unsigned char* key, unsigned short keylen, unsigned char* data, unsigned short datalen); //Дешифровать

	unsigned char CRC8(const char *pcBlock, unsigned char len, unsigned char crc = 0x0); //Простое вычисление CRC (как для GPS)
	unsigned short Crc16(unsigned char ch, unsigned short crc = 0xFFFF);
	unsigned short Crc16(const char *pcBlock, unsigned short len, unsigned short crc = 0xFFFF);

	
	float sqr(float val);
	double sqr(double val);
	void CalcNormals(float x0, float y0, float z0, float x1, float y1, float z1, float x2, float y2, float z2, float &xr, float &yr, float &zr);
	void fnCalcCircle(RfPointXYZ p1, RfPointXYZ p2, RfPointXYZ p3, float &a, float &b, float &r); //по 3 точкам в пространстве узнать коэфициенты уравнения шара

	void NormalInPolar3d(float x, float y, float z, float &AngleH, float &AngleV, float &r); //результат в радианах
	void NormalInPolar2d(float x, float y, float &Angle, float &r);
	void PolarInNormal3d(double AngleH, double AngleV, double r, float &x, float &y, float &z);
	void PolarInNormal3d(double AngleH, double AngleV, double r, double &x, double &y, double &z);
	float Max(float val1, float val2);
	float Min(float val1, float val2);
	RfPointXYZ getMaxPoint(RfPointXYZ point1, RfPointXYZ point2, RfPointXYZ point3);
	RfPointXYZ getMinPoint(RfPointXYZ point1, RfPointXYZ point2, RfPointXYZ point3);

	double DegToRad(double deg);
	double RadToDeg(double deg);
	double CorrectAngleRad(double angle);

	RfPointXYZ ApproachPoint3d(RfPointXYZ PointXYZ1, RfPointXYZ PointXYZ2, float Distans);
	RfPointXYZ setDistancePoint3d(RfPointXYZ PointXYZ1, RfPointXYZ PointXYZ2, float Distans);
	float fnGetAngle(RfPointXY CenterPoint, RfPointXY ResearchedPoint);
	float fnGetAngleXY(RfPointXYZ CenterPoint, RfPointXYZ ResearchedPoint);
	bool Tessellated2d(unsigned int inPos, unsigned int count, RfPointXYZ *PointsXYZ, unsigned int outPos, RsFacesABC *Vector3i);
	void TrianglesDeloneXY(unsigned int countP, RfPointXYZ *ListPoint, TSimpleList<RTriangle*>* ListEdge); //триангуляция по делоне

	float fnGetDistans2d(RfPointXY PointXY1, RfPointXY PointXY2);
	float fnGetDistans(RfPointXYZ p);
	float fnGetDistans3d(RfPointXYZ PointXYZ1, RfPointXYZ PointXYZ2);

	void Distance(float r, float cx, float cy, float lx1, float ly1, float lx2, float ly2, bool& Coincides, float& x, float& y);
	void MovePointOnAngle(float Angle, RfPointXY CenterPointXY, RfPointXY PointXY, RfPointXY & RezPointXY);
	RfPointXY ApproachPoint2d(RfPointXY PointXY1, RfPointXY PointXY2, float Distans);
	int roundf2(float val);
	int RandInt(int a, int b);
	bool inBox(RfPointXYZ pMin, RfPointXYZ pMax, RfPointXYZ p);//Находиться ли точка в нутри куба заданного минимальной и максимальной точками
	bool inBox(RfPointXYZ pMin, RfPointXYZ pMax, RdPointXYZ p);//Находиться ли точка в нутри куба заданного минимальной и максимальной точками

	void CalcPlane(RfPointXYZ P0, RfPointXYZ P1, RfPointXYZ P2, float &a, float &b, float &c, float &d); //уравнение плоскости по 3м точкам
	void CalcPlane2(RfPointXYZ v, RfPointXYZ p, float &a, float &b, float &c, float &d); //уравнение плоскости по вектору и точке на плоскости
	void CalcPlane2(RdPointXYZ v, RdPointXYZ p, double &a, double &b, double &c, double &d); //уравнение плоскости по вектору и точке на плоскости
																							 //пересичение геометрических фигур
	bool CrossingLine(RfPointXY PHead0, RfPointXY PTail0, RfPointXY PHead1, RfPointXY PTail1, RfPointXY & PRez); //Пересичение 2х линий на плоскости
	bool CrossingLineXY(RfPointXYZ PHead0, RfPointXYZ PTail0, RfPointXYZ PHead1, RfPointXYZ PTail1, RfPointXYZ & PRez); //Пересичение линий в плоскости XY  
	bool CrossingLineAndSphere(double r, RdPointXYZ p0, RdPointXYZ p1, RdPointXYZ p2, RdPointXYZ &rp1, RdPointXYZ &rp2); //пересичение сферы и линии
	bool CrossingLineAndSphere(float r, RfPointXYZ p0, RfPointXYZ p1, RfPointXYZ p2, RfPointXYZ &rp1, RfPointXYZ &rp2); //пересичение сферы и линии
	RfPointXYZ CrossingLineAndPlane(RfPointXYZ p1, RfPointXYZ p2, float a, float b, float c, float d); //пересичении линии и плоскости (линия заданна 2мя точками)
	RdPointXYZ CrossingLineAndPlane(RdPointXYZ p1, RdPointXYZ p2, double a, double b, double c, double d); //пересичении линии и плоскости (линия заданна 2мя точками)
	RfPointXYZ CrossingPlanes(RfPlaneABCD p1, RfPlaneABCD p2, RfPlaneABCD p3); //точка пересичения 3х плоскостей

																			   //работа с векторами
	float ScalarProduct(RfPointXYZ t, RfPointXYZ p); //Умножение векторов
	void normalized(RfPointXYZ &p); //В еденичный
	void normalized(RdPointXYZ &p); //В еденичный
	RfPointXYZ CrossProduct(RfPointXYZ p, RfPointXYZ t);
	RdPointXYZ CrossProduct(RdPointXYZ p, RdPointXYZ t);
	RfPointXYZ dotProduct(RfPointXYZ p, float t);
	float pythagoreanlength(RfPointXYZ p);
	//построение геометрических обьектов 
	void buildIcosahedron(double r, TSimpleList2<RdPointXYZ>* Points, TSimpleList2<RsFacesABC>* Faces); //Икосаэдр
	void buildOctahedron(double r, TSimpleList2<RdPointXYZ>* Points, TSimpleList2<RsFacesABC>* Faces); //Октаэдр

																									   //работа с матрицами
	void quatnext(float* dest, float* left, float* right); //умножение матриц 4x4
	void quatnext(double* dest, double* left, double* right); //умножение матриц 4x4
	void quatidentity(float* q); //сделать еденичной матрицу q[16]
	void quatidentity(double* q); //сделать еденичной матрицу q[16]
	RfPointXYZ MultPointOnRotArray(RfPointXYZ point, double* mas); //умножить точку на матрицу поворота 4x4
	RdPointXYZ MultPointOnRotArray(RdPointXYZ point, double* mas);
	void TransposeRotMat(double* q); //транспонировать только матрицу вращения
	void LookAt(RfPointXYZ vecEye, RfPointXYZ vecTop, double* q);//заполнить матрицу поворота по заданному вектору  q[16]

	TSimpleList2<RcPointXYZ>* Line3D(signed long int xDis, signed long int yDis, signed long int zDis);

#endif
