#include "stdafx.h" #include "FaultRosesCreator.h" #include const double PI = 3.1415926535897932384626433832795; CFaultRosesCreator::CFaultRosesCreator() :m_iRotateAngle(0) , m_fBarInterval(6) , m_nBarMaxNumber(200) , m_bAutoCalc(FALSE) , m_dCX(0) , m_dCY(0) , m_dR(100) , m_nRealBarMax(0) , m_barColor(RGB(255,0,0)) , m_nCircleTickInterval(45) { m_strLayerCircle = "玫瑰图\\圆框"; m_strLayerTicks="玫瑰图\\刻标"; m_strLayerText="玫瑰图\\文字"; m_strLayerBars = "玫瑰图\\花瓣"; } CFaultRosesCreator::~CFaultRosesCreator() { } void CFaultRosesCreator::Clear() { m_data.clear(); m_rosebars.clear(); } const int SEPNUMBER = 12; int SplitCString(const CString& str, const char * separator, int sep_number, vector &strArray) { strArray.clear(); int index = -1; const int MAX_COUNT = 1000000; //最大分割长度 int smallIndex = MAX_COUNT; CString szLeft; CString szRight = str; for (int i = 0; i< sep_number; i++) { index = szRight.Find(separator[i]); if (index >= 0 && index < smallIndex) { smallIndex = index; //遍历获得所有的分割符的最小Index } if (i == sep_number - 1 && smallIndex != MAX_COUNT) //遍历全部分割符之后 { szLeft = szRight.Left(smallIndex); szLeft.Trim(); //去除空格 if (!szLeft.IsEmpty()) strArray.push_back(szLeft); szRight = szRight.Right(szRight.GetLength() - smallIndex - 1); szRight.Trim(); if (szRight.GetLength()>0) { i = -1; smallIndex = MAX_COUNT; } else break; } else if (i == sep_number - 1) { szRight.Trim(); if (!szRight.IsEmpty()) strArray.push_back(szRight); } } return strArray.size(); } double CFaultRosesCreator::ConvertAngle(double angle) { if (m_iRotateAngle < 1) return angle; double v = angle - 90 ; while (v < 0) v += 360; v = 360 - v; while (v > 360 + 1e-8) v -= 360; while (v < -1e-8) v += 360; return v; } void CFaultRosesCreator::CreateRoseBars(void) { if (m_fBarInterval < 0.01) return; int N = ceil(360.0 / m_fBarInterval); m_rosebars.assign(N, RoseBar()); m_rosebars[0].agl[0] = 0; m_rosebars[0].agl[1] = m_fBarInterval; for (int i = 1; i < N ; i++) { m_rosebars[i].agl[0] = m_rosebars[i-1].agl[1]; m_rosebars[i].agl[1] = m_rosebars[i].agl[0] + m_fBarInterval; } if (m_rosebars[N - 1].agl[1] > 360) m_rosebars[N - 1].agl[1] = 360; list::iterator iter = m_data.begin(); for (; iter != m_data.end(); iter++) { double v = *iter; int i = int(v / m_fBarInterval); if (i < 0) i = 0; if (i > m_rosebars.size() - 1 ) i = m_rosebars.size() - 1; m_rosebars[i].count++; m_nRealBarMax = max(m_nRealBarMax, m_rosebars[i].count); } if (m_bAutoCalc) m_nBarMaxNumber = AutoCalcMapBarMaxNum(); } bool CFaultRosesCreator::ReadFile(CString strInput, int TargetColumn, int iRowStart) { CStdioFile fr; if (!fr.Open(strInput, CFile::modeRead|CFile::shareDenyNone)) { //const char msg[] = "文件路径不存在或无法打开"; return false; } CString line; vector strvec; const char seps[] = { ',' }; for (int i = 0; i < iRowStart; i++) fr.ReadString(line); while (fr.ReadString(line)) { if (line.GetLength() < 3) continue; //if (!::isdigit(line[0])) //{ // continue; //} /*strvec.clear(); SplitCString(line, seps, SEPNUMBER, strvec); if (strvec.size() < TargetColumn) continue;*/ CString csTemp; AfxExtractSubString(csTemp, (LPCTSTR)line, TargetColumn, ','); double v = atof((LPSTR)(LPCTSTR)csTemp); v = ConvertAngle(v); m_data.push_back(v); //对称角度存入data if (v > 180) v -= 180; else v += 180; m_data.push_back(v); } m_data.sort(); return true; } int CFaultRosesCreator::AutoCalcMapBarMaxNum(void) { if (m_nRealBarMax < 1) return 0; const int ticks = 2; double grossstep = m_nRealBarMax / ticks; double step = pow(10.0, floor(log10(grossstep))); if (5 * step < grossstep) step *= 5; else if (2 * step < grossstep) step *= 2; int maxNum = ceil(m_nRealBarMax / step)*step; return maxNum; } void CFaultRosesCreator::WriteDFD(CString strOutput) { FILE* fw = fopen((LPSTR)(LPCTSTR)strOutput,"w"); if(0 == fw) return; WriteDfdHead(fw); WriteLayers(fw); WriteBars( fw); //输出花瓣 WriteBorder( fw); //输出圆框 WriteTicks(fw); //输出刻线 WriteText( fw); //输出文字 fclose(fw); } void CFaultRosesCreator::WriteDfdHead(FILE* fw) { fprintf(fw,"Version 2025\n"); //fprintf(fw,"Copyright DoubleFox\n"); //fprintf(fw,"SoftwareVer 5.0\n"); //fprintf(fw,"BkColor 16777215\n"); fprintf(fw,"Display\n"); fprintf(fw,"%.12g,%.12g\n",m_dCX-m_dR,m_dCY-m_dR); fprintf(fw,"%.12g,%.12g\n",m_dCX+m_dR,m_dCY+m_dR); fprintf(fw,"\n"); fprintf(fw,"ScaleFactor\n"); fprintf(fw,"1000\n"); } void CFaultRosesCreator::WriteLayers(FILE* fw) { fprintf(fw,"Class Layer\n"); fprintf(fw,"\n"); fprintf(fw,"Layer M 0\n"); fprintf(fw,"Layer ViewAndEdit\n"); fprintf(fw,"Layer M 玫瑰图\n"); fprintf(fw,"Layer ViewAndEdit\n"); fprintf(fw,"Layer M %s\n",m_strLayerCircle); fprintf(fw,"Layer ViewAndEdit\n"); fprintf(fw,"Layer M %s\n",m_strLayerTicks); fprintf(fw,"Layer ViewAndEdit\n"); fprintf(fw,"Layer M %s\n",m_strLayerText); fprintf(fw,"Layer ViewAndEdit\n"); fprintf(fw,"Layer M %s\n",m_strLayerBars); fprintf(fw,"Layer ViewAndEdit\n"); fprintf(fw,"\n"); fprintf(fw,"Layer M 0\n"); fprintf(fw,"Layer M 玫瑰图\n"); fprintf(fw,"Layer M %s\n",m_strLayerCircle); fprintf(fw,"Layer M %s\n",m_strLayerTicks); fprintf(fw,"Layer M %s\n",m_strLayerText); fprintf(fw,"Layer M %s\n",m_strLayerBars); //fprintf(fw,"State 10\n"); fprintf(fw, "HowToViewPoint\n"); fprintf(fw, "Font 7 14 0 400 0 0 0 1 0 16 0 0 Times New Roman\n"); fprintf(fw, "Mark 0.0000 0.0000 0.0000\n"); fprintf(fw, "Text 20.0000 8.0000 0.0000 0.0000 -10.0000 76\n"); fprintf(fw, "Color 0 16777215\n"); fprintf(fw, "Mode 2048\n"); fprintf(fw, "\n"); fprintf(fw, "Layer M 玫瑰图\\文字\n"); //fprintf(fw, "Layer M 玫瑰图\\文字\n", m_strLayerText); fprintf(fw, "Layer HowToViewPoint\n"); fprintf(fw, "HowToViewCurve\n"); fprintf(fw,"Property 0 %ld 65568 0 0 20000.000000 30000.000000 10\n",m_barColor); fprintf(fw,"Solid\n"); fprintf(fw, "Property 0 %ld 65536 0 0 20000.000000 30000.000000 10\n", m_barColor); fprintf(fw, "Solid\n"); fprintf(fw,"NoDraw\n"); fprintf(fw, "\n"); fprintf(fw, "Layer M %s\n", m_strLayerBars); fprintf(fw, "Layer HowToViewCurve\n"); fprintf(fw, "HowToViewCurve\n"); fprintf(fw, "\n\n"); fprintf(fw, "HowToViewPoint\n"); fprintf(fw, "\n"); fprintf(fw, "State 10\n"); } void CFaultRosesCreator::WriteBorder(FILE* fw) //输出圆框 { WriteColor(fw,0); fprintf(fw,"Layer M %s\n",m_strLayerCircle); //fprintf(fw,"_Circle\n"); //fprintf(fw,"%.12g,%.12g\n",m_dCX,m_dCY); //fprintf(fw,"%.12g,%.12g\n",m_dCX+m_dR,m_dCY+m_dR); //fprintf(fw,"0 4 16777215\n"); fprintf(fw, "_Ellipse\n"); fprintf(fw, "%.12g,%.12g\n", m_dCX, m_dCY); fprintf(fw, "%.12g,%.12g\n", m_dCX + m_dR, m_dCY + m_dR); fprintf(fw, "0 1\n"); } //由角度和起止比例获取线段 bool CFaultRosesCreator::GetSegment(double angle, double fstart, double fend, double*x, double* y) { GetCoordiante(angle,fstart, x[0], y[0]); GetCoordiante(angle, fend, x[1], y[1]); return true; } void CFaultRosesCreator::WriteOneTick(FILE* fw, double angle, double fs,double fe) { double x[2], y[2]; GetSegment(angle, fs,fe, x, y); fprintf(fw, "Pline\n"); fprintf(fw, "%.12g,%.12g\n", x[0], y[0]); fprintf(fw, "%.12g,%.12g\n", x[1], y[1]); fprintf(fw, "\n"); } void CFaultRosesCreator::WriteTicks(FILE* fw)//输出刻线 { WriteColor(fw,RGB(0,0,0)); fprintf(fw,"Layer M %s\n",m_strLayerTicks); for (int i = 0; i < 360; i+=m_nCircleTickInterval) if(i != 90) WriteOneTick(fw, i, 0.95,1.0); WriteOneTick(fw, 90, 0, 1); //中间刻标 double x, y; GetCoordiante(90, 0.5, x, y); fprintf(fw, "Pline\n"); fprintf(fw, "%.12g,%.12g\n", x,y); fprintf(fw, "%.12g,%.12g\n", x,y-m_dR/20.0); fprintf(fw, "\n"); } void CFaultRosesCreator::WriteText(FILE* fw) //输出文字 { WriteColor(fw,RGB(0,0,0)); fprintf(fw,"Layer M %s\n",m_strLayerText); double height = m_dR / 10.0; double width = 4 * height / 10.0; double x0, y0;//文字左上角坐标 CString strText; CString strD = "°"; //输出角度文字 for (int i = 0; i < 360; i += m_nCircleTickInterval) { GetCoordiante(i, 1.01, x0, y0); strText.Format("%d", i); strText += strD; switch (i) { case 0: x0 -= width / 2.0; y0 += height/1.2; break; case 180: x0 -= width *1.5; break; case 90: case 45: x0 += width / 4; y0 += height / 2.0; break; case 225: x0 -= width*4; break; case 270: x0 -= width*4.2; y0 += height / 2.0; break; case 315: x0 -= width*4; y0 += height/1.8; break; default: if(i > 0 && i < 45) { y0 += height /1.2; } else if (i > 45 && i < 90) { y0 += height / 2.0; x0 += width / 4.0; } else if (i > 90 && i < 180) { x0 -= width / 2.0; } else if (i > 180 && i < 270) { x0 -= width * 4; } else if (i > 270 && i < 315) { x0 -= width * 4.5; y0 += height / 2.0; } else if (i > 315 && i < 360) { x0 -= width * 4; y0 += height / 1.5; } break; } WriteOneText(fw, strText, x0, y0, width, height); } //输出个数文字 //中间刻标 GetCoordiante(90, 0.5, x0, y0); y0 -= m_dR / 20.0; strText.Format("%g", m_nBarMaxNumber / 2.0); x0 -= width*strText.GetLength() / 2.0; WriteOneText(fw, strText, x0, y0, width, height); //最大个数刻标 x0 = m_dCX + m_dR - width/2.0; strText.Format("%d", m_nBarMaxNumber ); int len = strText.GetLength(); x0 -= width*len; WriteOneText(fw, strText, x0, y0, width, height); } void CFaultRosesCreator::WriteOneText(FILE* fw, CString str, double x0, double y0, double width, double height) { fprintf(fw, "3dPoint %.12g,%.12g,0 0 %s\n", x0, y0, str); //fprintf(fw, "FONT %.12g, %.12g, 0.00000000 100 0.00000000\n", // x0,y0); //fprintf(fw, "{\n"); //fprintf(fw, "%s\n", str); //fprintf(fw, "}\n"); //fprintf(fw, "%.12g %.12g 0.000000 0 400 0 0 0 1 0 16 0 0 Times New Roman\n", // width, height); } void CFaultRosesCreator::WriteBars(FILE* fw) //输出花瓣 { COLORREF clr = m_barColor; WriteColor(fw,clr); fprintf(fw,"Layer M %s\n",m_strLayerBars); for(int i = 0; i < m_rosebars.size(); i ++ ) WriteOneBar(fw,m_rosebars[i],clr); } void CFaultRosesCreator::WriteOneBar(FILE* fw,RoseBar rb, COLORREF clr) { double x[4], y[4]; double factor = float(rb.count)/m_nBarMaxNumber; if(factor>1) factor = 1; x[0] = m_dCX;y[0] = m_dCY; x[3] = m_dCX;y[3] = m_dCY; GetCoordiante(rb.agl[0],factor,x[1],y[1]); GetCoordiante(rb.agl[1],factor,x[2],y[2]); fprintf(fw,"Pline.%d\n",rb.count); for(int i = 0; i <4; i ++ ) { fprintf(fw,"%.12g,%.12g\n",x[i],y[i]); } fprintf(fw,"\n"); } double CFaultRosesCreator::GetRealAngle(double degree) { double angle = 360-degree; angle += 90; return angle; } bool CFaultRosesCreator::GetCoordiante(double degree, double factor, double& x, double& y) { double angle = GetRealAngle(degree); double radian = PI* angle/180.0; x = m_dCX + m_dR*cos(radian)*factor; y = m_dCY + m_dR*sin(radian)*factor; return true; } void CFaultRosesCreator::WriteColor(FILE* fw,COLORREF clr) { fprintf(fw,"Color %ld\n",clr); } RoseBar::RoseBar(void) { agl[0] = agl[1] = 0; count = 0; }