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.
TwoLaserHead-PushJig/LaiPuLaser/DxfReadMgr.cpp

1072 lines
27 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 "DxfReadMgr.h"
#include "LogMgr.h"
#include "GlobalFunction.h"
#include "SmartPtr.h"
#include "ObjCircle.h"
#include "ObjPline.h"
#include "DataPoint.h"
#include "GlobalDefine.h"
#include "CommandMgr.h"
#include "WorkRecord.h"
#include "WorkFileMgr.h"
#include "ProgramCutMgr.h"
#include "FileMgr.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#if 1
float x,y,z;
CPos::CPos()
{
x = 0.0;
y = 0.0;
z = 0.0;
}
CPos::CPos(float tx, float ty, float tz)
{
x = tx;
y = ty;
z = tz;
}
CPos::CPos(POS tpos)
{
x = tpos.x;
y = tpos.y;
z = tpos.z;
}
CPos::CPos(CPoint pot)
{
x = (float)pot.x;
y = (float)pot.y;
z = 0.0;
}
CPos::~CPos()
{
}
float CPos::Clear()
{
x = 0.0;
y = 0.0;
z = 0.0;
return 0;
}
CPos CPos::operator =(CPos pos)
{
x = pos.x;
y = pos.y;
z = pos.z;
return *this;
}
CPos CPos::operator =(int pos)
{
x = (float)pos;
y = (float)pos;
z = (float)pos;
return *this;
}
CPos CPos::operator+(CPos pos)
{
CPos tmp;
tmp.x = x + pos.x;
tmp.y = y + pos.y;
tmp.z = z + pos.z;
return tmp;
}
CPos CPos::operator-(CPos pos)
{
CPos tmp;
tmp.x = x - pos.x;
tmp.y = y - pos.y;
tmp.z = z - pos.z;
return tmp;
}
bool CPos::operator==(CPos pos)
{
if ((x==pos.x) && (y==pos.y) && (z=pos.z))
return true;
else
return false;
}
CPoint Point(CPos pos)
{
CPoint tmp;
tmp.x = (int)pos.x;
tmp.y = (int)pos.y;
return tmp;
}
#endif
#if 1
const int MAX_NUMBER=500;
int a;
CString tr;
bool finded = false;
#if 1
//定义读取strMarket标签
#define READ_MARKET(strMarket) \
if (!feof(fp) && !ferror(fp))\
{\
tr.Empty();\
fscanf(fp, "%s\n", m_str);\
a++;\
while(strcmp(m_str, strMarket) != 0)\
{\
fscanf(fp, "%s\n", m_str);\
a++;\
}}
#endif
//比较标签数组内容
#define CMP(array, num) \
for (int i=0; i<num; i++) \
{\
if (finded)\
break;\
if(strcmp(m_str, array##[i]) == 0)\
finded = true;\
else\
finded = false;\
}
//定义读取strMarket标签数组-------------------------------------------????????????????????????
#define READ_MARKETARRAY(strMarket, num) \
if (!feof(fp) && !ferror(fp))\
{\
tr.Empty();\
finded = false;\
fscanf(fp, "%s\n", m_str);\
a++;\
CMP(strMarket, num);\
while(!finded)\
{\
fscanf(fp, "%s\n", m_str);\
a++;\
CMP(strMarket, num);\
}\
}
/*
*/
bool bbreak=false;//已搜索至段尾
//搜索读取value数值
#define READ_VALUE1(strVal) \
ASSERT(fp!=NULL);\
bbreak=false;\
if (!feof(fp) && !ferror(fp))\
{\
fscanf(fp,"%s\n", m_str);\
while(strcmp(m_str, strVal) != 0)\
{\
if(strcmp(m_str, "ENDSEC") != 0)\
fscanf(fp,"%s\n", m_str);\
else\
{\
bbreak=true;\
break;\
}}\
if (!bbreak)\
fscanf(fp,"%f\n", &m_val);\
}
//直接读取value数值
#define READ_VALUE(strVal) \
ASSERT(fp!=NULL);\
if (!feof(fp) && !ferror(fp))\
{\
fscanf(fp,"%s\n", m_str);\
if(strcmp(m_str, strVal) == 0)\
fscanf(fp,"%f\n", &m_val);\
}
//搜索读取value内容
#define READ_STR1(strVal) \
ASSERT(fp!=NULL);\
if (!feof(fp) && !ferror(fp))\
{\
fscanf(fp,"%s\n", m_str);\
while(strcmp(m_str, strVal) == 0)\
{\
fscanf(fp,"%s\n", &m_strcont);\
fscanf(fp,"%s\n", &m_strcont);\
}}
//直接读取value内容
#define READ_STR(strVal) \
ASSERT(fp!=NULL);\
if (!feof(fp) && !ferror(fp))\
{\
fscanf(fp,"%s\n", m_str);\
if(strcmp(m_str, strVal) == 0)\
fscanf(fp,"%s\n", &m_strcont);\
}
//定义读取3维坐标点
#define READ_3DCOORD(number) \
m_pos.Clear();\
if (number == 0)\
{\
READ_VALUE1("10");\
m_pos.x = m_val;\
if(!bbreak)\
{\
READ_VALUE("20");\
m_pos.y = m_val;\
READ_VALUE("30");\
m_pos.z = m_val;\
}\
}\
else if (number == 1)\
{\
READ_VALUE1("11");\
m_pos.x = m_val;\
if(!bbreak)\
{\
READ_VALUE("21");\
m_pos.y = m_val;\
READ_VALUE("31");\
m_pos.z = m_val;\
}\
}
//定义读取2维坐标点
#define READ_2DCOORD(number) \
m_pos.Clear();\
if (number == 0)\
{\
READ_VALUE1("10");\
m_pos.x = m_val;\
if(!bbreak)\
{\
READ_VALUE("20");\
m_pos.y = m_val;\
}\
}\
else if (number == 1)\
{\
READ_VALUE1("11");\
m_pos.x = m_val;\
if(!bbreak)\
{\
READ_VALUE("21");\
m_pos.y = m_val;\
}\
}
//定义读取尺寸界线坐标点
#define READ_JXCOORD(number) \
m_pos.x = 0.0;\
m_pos.y = 0.0;\
m_pos.z = 0.0;\
if (number == 0)\
{\
READ_VALUE1("13");\
m_pos.x = m_val;\
if(!bbreak)\
{\
READ_VALUE("23");\
m_pos.y = m_val;\
READ_VALUE("33");\
m_pos.z = m_val;\
}\
}\
else if (number == 1)\
{\
READ_VALUE1("14");\
m_pos.x = m_val;\
if(!bbreak)\
{\
READ_VALUE("24");\
m_pos.y = m_val;\
READ_VALUE("34");\
m_pos.z = m_val;\
}\
}
CDxfReadMgr *gDxfReadMgr = new CDxfReadMgr;
CDxfReadMgr::CDxfReadMgr(void)
{
b_ShowArcRadius = true;//显示计算的圆弧半径(用来控制只显示一次)
}
CDxfReadMgr::~CDxfReadMgr(void)
{
}
//Angle 是打开以后的旋转角度
#include "ClientMgr.h"
bool CDxfReadMgr::OpenDxfFileDlg(double Angle)
{
CFileDialog FileOpen(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "dxf 文件 (*.dxf)|*.dxf;");
/*CFileMgr fg;
CString exeDir = fg.GetWorkPath();
FileOpen.m_ofn.lpstrInitialDir = exeDir; //指定文件夹*/
if(IDOK == FileOpen.DoModal())
{
CString FilePath=FileOpen.GetPathName();
gClientMgr->SendCmd_OpenFile(FilePath);
//先清除所有obj
CLayer &layer = GetLayerInstance();
layer.SelAllObj();
layer.DelSelObj();
layer.NotSelAllObj();//全不选
if(ReadDxfFile(FilePath))
{
layer.SelAllObj();//全选
layer.OnRotato(Angle);//右旋转90 度
GetCurViewPtr()->MoveSelObjToCenter();//移动到中心区域
layer.NotSelAllObj();//全不选
//清除所有undo 指令,避免操作创建的layer obj 对象
gCommandMgr.Reset();
//设置当前产品型号
CFileMgr FileMgr;
CString s = FileMgr.GetFileNameFromPath(FilePath,true);
gWorkRecordMgr->SetProductType(s);
CWorkFileMgr WorkFileMgr;
WorkFileMgr.SaveFileName(FilePath);
//记录当前打开文件的名字
gProgramCutMgr->SetCurOpenFileName(FileMgr.GetFileNameFromPath(FilePath,true));
gProgramCutMgr->SetCurOpenFileFullName(FilePath);
return true;
}
}
return false;
}
bool CDxfReadMgr::ReadDxfFile(CString FilePath)
{
FILE* fp;
if (FilePath.IsEmpty())
{
gLogMgr->WriteDebugLog("Func : ReadDxfFile ---->Dxf File Path Empty!");//路径为空
return false;
}
fp = fopen(FilePath, "r");
if (!fp)
{
gLogMgr->WriteDebugLog("Func : ReadDxfFile ---->Dxf File Open Error!");
return false;
}
m_LINE.Empty();
m_CIRCLE.Empty();
m_POLYLINE.Empty();
m_ARC.Empty();
m_TEXT.Empty();
m_MTEXT.Empty();
m_DIMENSION.Empty();
b_ShowArcRadius = true;
ReadEntitiesSec(fp);
//gLogMgr->WriteDebugLog(m_POLYLINE);
FilePath = "Func : ReadDxfFile ---->" + FilePath;
gLogMgr->WriteDebugLog(FilePath);
fclose(fp);
return true;
}
void CDxfReadMgr::SetVal(CPos &tagpos)
{
tagpos = m_pos;
}
//提取对象实体
bool CDxfReadMgr::ReadEntitiesSec(FILE* fp)
{
if (fp == NULL)
return false;
CString strBlockWord = _T("LINE, CIRCLE, LWPOLYLINE, ARC, MTEXT, TEXT, DIMENSION");
CString strSynWord = _T("AcDbLine, AcDbCircle, AcDbPolyline, AcDbArc, AcDbMText,AcDbText,AcDbDimension");
CString strDimension[2] ={"AcDbAlignedDimension", "AcDbOrdinateDimension"};
vector<CString> strTypeArray;
LoadSynWord(strBlockWord, strTypeArray);//加载类型关键字
int number[7] = {0};
READ_MARKET("ENTITIES");
fscanf(fp, "%s\n", m_str);
a++;
do {
fscanf(fp,"%s\n", m_str);
a++;
int size = strTypeArray.size();
for (int i=0; i<size; i++)//遍历类型
{
if (strcmp(m_str, strTypeArray[i])==0)//取得相应数据
{
CString str;
switch(i)
{
case 0://直线
number[0]++;
LoadLineData(fp);
break;
case 1://圆
number[1]++;
LoadCircleData(fp);
break;
case 2://多段线
number[2]++;
str.Format("第%d个多段线\r\n",number[2]);
m_POLYLINE += str;
LoadPolyLineData(fp);
break;
case 3://圆弧
number[3]++;
LoadArcData(fp);
break;
case 4://多行文本
number[4]++;
LoadMtextData(fp);
break;
case 5://单行文本
number[5]++;
LoadTextData(fp);
break;
case 6://标注
number[6]++;
LoadDimensionData(fp);
break;
default:
break;
}
}
}
}while(strcmp(m_str, "ENDSEC") != 0);//到达段尾
return true;
}
void CDxfReadMgr::LoadSynWord(CString strSynWord, vector<CString> &strArrayKeyWords)
{
CString strTemp;
int nPosPrior = -1;
int nPos;
nPos = strSynWord.Find(_T(","), 0);
while(nPos!=-1)
{
strTemp = strSynWord.Mid(nPosPrior + 1, nPos - nPosPrior -1);
strTemp.TrimRight();
strTemp.TrimLeft();
strArrayKeyWords.push_back(strTemp);
nPosPrior = nPos;
nPos = strSynWord.Find(_T(","), nPosPrior + 1);
}
strTemp = strSynWord.Mid(nPosPrior +1, strSynWord.GetLength() - nPosPrior -1);
strTemp.TrimRight();
strTemp.TrimLeft();
strArrayKeyWords.push_back(strTemp);
}
bool CDxfReadMgr::LoadLineData(FILE* fp)//加载直线数据
{
CPos pos1, pos2;
CString strtmp;
READ_MARKET("AcDbLine");
READ_3DCOORD(0);
SetVal(pos1);//读取起点坐标
READ_3DCOORD(1);
SetVal(pos2);//读取端点坐标
strtmp.Format("第%d条直线\r\n 起点坐标: x=%.4f y=%.4f z=%.4f \r\n 端点坐标: x=%.4f y=%.4f z=%.4f\r\n", \
2, pos1.x, pos1.y, pos1.z, pos2.x, pos2.y, pos2.z);
m_LINE += strtmp;
//创建多线段对象
CObjPline *pObjPline = new CObjPline;
pObjPline->Creat(Dbxy(pos1.x, pos1.y),Dbxy(pos2.x, pos2.y));
GetLayerInstance().AddObject(pObjPline);
return 0;
}
bool CDxfReadMgr::LoadCircleData(FILE* fp)//加载圆数据
{
CPos pos1;
CString strtmp;
READ_MARKET("AcDbCircle");
READ_3DCOORD(0);
SetVal(pos1);//读取圆心坐标
READ_VALUE("40");//读取圆半径
strtmp.Format("第%d个圆\r\n 圆心坐标: x=%.4f y=%.4f z=%.4f 半径: %.4f\r\n", 3, pos1.x, pos1.y, pos1.z, m_val);
m_CIRCLE += strtmp;
//创建circle 的obj 对象
CObjCircle *p = new CObjCircle;
CCirclePar ObjCirclePar;
ObjCirclePar.CenterPt = Dbxy(pos1.x,pos1.y);
ObjCirclePar.Radius =m_val;
ObjCirclePar.DEdgeCnt = 0;
p->Creat(ObjCirclePar);
GetLayerInstance().AddObject(p);
return 0;
}
//读取一条多段线数据
bool CDxfReadMgr::LoadPolyLineData(FILE* fp)
{
CPos pos[MAX_NUMBER];
float Convexity[MAX_NUMBER];//凸度
memset(Convexity,0,sizeof(float)*MAX_NUMBER);
CString strtmp;
int m;
int PtCnt;
int bClose;//是否闭合
READ_MARKET("AcDbPolyline");
READ_VALUE1("90");//读取定点数
PtCnt = int(m_val);
READ_VALUE1("70");//是否闭合
bClose = int(m_val); //1为闭合
if(PtCnt<2 || PtCnt > MAX_NUMBER)
{
//strtmp.Format("读取第%d个多段线坐标点数%d超过标定数据无法显示!", 3, PtCnt);
return false;
}
bool bFlg10 = true;//是否需要查找10
for(m=0; m<PtCnt; m++)
{
if(bFlg10)
{
READ_VALUE1("10");
m_pos.x = m_val;
}
if(!bbreak)
{
READ_VALUE("20");
m_pos.y = m_val;
SetVal(pos[m]);//读取坐标
if (!feof(fp) && !ferror(fp))
{
fscanf(fp,"%s\n", m_str);
if(strcmp(m_str, ("40")) == 0)
{
READ_VALUE("41");//41 去掉
fscanf(fp,"%s\n", m_str);
fscanf(fp,"%f\n", &m_val);
fscanf(fp,"%s\n", m_str);
}
if(strcmp(m_str, ("10")) == 0)//没有凸度的情况
{
fscanf(fp,"%f\n", &m_val);
m_pos.x = m_val;
bFlg10 = false;
}
else if(strcmp(m_str, ("42")) == 0)//有凸度的情况
{
fscanf(fp,"%f\n", &m_val);
Convexity[m] = m_val;
bFlg10 = true;
}
}
}
}
if(PtCnt<=0)
return 0;
//创建多线段对象
CObjPline *pObjPline = new CObjPline;
//整体偏移到原点
Dbxy AllOffset(pos[0].x-100, pos[0].y-100);
for(int k=0;k<MAX_NUMBER;k++)
{
pos[k].x -= AllOffset.x;
pos[k].y -= AllOffset.y;
}
for (m=0; m<PtCnt; m++)
{
double CurConvexity = Convexity[m];
#if 0
strtmp.Format(" %d端点坐标: x=%.4f y=%.4f z=%.4f \r\n",m, pos[m].x, pos[m].y, pos[m].z);
gLogMgr->WriteDebugLog(strtmp);
strtmp.Format(" %d凸度值=%.4f \r\n",m, CurConvexity);
gLogMgr->WriteDebugLog(strtmp);
#endif
if(m==0)//创建多线段
{
pObjPline->Creat(Dbxy(pos[m].x,pos[m].y),Dbxy(pos[m].x,pos[m].y));
}
else
{
CDataPoint DataPoint(Dbxy(pos[m].x,pos[m].y));
DataPoint.SetIsNode(true);
pObjPline->AddDataPoint(DataPoint);
}
//处理多线段的圆角
if(!IsDbEqualZero(CurConvexity))
{
vector<Dbxy> PtVec;
if(m != PtCnt-1)
{
CreatArcData(Dbxy(pos[m].x,pos[m].y),Dbxy(pos[m+1].x,pos[m+1].y),CurConvexity,PtVec);
}
else//最后一个点特殊处理
{
CreatArcData(Dbxy(pos[m].x,pos[m].y),Dbxy(pos[0].x,pos[0].y),CurConvexity,PtVec);
}
vector<Dbxy>::iterator iter = PtVec.begin();
vector<Dbxy>::iterator iter_end = PtVec.end();
for(;iter!=iter_end;iter++)
{
CDataPoint DataPoint((*iter));
DataPoint.SetIsNode(true);
pObjPline->AddDataPoint(DataPoint);
}
}
}
#if 1
if(bClose)//闭合
{
CDataPoint DataPoint(Dbxy(pos[0].x,pos[0].y));
DataPoint.SetIsNode(true);
pObjPline->AddDataPoint(DataPoint);
}
#endif
//整体偏移回原来的位置
vector<CDataPoint>&PtContainer = pObjPline->GetPtContainer();
int size = PtContainer.size();
for(int k=0;k<size;k++)
{
Dbxy pt = PtContainer[k].GetPt();
pt.x += AllOffset.x;
pt.y += AllOffset.y;
PtContainer[k].SetPt(pt);
}
GetLayerInstance().AddObject(pObjPline);
return 0;
}
bool CDxfReadMgr::LoadArcData(FILE* fp)//加载圆弧数据
{
CString strtmp;
CPos pos;
float nRadio;
float angle1, angle2;
READ_MARKET("AcDbCircle");
READ_3DCOORD(0);
SetVal(pos);//读取圆心坐标
READ_VALUE("40");//读取圆半径
nRadio = m_val;
READ_MARKET("AcDbArc");
READ_VALUE("50");//读取起始角度
angle1 = m_val;
READ_VALUE("51");//读取结束角度
angle2 = m_val;
strtmp.Format("第%d个圆弧\r\n 圆心坐标: x=%.4f y=%.4f z=%.4f 半径: %.4f\r\n 起始角度: %.0f 结束角度: %.0f\r\n", \
4, pos.x, pos.y, pos.z, nRadio, angle1, angle2);
//m_ARC += strtmp;
if(angle1>angle2)
{
angle2 = angle2 + 360;
}
//圆弧创建多线段对象
CCirclePar CirclePar;
vector<Dbxy> PtVec;
CirclePar.StartAng = angle1;
CirclePar.EndAng = angle2;
CirclePar.CenterPt = Dbxy(pos.x,pos.y);
CirclePar.Radius =nRadio;
CirclePar.DEdgeCnt = 0;//根据圆的半径自动选择点数
CirclePar.bMerge = false;//闭合
CreatCircleData(CirclePar,PtVec);
CObjPline *pObjPline = new CObjPline;
vector<Dbxy>::iterator iter = PtVec.begin();
vector<Dbxy>::iterator iter_end = PtVec.end();
for(;iter!=iter_end;iter++)
{
CDataPoint DataPoint((*iter));
DataPoint.SetIsNode(true);
pObjPline->AddDataPoint(DataPoint);
}
GetLayerInstance().AddObject(pObjPline);
return 0;
}
bool CDxfReadMgr::LoadTextData(FILE* fp)//加载单行文本数据
{
CString strtmp;
CPos pos;
float fontheight;
char strcont[50];//字符内容缓冲区**
READ_MARKET("AcDbText");
READ_3DCOORD(0);
SetVal(pos);//读取文本起始坐标
READ_VALUE("40");
fontheight = m_val;//读取文字高度
//
READ_STR("1");
strcpy(strcont, m_strcont);
strtmp.Format("第%d个文字段\r\n 文字坐标: x=%.4f y=%.4f z=%.4f 高度: %.2f \r\n 内容: %s\r\n", \
5, pos.x, pos.y, pos.z, fontheight, strcont);
m_TEXT += strtmp;
return 0;
}
bool CDxfReadMgr::LoadMtextData(FILE* fp)//加载多行文本数据
{
CString strtmp;
CPos pos1;
float fontheight, fontwidth;
char strcont[255];//字符内容缓冲区**
READ_MARKET("AcDbMText");
READ_3DCOORD(0);
SetVal(pos1);//读取文本起始坐标
READ_VALUE("40");
fontheight = m_val;//读取文字高度
READ_VALUE("41");
fontwidth = m_val;//读取文字宽度
READ_VALUE("71");
READ_VALUE("72");
READ_STR("1");
strcpy(strcont, m_strcont);
strtmp.Format("第%d个文字段\r\n 文字坐标: x=%.4f y=%.4f z=%.4f\r\n 高度: %.2f 宽度: %.2f\r\n 内容: %s\r\n", \
5, pos1.x, pos1.y, pos1.z, fontheight, fontwidth, strcont);
m_MTEXT += strtmp;
return 0;
}
bool CDxfReadMgr::LoadDimensionData(FILE* fp)//加载标注数据
{
CString strDimension[2] ={"AcDbAlignedDimension", "AcDbOrdinateDimension"};
CString strtmp;
CPos pos1, pos2, pos3, pos4;
char strcont[255];//字符内容缓冲区**
READ_MARKET("AcDbDimension");
READ_3DCOORD(0);
SetVal(pos1);//读取尺寸线定义点
READ_3DCOORD(1);
SetVal(pos2);//读取标注位置
READ_VALUE("70");
READ_VALUE("71");
READ_STR("42");//读取标注内容
strcpy(strcont, m_strcont);
READ_MARKETARRAY(strDimension, 2);
strtmp.Format("第%d个标注\r\n 第一尺寸界线: x=%.4f y=%.4f z=%.4f\r\n 第二尺寸界线: x=%.4f y=%.4f z=%.4f\r\n 尺寸线: x=%.4f y=%.4f z=%.4f\r\n 标注位置: x=%.4f y=%.4f z=%.4f\r\n 文字大小: %d 标注内容: %s\r\n", \
6, pos3.x, pos3.y, pos3.z, pos4.x, pos4.y, pos4.z, \
pos1.x, pos1.y, pos1.z, pos2.x, pos2.y, pos2.z, 20, strcont);
m_DIMENSION += strtmp;
return 0;
}
#if 1
//根据两个端点和凸度计算圆心坐标CenterPoint (u 为凸度)
//返回圆弧的半径
double CDxfReadMgr::GetCenterPtByConvexity(Dbxy BeginPoint,Dbxy EndPoint,double Convexity,Dbxy &CenterPoint)
{
double dConvexityDegree=Convexity; //凸度
double theta_degree ;//角度,包角
double dStarX=0,dStarY=0;//圆弧起始点
double dEndX=0,dEndY=0; //圆弧终止点
double dStarC=0,dEndC=0; //圆弧起始角度,终止角度
double dmiddleX=0,dmiddleY=0;//起始点和终止点连接线的中点横纵坐标
double dCenterX=0,dCenterY=0;//圆心坐标
double dCenterX1=0,dCenterY1=0;//圆心坐标1
double dCenterX2=0,dCenterY2=0;//圆心坐标2
double dLength; //弦长
double dfR; //半径
double k = 0.0;//弦的斜率
double k_verticle = 0.0;//弦的中垂线的斜率
double mid_x = 0.0,mid_y = 0.0;//弦的中点坐标
double a = 1.0;
double b = 1.0;
double c = 1.0;
double angleChordX=0;//弦向量X正方向的角度
int direction=0;//判断是G02还是G03
bool isMinorArc=TRUE;//圆弧半径是否为较小的
double dStartVale=0; //起始角的cosdStarC
double dEndVale=0; //终止角的cosdEndC
//当凸度dConvexityDegree不等于0时表示为圆弧
if (0!=dConvexityDegree)
{
theta_degree = 4*atan(fabs(dConvexityDegree));
//起始点,终止点
dStarX = BeginPoint.x;
dStarY = BeginPoint.y;
dEndX = EndPoint.x;
dEndY = EndPoint.y;
//弦长
dLength = sqrt(pow(dStarX-dEndX,2)+pow(dStarY-dEndY,2));
//计算圆弧半径
dfR = fabs(0.5*dLength/sin(0.5*theta_degree));
k = (dEndY - dStarY) / (dEndX - dStarX);
if(k == 0)
{
dCenterX1 = (dStarX + dEndX) / 2.0;
dCenterX2 = (dStarX + dEndX) / 2.0;
dCenterY1 = dStarY + sqrt(dfR * dfR -(dStarX - dEndX) * (dStarX - dEndX) / 4.0);
dCenterY2 = dEndY - sqrt(dfR * dfR -(dStarX - dEndX) * (dStarX - dEndX) / 4.0);
}
else
{
k_verticle = -1.0 / k;
mid_x = (dStarX + dEndX) / 2.0;
mid_y = (dStarY + dEndY) / 2.0;
a = 1.0 + k_verticle * k_verticle;
b = -2 * mid_x - k_verticle * k_verticle * (dStarX + dEndX);
c = mid_x * mid_x + k_verticle * k_verticle * (dStarX + dEndX) * (dStarX + dEndX) / 4.0 -
(dfR * dfR - ((mid_x - dStarX) * (mid_x - dStarX) + (mid_y - dStarY) * (mid_y - dStarY)));
dCenterX1 = (-1.0 * b + sqrt(b * b -4 * a * c)) / (2 * a);
dCenterX2 = (-1.0 * b - sqrt(b * b -4 * a * c)) / (2 * a);
dCenterY1 = k_verticle*dCenterX1 -k_verticle*mid_x+mid_y;
dCenterY2 = k_verticle*dCenterX2 -k_verticle*mid_x+mid_y;
}
//凸度绝对值小于1表示圆弧包角小于180°凸度绝对值大于1表示圆弧包角大于180°
if (fabs(dConvexityDegree)<=1)
isMinorArc=TRUE;
else
isMinorArc=FALSE;
//确定圆弧的顺逆
if (0>dConvexityDegree)
direction=2;
else
direction=3;
//确定圆心 ------------------------------------------------------
angleChordX=acos((1*(dEndX-dStarX)+0*(dEndY-dStarY))/dLength)*180/PI;
if ((dEndY-dStarY)<0)
{
angleChordX*=-1;
}
if ((angleChordX>0 && angleChordX<180)||angleChordX==180)
{
if (direction==2)//顺圆
{
if(isMinorArc)
{
dCenterX=dCenterX1;
dCenterY=dCenterY1;
}
else
{
dCenterX=dCenterX2;
dCenterY=dCenterY2;
}
}
else if (direction==3)//逆圆
{
if (isMinorArc)
{
dCenterX=dCenterX2;
dCenterY=dCenterY2;
}
else
{
dCenterX=dCenterX1;
dCenterY=dCenterY1;
}
}
}
else
{
if (direction==2)//顺圆
{
if(isMinorArc)
{
dCenterX=dCenterX2;
dCenterY=dCenterY2;
}
else
{
dCenterX=dCenterX1;
dCenterY=dCenterY1;
}
}
else if (direction==3)//逆圆
{
if (isMinorArc)
{
dCenterX=dCenterX1;
dCenterY=dCenterY1;
}
else
{
dCenterX=dCenterX2;
dCenterY=dCenterY2;
}
}
}
}
CenterPoint.x = dCenterX;
CenterPoint.y = dCenterY;
return dfR;
}
//创建多线段的圆角数据Convexity 为凸度
void CDxfReadMgr::CreatArcData(Dbxy Pt1,Dbxy Pt2,double Convexity,vector<Dbxy> &PtVec)
{
int times = 10;
int OffsetTimes = 0;
Dbxy Offset;
for(int k=0;k<times;k++)
{
if(OffsetTimes>0)
{
//避免有时候计算错误没有数据,偏移一点再来一次
double Gap = 0.000001;
Pt1.x += Gap;
Pt1.y += Gap;
Pt2.x += Gap;
Pt2.y += Gap;
Offset.x += Gap;
Offset.y += Gap;
}
//计算弧线的圆心点-------------------------------------
Dbxy CenterPoint;
double R = GetCenterPtByConvexity(Pt1,Pt2,Convexity,CenterPoint);
if(b_ShowArcRadius)
{
CString LogStr;
LogStr.Format(_T("[圆弧半径ArcRadius] = [%f]"),R);
gLogMgr->WriteDebugLog(LogStr);
LogStr.Format(_T("[CenterPoint.x] = [%f],[CenterPoint.y] = [%f]"),CenterPoint.x,CenterPoint.y);
gLogMgr->WriteDebugLog(LogStr);
LogStr.Format(_T("[Dis1 ] = [%f]"),CalDistance(Pt1,CenterPoint));
gLogMgr->WriteDebugLog(LogStr);
LogStr.Format(_T("[Dis2 ] = [%f]"),CalDistance(Pt2,CenterPoint));
gLogMgr->WriteDebugLog(LogStr);
b_ShowArcRadius = false;
}
//设置弧线参数--------------------------------------------
//主要是这个角度
CCirclePar CirclePar;
double StartAng = Cal360AngleByTwoPt(Pt1,CenterPoint);
double EndAng = Cal360AngleByTwoPt(Pt2,CenterPoint);
if(StartAng<0)
StartAng += 360;
if(EndAng<0)
EndAng += 360;
if(Convexity<0)
{
swap(StartAng,EndAng);
}
if(StartAng>EndAng)
EndAng += 360;
CirclePar.StartAng = StartAng;
CirclePar.EndAng = EndAng;
CirclePar.CenterPt = CenterPoint;
CirclePar.Radius =R;
CirclePar.DEdgeCnt = 0;//根据圆的半径自动选择点数
CirclePar.bMerge = false;
CreatCircleData(CirclePar,PtVec);
if(Convexity<0)//凸度小于0 为顺时针
{
vector<Dbxy>::iterator iter = PtVec.begin();
vector<Dbxy>::iterator iter_end = PtVec.end();
reverse(iter,iter_end);
}
if(!PtVec.empty())
break;
OffsetTimes++;
}
#if 0
//整体性偏移-----------------------------------------
CString LogStr;
LogStr.Format(_T("CreatArcData[OffsetTimes] = [%d]"),OffsetTimes);
gLogMgr->WriteDebugLog(LogStr);
#endif
//偏移回原来的位置
vector<Dbxy>::iterator iter = PtVec.begin();
vector<Dbxy>::iterator iter_end = PtVec.end();
for(;iter!=iter_end;iter++)
{
if(OffsetTimes>0)
{
(*iter).x -= Offset.x;
(*iter).y -= Offset.y;
}
}
}
#endif
#endif