You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

698 lines
15 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "StdAfx.h"
#include "GlobalFunction.h"
#include "PropertiesWnd.h"
#include "BitOperation.h"
#include "GlobalDrawMgr.h"
#include<math.h>
#include "MsgBox.h"
#if 1
//获取当前视类指针
CLaiPuLaserView *GetCurViewPtr()
{
CMainFrame *pFrame = (CMainFrame*)AfxGetApp()->GetMainWnd();
CChildFrame *pChild = (CChildFrame*)pFrame->GetActiveFrame();
CLaiPuLaserView *pView = (CLaiPuLaserView*)pChild->GetActiveView();
return pView;
}
//获取当前文件指针
CLaiPuLaserDoc *GetCurDocPtr()
{
CLaiPuLaserView *pView = GetCurViewPtr();
CLaiPuLaserDoc *pDoc = pView->GetDocument();
return pDoc;
}
CMainFrame* GetFrame()
{
CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->GetMainWnd();
return pFrame;
}
//获取layer 的实例
CLayer &GetLayerInstance()
{
return CLayer::Instance();
}
#endif
#if 1//矩形范围相关函数
//点是否在矩形中
bool IsPointInRect(Dbxy point,DbRect rect)
{
if(point.x>= rect.L && point.x<=rect.R && point.y<= rect.T && point.y>=rect.B)
return true;
else
return false;
}
//两个矩形是否相交
bool IsTwoRectIntersect(DbRect &rect1,DbRect &rect2)
{
if((((rect2.L>=rect1.L)&&(rect2.L<=rect1.R)) || ((rect2.R>=rect1.L)&&(rect2.R<=rect1.R))) &&
(((rect2.T>=rect1.B)&&(rect2.T<=rect1.T)) || ((rect2.B>=rect1.B)&&(rect2.B<=rect1.T))))
return true;
else
return false;
}
//判断点形成的直线是否可能和rect 相交
//Radius 是直线的一半长度mm
bool IsLineAndRectIntersect(Dbxy pt,DbRect rect,double Ang,double Radius)
{
//计算直线的端点
Dbxy StartPt(Radius*(-1),pt.y);
Dbxy EndPt(Radius,pt.y);
StartPt = RotatoPt(StartPt,Ang,pt);
EndPt = RotatoPt(EndPt,Ang,pt);
return IsLineInRect(StartPt,EndPt,rect);
}
//判断线段是否在矩形中
bool IsLineInRect(Dbxy point1,Dbxy point2,DbRect rect)
{
if(IsTwoLineIntersect(point1,point2,Dbxy(rect.R,rect.T),Dbxy(rect.L,rect.B)))
return true;
if(IsTwoLineIntersect(point1,point2,Dbxy(rect.L,rect.T),Dbxy(rect.R,rect.B)))
return true;
if(IsPointInRect(point1,rect) || IsPointInRect(point2,rect))
return true;
return false;
}
void AdjustRange(double &min,double &max,double val)
{
if(min>max)//第一个点
{
min = max = val;
}
else
{
if(min > val)
{
min = val;
}
if(max < val)
{
max = val;
}
}
}
//获取数据点的边界范围
DbRect GetDbPointVecRect(vector<Dbxy> &vec)
{
DbRect rect;
vector<Dbxy>::iterator iter = vec.begin();
vector<Dbxy>::iterator iter_end = vec.end();
for(;iter!=iter_end;iter++)
{
AdjustRectByPoint(rect,(*iter));
}
return rect;
}
//根据一个点来扩大矩形范围
void AdjustRectByPoint(DbRect &rect,Dbxy pt)
{
AdjustRange(rect.L,rect.R,pt.x);
AdjustRange(rect.B,rect.T,pt.y);
}
//根据一个矩形来扩大矩形范围
void AdjustRectByRect(DbRect &rect1,DbRect rect2)
{
Dbxy pt1(rect2.L,rect2.T);
Dbxy pt2(rect2.R,rect2.B);
AdjustRectByPoint(rect1,pt1);
AdjustRectByPoint(rect1,pt2);
}
#endif
#if 1//判断两条线段是否相交
#define EPS 1e-8
#define ZERO(x) (((x)>0?(x):-(x))<EPS) //判断double 是否为0
//计算交叉乘积(P1-P0)x(P2-P0)
double xmult(Dbxy p1,Dbxy p2,Dbxy p0)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
//判点是否在线段上,包括端点
int dot_online_in(Dbxy p,Dbxy l1,Dbxy l2)
{
return ZERO(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<EPS&&(l1.y-p.y)*(l2.y-p.y)<EPS;
}
//判两点在线段同侧,点在线段上返回0
int same_side(Dbxy p1,Dbxy p2,Dbxy l1,Dbxy l2)
{
return xmult(l1,p1,l2)*xmult(l1,p2,l2)>EPS;
}
//判两直线平行
int Parallel(Dbxy u1,Dbxy u2,Dbxy v1,Dbxy v2)
{
return ZERO((u1.x-u2.x)*(v1.y-v2.y)-(v1.x-v2.x)*(u1.y-u2.y));
}
//判三点共线
int dots_inline(Dbxy p1,Dbxy p2,Dbxy p3)
{
return ZERO(xmult(p1,p2,p3));
}
//两条线段是否相交
int IsTwoLineIntersect(Dbxy u1,Dbxy u2,Dbxy v1,Dbxy v2)
{
if (!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2))
return !same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2);
return dot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2);
}
//计算两条线段的交点
Dbxy CalIntersection(Dbxy u1,Dbxy u2,Dbxy v1,Dbxy v2)
{
Dbxy ret=u1;
double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
ret.x+=(u2.x-u1.x)*t;
ret.y+=(u2.y-u1.y)*t;
return ret;
}
void IntersectionOfRectAndLineExt(bool &flg,Dbxy &pt1,Dbxy &pt2,Dbxy u1,Dbxy u2,Dbxy v1,Dbxy v2)
{
if(IsTwoLineIntersect(u1,u2,v1,v2))
{
//如果相交求出交点
Dbxy pt = CalIntersection(u1,u2,v1,v2);
if(flg)
{
pt1 = pt;
}
else
{
pt2 = pt;
}
flg =!flg;
}
}
//计算矩形和线段的交点
Dbxy IntersectionOfRectAndLine(Dbxy LinePt1,Dbxy LinePt2,DbRect rect)
{
bool flg = false;//用来区分保存到点1 还是点2
Dbxy pt1,pt2;
//先求出线段和rect 两条边的交点
{
Dbxy TmpPt1(rect.L,rect.T);
Dbxy TmpPt2(rect.L,rect.B);
IntersectionOfRectAndLineExt(flg,pt1,pt2,LinePt1,LinePt2,TmpPt1,TmpPt2);
}
{
Dbxy TmpPt1(rect.L,rect.B);
Dbxy TmpPt2(rect.R,rect.B);
IntersectionOfRectAndLineExt(flg,pt1,pt2,LinePt1,LinePt2,TmpPt1,TmpPt2);
}
{
Dbxy TmpPt1(rect.R,rect.B);
Dbxy TmpPt2(rect.R,rect.T);
IntersectionOfRectAndLineExt(flg,pt1,pt2,LinePt1,LinePt2,TmpPt1,TmpPt2);
}
{
Dbxy TmpPt1(rect.R,rect.T);
Dbxy TmpPt2(rect.L,rect.T);
IntersectionOfRectAndLineExt(flg,pt1,pt2,LinePt1,LinePt2,TmpPt1,TmpPt2);
}
//返回两个点的中间点
return CenterPtOfTwoPoint(pt1,pt2);
}
//计算两个点的中间的点
Dbxy CenterPtOfTwoPoint(Dbxy Pt1,Dbxy Pt2)
{
Dbxy ret;
ret.x = (Pt1.x+Pt2.x)/2;
ret.y = (Pt1.y+Pt2.y)/2;
return ret;
}
#endif
#if 1//计算函数
//反正切角转换为360 角
double AngleTo360(double Angle)
{
double _360Angle;
_360Angle = - Angle*180/PI;
//校正为正值
if(_360Angle < 0)
{
_360Angle += 360;
}
if(_360Angle > 180)
{
_360Angle -= 360;
}
return _360Angle;
}
//360 角转换为弧度(360°角=2π弧度)
double _360ToAngle(double _360Angle)
{
double Angle;
Angle = (_360Angle*PI)/180;
return Angle;
}
//计算反正切角度StartPt: 旋转起始点EndPt: 旋转结束点CenterPt: 旋转中心点
double CalAngle(Dbxy CenterPt,Dbxy StartPt,Dbxy EndPt)
{
double x2 = CenterPt.x;
double y2 = CenterPt.y;
double x1 = StartPt.x;
double y1 = StartPt.y;
double x3 = EndPt.x;
double y3 = EndPt.y;
double flRlt,flAtanA,flAtanB;
//从中心点竖方向开始旋转
if(x1==x2)
{
if(y1>y2)
{
flAtanA=PI/2;
}else if(y1<y2)
{
flAtanA=-PI/2;
}else
{
flAtanA=0;
}
flAtanB = 0;
}
//旋转到中心点竖方向
else if(x3==x2)
{
if(y3>y2)
{
flAtanB=PI/2;
}else if(y3<y2)
{
flAtanB=-PI/2;
}else
{
flAtanB=0;
}
flAtanA=0;
}
else
{
//反正切函数atan 可以将斜率转换为角度
flAtanA=atan((y1-y2)/(x1-x2));
flAtanB=atan((y3-y2)/(x3-x2));
if(y1-y2>0&&x1-x2<0){
flAtanA+=PI;
}
if(y1-y2<=0&&x1-x2<0){
flAtanA+=PI;
}
if(y3-y2>0&&x3-x2<0){
flAtanB+=PI;
}
if(y3-y2<=0&&x3-x2<0){
flAtanB+=PI;
}
}
flRlt=flAtanB-flAtanA;
return flRlt*(-1);
}
//通过两个点计算360 度角
double Cal360AngleByTwoPt(Dbxy pt1,Dbxy pt2)
{
Dbxy StartPt;
StartPt.x = CalDistance(pt1,pt2);
StartPt.y = pt1.y;
//先计算反正切角
double angle = CalAngle(pt1,StartPt,pt2);
return AngleTo360(angle);
}
//旋转一个点,返回旋转后的点
//Angle 是弧度角CenterPt 是旋转中心点
Dbxy RotatoPt(Dbxy pt,double Angle,Dbxy CenterPt)
{
Dbxy ret;
//旋转-----------------------------------------------
ret.x = ((pt.x-CenterPt.x)*cos(Angle)-(pt.y-CenterPt.y)*sin(Angle))+CenterPt.x;
ret.y = ((pt.y-CenterPt.y)*cos(Angle)+(pt.x-CenterPt.x)*sin(Angle))+CenterPt.y;
return ret;
}
//根据第一个点,线段的长度,角度计算出线段第二个点
//angle 是弧度角
Dbxy GetPoint2(Dbxy point1,double length,double angle)
{
Dbxy point2;
point2.x = point1.x+length*cos(angle);
point2.y = point1.y+length*sin(angle);
return point2;
}
#endif
#if 1
//判断两个double 是否相等
bool IsTwoDbEqual(double a,double b)
{
if((abs(a-b))<=COORD_EPS)
return true;
else
return false;
}
bool IsTwoDbPtEqual(Dbxy pt1,Dbxy pt2,double eps)
{
if(((abs(pt1.x-pt2.x))<=eps)&&((abs(pt1.y-pt2.y))<=eps))
return true;
else
return false;
}
bool IsTwoDbEqual(double a,double b,double eps)
{
if((abs(a-b))<=eps)
return true;
else
return false;
}
bool IsDbEqualZero(double num)
{
if(num<0)
{
num *= -1;
}
if(num <= COORD_EPS)
return true;
else
return false;
}
bool IsDbxyZero(Dbxy pt)
{
return IsDbEqualZero(pt.x) && IsDbEqualZero(pt.y);
}
void SwapTwoPt(Dbxy &pt1,Dbxy &pt2)
{
Dbxy pt = pt1;
pt1 = pt2;
pt2 = pt;
}
//计算两点之间的距离(勾股定律:Z^2 = X^2 + Y^2)
//返回值肯定是大于0 的
double CalDistance(Dbxy pt1,Dbxy pt2)
{
double flRlt;
flRlt=(pt1.x-pt2.x)*(pt1.x-pt2.x)+(pt1.y-pt2.y)*(pt1.y-pt2.y);
flRlt=sqrt(flRlt);
return flRlt;
}
//计算num 有几位
int GetNumDigit(int num)
{
int cnt = 0;
while(num)
{
num /=10;
cnt++;
}
if(cnt==0)//最少一位
cnt = 1;
return cnt;
}
#endif
#if 1
bool CheckStringIsNum(CString str)
{
CString strSet1 = "qwertyuiopasdfghjklzxcvbnm";
CString strSet2 = "QWERTYUIOPASDFGHJKLZXCVBNM";
CString strSet3 = "!@#$%^&*()_+=[]\\{}|;':\",/<>?";
CString strSet = strSet1+strSet2+strSet3;
if(str.FindOneOf(strSet)==-1)
{
return true;
}
return false;
}
//从str 中提取两个值(例如123.456,789.123)
//提取到Val1 返回1,同时提取到Val1,Val2 返回2
//一个没提取到返回0
int GetTwoNum(CString str,double &Val1,double &Val2)
{
int CommaPos = 0;
//检查是否有逗号
CommaPos = str.Find(',',0);
if(CommaPos!=-1)
{
CString str1(str,CommaPos);
str.Delete(0,CommaPos+1);
CString str2(str);
if(CheckStringIsNum(str1)&&CheckStringIsNum(str2))
{
Val1 = atof(str1);
Val2 = atof(str2);
return 2;
}
}
else
{
if(CheckStringIsNum(str))
{
Val1 = atof(str);
return 1;
}
}
return 0;
}
#endif
#if 1//排序点容器
//通过x 排序
bool CompareDbxyByX(Dbxy pt1,Dbxy pt2)
{
return pt1.x>pt2.x;
}
bool CompareDbxyByY(Dbxy pt1,Dbxy pt2)
{
return pt1.y>pt2.y;
}
#endif
#if 1
//判断shift 是否按下
bool IsShiftKeyDown()
{
if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
return true;
else
return false;
}
#endif
int Byte2Int(BYTE x)
{
BYTE c = 0x80;
int a = (IsBitOn(x,7))?c:0;
x = SetBitOff(x,7);
return x+a;
}
//保留val 小数点后面n 位
double RetainDecimalPlaces(double val,int n)
{
for(int i=0;i<n;i++)
{
val *= 10;
}
int t = (int)val;
val = (double)t;
for(int i=0;i<n;i++)
{
val /= 10;
}
return val;
}
//获取0~ rang 的一个随机值
int GetRandVal(int rang)
{
int ret = rand()%rang;
return ret;
}
//等待一个线程结束
void WaitForThreadExit(CWinThread* pThread)
{
if(pThread == NULL)
return;
DWORD dRet=-2;
MSG msg;
while (1)
{
dRet=MsgWaitForMultipleObjects(1,&pThread->m_hThread,FALSE,INFINITE,QS_ALLINPUT);
if (dRet == WAIT_OBJECT_0)//等待的线程结束
{
break;
}
else if (dRet == WAIT_OBJECT_0+1)//有消息到达,转发
{
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else//错误
{
break;
}
}
}
//检查bool 变量b 为期望值,返回检查结果是否通过
bool CheckBool(bool b,CString msg)
{
if(!b)
{
CMsgBox MsgBox;
MsgBox.Show(msg);
return false;
}
return true;
}
//创建圆数据到Vec
void CreatCircleData(CCirclePar CirclePar,vector<Dbxy> &Vec)
{
Vec.clear();
Dbxy CenterPt = CirclePar.CenterPt;
double Radius = CirclePar.Radius;
int DEdgeCnt = CirclePar.DEdgeCnt;
bool bMerge = CirclePar.bMerge;
double StartAng = CirclePar.StartAng;
double EndAng = CirclePar.EndAng;
if(DEdgeCnt == 0)
{
DEdgeCnt = gDraw->GetCirclePtCnt(Radius);
}
//半径------------------------------------
double EachAngle = 360/DEdgeCnt;
bool Flg = true;//第一个点的标志
double CurrAngle =StartAng;
Dbxy pt;
Dbxy FirstPt;
bool bLastPt = false;
while(CurrAngle<(EndAng+0.001))
{
//角度转换为弧度
double radian = CurrAngle*PI/180;
if(IsDbEqualZero(Radius))//半径为0 则为点
{
pt = CenterPt;
}
else
{
pt.x = CenterPt.x + Radius*cos(radian);
pt.y = CenterPt.y + Radius*sin(radian);
}
if(Flg)
{
Flg = false;
FirstPt = pt;
Vec.push_back(pt);
}
else
{
Vec.push_back(pt);
}
if(bLastPt)
break;
CurrAngle += EachAngle;
if(CurrAngle>EndAng)//最后一个点特殊计算
{
CurrAngle = EndAng;
bLastPt = true;
}
}
//最后一条线段
if(bMerge)
Vec.push_back(FirstPt);
}
//检查n 的范围[Start,end]
bool CheckRange(int n,int Start,int end)
{
return n>=Start && n<=end;
}
#if 1
//n 转换为16 进制字符
char Int2HexChar(int n)
{
char c = '0';
if(n>=0 && n<= 9)
c = '0' + n;
else if(n>=10 && n<= 15)
c = 'A' + n - 10;
return c;
}
//16进制的char 转换为十进制数
int HexChar2Int(char c)
{
int val = 0;
if(c>='0' && c<='9')
val = (c - '0');
else if(c>='A' && c<='F')
val = (c - 'A') + 10;
else if(c>='a' && c<='f')
val = (c - 'a') + 10;
return val;
}
//4字节的16 进制转换为十进制数(比如0707 ---->17991179---->4473)
double _4DigitHex2Double(char *buf,int len)
{
double Sum = 0;
for(int k=0;k<len;k++)
{
double m = len-k-1;
double val = HexChar2Int(buf[k]);
Sum += val*pow(16,m);
}
return Sum;
}
//两个字符转换为16 进制数
//比如charA = 'B' ,charB = 'F' 转换为 0xBF (191)
int _2CharToHex(char charA,char charB)
{
int a = HexChar2Int(charA);
int b = HexChar2Int(charB);
return a*16 + b;
}
/*整型数转换为2 字节16 位数
比如5000的16 进制为0x1388 ,转换结果
buf[0] = 0x13
buf[1] = 0x88
*/
void IntTo2ByteHex(int n,char *buf)
{
char TmpBuf[128];
memset(TmpBuf,0,128);
//5000->"1388"
itoa(n,TmpBuf,16);
int len = strlen(TmpBuf);
char CharBuf4[4];
memset(CharBuf4,0,4);
int idx = 3;
while(len>0 && idx>=0)
{
CharBuf4[idx] = TmpBuf[len-1];//保存在TmpBuf 的后面几位
len--;
idx--;
}
buf[0] = _2CharToHex(CharBuf4[0],CharBuf4[1]);//0x13
buf[1] = _2CharToHex(CharBuf4[2],CharBuf4[3]);//0x88
}
//1138--->5000 2008--->8200
int HexByte2Int(int Byte1,int Byte2)
{
int Byte4 = Byte1%16;
int Byte3 = (Byte1-Byte4)/16;
int Byte6 = Byte2%16;
int Byte5 = (Byte2-Byte6)/16;
int val =0;
val = (Byte3)*16*16*16+(Byte4)*16*16+(Byte5)*16+(Byte6);
return val;
}
#endif