Files
geomative/GeomativeStudio/cpp/Views/AppDataCEIpCurveGraphView.cpp
T
coco df489d5640 a
2026-07-03 16:05:30 +08:00

521 lines
14 KiB
C++

// AppDataCEIpCurveGraphView.cpp : implementation file
//
#include "stdafx.h"
#include "geomative.h"
#include "AppDataCEIpCurveGraphView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAppDataCEIpCurveGraphView
extern void get_fit_equation(double x[],double y[],int n,double a[],int m,double dt[]);
extern double get_fit_equation_value(double x, double a[], int m);
IMPLEMENT_DYNCREATE(CAppDataCEIpCurveGraphView, CView)
CAppDataCEIpCurveGraphView::CAppDataCEIpCurveGraphView()
{
m_fMaxAbsV = 0.0;
m_iCXOffset = 55;
m_iCYOffset = 35;
m_pPoint = NULL;
m_pPointTwo = NULL;
m_pFillTWPt1 = NULL;
m_pFillTWPt2 = NULL;
m_iPtNum = 0;
m_dX1Average = 0;
m_dX2Average = 0;
m_dPeriodInfo = 0;
m_dChrVoltage1 = 0;
m_dChrVoltage2 = 0;
memset(m_dCoffient1, 0, sizeof(m_dCoffient1));
memset(m_dCoffient2, 0, sizeof(m_dCoffient2));
m_vtTimeWin.clear();
}
CAppDataCEIpCurveGraphView::~CAppDataCEIpCurveGraphView()
{
ClearPoint();
}
BEGIN_MESSAGE_MAP(CAppDataCEIpCurveGraphView, CView)
//{{AFX_MSG_MAP(CAppDataCEIpCurveGraphView)
// NOTE - the ClassWizard will add and remove mapping macros here.
ON_WM_MOUSEACTIVATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAppDataCEIpCurveGraphView drawing
void CAppDataCEIpCurveGraphView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
if (m_dPeriodInfo < 1)
{
return;
}
if (0 != m_iPtNum)
{
DrawEX(pDC);
DrawLY(pDC);
DrawLine(pDC);
}
}
/////////////////////////////////////////////////////////////////////////////
// CAppDataCEIpCurveGraphView diagnostics
#ifdef _DEBUG
void CAppDataCEIpCurveGraphView::AssertValid() const
{
CView::AssertValid();
}
void CAppDataCEIpCurveGraphView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CAppDataCEIpCurveGraphView message handlers
int CAppDataCEIpCurveGraphView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT msg)
{
return APP_SUCCESS;
}
void CAppDataCEIpCurveGraphView::DrawLine(CDC* const pDC)
{
CPen lPen(PS_SOLID, 1, RGB(30, 200, 30));
CPen* pOldLPen = NULL;
pOldLPen = pDC->SelectObject(&lPen);
int iIndex = (int)VAL_ZERO;
// iIndex = (int)VAL_ZERO;
int nPtNumber = 4 * m_iPtNum;
pDC->MoveTo(*(m_pPoint + iIndex));
while (iIndex < nPtNumber)
{
pDC->LineTo(*(m_pPoint + iIndex));
pDC->SetPixel(*(m_pPoint+iIndex), RGB(0xFF, 0x00, 0x00));
iIndex++;
}
iIndex = 0;
pDC->MoveTo(*(m_pPointTwo + iIndex));
while (iIndex < nPtNumber)
{
pDC->LineTo(*(m_pPointTwo + iIndex));
pDC->SetPixel(*(m_pPointTwo+iIndex), RGB(0xFF, 0x00, 0x00));
iIndex++;
}
//开始填充窗口的部分
CPen lFillTWPen(PS_SOLID, 1, RGB(192,192,192));
pDC->SelectObject(&lFillTWPen);
CString strMInfo;
int nMIndex = 0;
for (int i = 0; i < m_vtTimeWin.size()*(FILL_TIMEWIN_NUM+1); i++)
{
pDC->MoveTo(m_pFillTWPt1[i]);
pDC->LineTo(m_pFillTWPt2[i]);
//填充序号标识符
if (0 == i%(FILL_TIMEWIN_NUM+1))
{
strMInfo.Empty();
strMInfo.Format(_T("M%d"),nMIndex);
pDC->DrawText(strMInfo, CRect(m_pFillTWPt1[i].x, m_pFillTWPt1[i].y - 14, m_pFillTWPt1[i].x+20, m_pFillTWPt1[i].y-2), DT_SINGLELINE | DT_VCENTER | DT_LEFT);
nMIndex++;
}
}
pDC->SelectObject(pOldLPen);
}
void CAppDataCEIpCurveGraphView::DrawEX(CDC* const pDC)
{
CString szLabel = _T("");
pDC->MoveTo(m_iCXOffset - 1, m_iCYOffset + 150);
pDC->LineTo(m_iCXOffset + 410, m_iCYOffset + 150);
pDC->MoveTo(m_iCXOffset + 408, m_iCYOffset + 150);
pDC->LineTo(m_iCXOffset + 403, m_iCYOffset + 147);
pDC->MoveTo(m_iCXOffset + 408, m_iCYOffset + 150);
pDC->LineTo(m_iCXOffset + 403, m_iCYOffset + 153);
szLabel.Empty();
szLabel = _T("T");
pDC->DrawText(szLabel, CRect(m_iCXOffset + 415, m_iCYOffset + 143, m_iCXOffset + 445, m_iCYOffset + 157), DT_SINGLELINE | DT_VCENTER | DT_LEFT);
// pDC->LineTo(m_iCXOffset + 400 + 10, m_iCYOffset + 300 / 2 - 5);
}
void CAppDataCEIpCurveGraphView::DrawLY(CDC* const pDC)
{
CPen penDot(PS_DOT, 1, RGB(180, 180, 180));
CPen* pPenOld = NULL;
CFont fontEX;
CFont* pFontOldEX = NULL;
CString szLabel = _T("");
int iIndex = (int)VAL_ZERO;
szLabel.Empty();
szLabel = _T("V(mV)");
pDC->DrawText(szLabel, CRect(m_iCXOffset - 20, m_iCYOffset - 28, m_iCXOffset + 20, m_iCYOffset - 8), DT_SINGLELINE | DT_VCENTER | DT_CENTER);
pDC->MoveTo(m_iCXOffset - 1, m_iCYOffset);
pDC->LineTo(m_iCXOffset - 1, m_iCYOffset + 300);
fontEX.CreatePointFont(80, _T("Tahoma"));
pFontOldEX = pDC->SelectObject(&fontEX);
iIndex = (int)VAL_ZERO;
while (iIndex < 11)
{
//纵轴上的小短线
pDC->MoveTo(m_iCXOffset - 1, m_iCYOffset + 30 * iIndex);
pDC->LineTo(m_iCXOffset - 6, m_iCYOffset + 30 * iIndex);
if (5 != iIndex)
{
//图像后面的虚线
pPenOld = pDC->SelectObject(&penDot);
pDC->MoveTo(m_iCXOffset - 1, m_iCYOffset + 30 * iIndex);
pDC->LineTo(m_iCXOffset + 400, m_iCYOffset + 30 * iIndex);
pDC->SelectObject(pPenOld);
}
//纵轴小短线旁边的坐标数字
szLabel.Empty();
szLabel.Format(_T("%d"), m_iMaxYScale - (m_iMaxYScale / 5) * iIndex);
pDC->DrawText(szLabel, CRect(m_iCXOffset - 35, m_iCYOffset + iIndex * 30 - 5, m_iCXOffset - 5, m_iCYOffset + iIndex * 30 + 5), DT_SINGLELINE | DT_VCENTER | DT_RIGHT);
iIndex++;
}
fontEX.DeleteObject();
pDC->SelectObject(pFontOldEX);
}
int CAppDataCEIpCurveGraphView::CoordinateMapping(float fValue, float fMappingRange, int MappingFactor)
{
float fUnit = 0.0;
float fMValue = 0.0;
fUnit = (float)(fMappingRange / MappingFactor);
fMValue = fValue / fUnit;
return (int)ceilf(fMValue);
}
void CAppDataCEIpCurveGraphView::CalculatePointCoo()
{
CPoint* pPoint = NULL;
float fXValue = 0.0;
float fYValue = 0.0;
CString szValue = _T("");
int iIndex = (int)VAL_ZERO;
CalculateMaxScale();
ClearPoint();
float fXUnit = 1.0*400/m_iMaxXScale;
float fYUnit = 1.0*150/m_iMaxYScale;
int nPtNumber = 0;
//读m_saOrgDataOne中的数据并绘图
if (m_iPtNum > 0)
{
//计算第一次放电过程的数据
nPtNumber = 4 * m_iPtNum; //将所需要画的点设置为原来的4倍
double dSplit = m_dPeriodInfo/(4*nPtNumber-1);
m_pPoint = new POINT[nPtNumber];
iIndex = (int)0;
while (iIndex < nPtNumber)
{
szValue.Empty();
fXValue = dSplit * iIndex;
(m_pPoint+iIndex)->x = m_iCXOffset + (int)ceilf(fXValue * fXUnit);
//进行转换的目的是因为m_iCYOffset是Y轴的最高点,而视图的基准点在左上角
fYValue = (float)this->m_iMaxYScale - get_fit_equation_value(fXValue - m_dX1Average, m_dCoffient1, m_iPtNum - 1);
(m_pPoint+iIndex)->y = m_iCYOffset + (int)ceilf(fYValue * fYUnit);
iIndex++;
}
//计算第二次放电过程的数据
nPtNumber = 4 * m_iPtNum; //将所需要画的点设置为原来的4倍
m_pPointTwo = new POINT[nPtNumber];
iIndex = (int)0;
while (iIndex < nPtNumber)
{
fXValue = iIndex * dSplit;
(m_pPointTwo+iIndex)->x = m_iCXOffset + (int)ceilf(fXValue * fXUnit);
fYValue = fabs(get_fit_equation_value(fXValue - m_dX2Average, m_dCoffient2, m_iPtNum - 1));
(m_pPointTwo+iIndex)->y = m_iCYOffset + 150 + (int)ceilf(fYValue * fYUnit);
iIndex++;
}
}
//将划分为8等分进行阴影线的划
int nFillSegNum = FILL_TIMEWIN_NUM;
int nSigFillPtNum = nFillSegNum+1;//点数比段数多1
m_pFillTWPt1 = new POINT[m_vtTimeWin.size() * nSigFillPtNum];
m_pFillTWPt2 = new POINT[m_vtTimeWin.size() * nSigFillPtNum];
memset(m_pFillTWPt1, 0, sizeof(POINT)*m_vtTimeWin.size() * nSigFillPtNum);
memset(m_pFillTWPt2, 0, sizeof(POINT)*m_vtTimeWin.size() * nSigFillPtNum);
for (int i =0; i < m_vtTimeWin.size(); i++)
{
float fSigSplit = (float)m_vtTimeWin[i].nTWWidth/nFillSegNum;
//计算第一次放电过程的X和Y值
int j = 0;
for (j = 0; j < nSigFillPtNum; j++)
{
if (nFillSegNum == j)//这样做是为了防止除8,又乘8之后,不一定精确的等于原来的值得问题
fXValue = m_vtTimeWin[i].nTWStartPos + m_vtTimeWin[i].nTWWidth;
else
fXValue = m_vtTimeWin[i].nTWStartPos + j*fSigSplit;
m_pFillTWPt1[i*nSigFillPtNum+j].x = m_iCXOffset + (int)ceilf(fXValue * fXUnit);
fYValue = (float)this->m_iMaxYScale - get_fit_equation_value(fXValue - m_dX1Average, m_dCoffient1, m_iPtNum - 1);
m_pFillTWPt1[i*nSigFillPtNum+j].y = m_iCYOffset + (int)ceilf(fYValue * fYUnit);
}
//计算第二次放电过程的Y值
for (j = 0; j < nSigFillPtNum; j++)
{
if (nFillSegNum == j)//这样做是为了防止除8,又乘8之后,不一定精确的等于原来的值得问题
fXValue = m_vtTimeWin[i].nTWStartPos + m_vtTimeWin[i].nTWWidth;
else
fXValue = m_vtTimeWin[i].nTWStartPos + j*fSigSplit;
m_pFillTWPt2[i*nSigFillPtNum+j].x = m_iCXOffset + (int)ceilf(fXValue * fXUnit);
fYValue = fabs(get_fit_equation_value(fXValue - m_dX2Average, m_dCoffient2, m_iPtNum - 1));
m_pFillTWPt2[i*nSigFillPtNum+j].y = m_iCYOffset + 150 + (int)ceilf(fYValue * fYUnit);
}
}
// //读m_saOrgDataTwo中的数据并绘图
// if (m_saOrgDataTwo.GetSize() > /*4*/0)
// {
// // m_iPtNumTwo = this->m_saOrgDataTwo.GetSize()/* - 4*/;
// nPtNumber = 4 * m_iPtNum; //将所需要画的点设置为原来的4倍
// m_pPointTwo = new POINT[m_iPtNumTwo];
// iIndex = (int)0;
// while (iIndex < m_iPtNumTwo)
// {
// szValue.Empty();
// szValue = this->m_saOrgDataTwo.GetAt(iIndex /*+ 4*/);
//
// fXValue = (float)iIndex;
// (m_pPointTwo+iIndex)->x = m_iCXOffset + this->CoordinateMapping(fXValue, (float)this->m_iMaxXScale, 400);
//
// fYValue = (float)this->m_iMaxYScale - (float)atof(szValue);
// (m_pPointTwo+iIndex)->y = m_iCYOffset + this->CoordinateMapping(fYValue, (float)2 * m_iMaxYScale, 300);
//
// iIndex++;
// }
// }
}
void CAppDataCEIpCurveGraphView::CalculateMaxScale()
{
m_iMaxXScale = 1.1 * m_dPeriodInfo / 4; //将X轴的最大范围设置为周期的1.15倍
double dTmp = (fabs(m_dChrVoltage1) > fabs(m_dChrVoltage2)) ? fabs(m_dChrVoltage1) : fabs(m_dChrVoltage2);
m_iMaxYScale = dTmp * 1.1;
// int iFill = (int)VAL_ZERO;
// m_iMaxYScale = (int)ceil(this->m_fMaxAbsV);
//
// iFill = (int)VAL_ZERO;
// while (TRUE)
// {
// if (0.0 == ((m_iMaxYScale + iFill) * 2) % 10)
// {
// m_iMaxYScale = m_iMaxYScale + iFill;
// break;
// }
// iFill++;
// }
//
// if (this->m_saOrgDataOne.GetSize() > /*4*/0)
// {
// m_iMaxXScale = this->m_saOrgDataOne.GetSize()/* - 4*/;
// }
}
void CAppDataCEIpCurveGraphView::ClearPoint()
{
int iIndex = (int)VAL_ZERO;
if (m_pPoint)
{
delete[] m_pPoint;
m_pPoint = NULL;
}
if (m_pPointTwo)
{
delete[] m_pPointTwo;
m_pPointTwo = NULL;
}
if (m_pFillTWPt1)
{
delete[] m_pFillTWPt1;
m_pFillTWPt1 = NULL;
}
if (m_pFillTWPt2)
{
delete[] m_pFillTWPt2;
m_pFillTWPt2 = NULL;
}
}
void CAppDataCEIpCurveGraphView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
CalculateIpCurve();
CalculatePointCoo();
}
void CAppDataCEIpCurveGraphView::CalculateIpCurve()
{
int nSize = m_saOrgDataOne.GetSize();
m_iPtNum = atoi(m_saOrgDataOne.GetAt(3));
double dSplit = m_dPeriodInfo/(m_iPtNum-1);
m_iPtNum = m_iPtNum/4;
CString szTmp = _T("");
//取出原始数据第二第四段
double dXData[MAX_DISCHARGE_PT], dYData[MAX_DISCHARGE_PT], dtInfo[MAX_DISCHARGE_PT];
memset(dXData, 0, sizeof(dXData));
memset(dYData, 0, sizeof(dYData));
memset(m_dCoffient1, 0, sizeof(m_dCoffient1));
memset(dtInfo, 0, sizeof(dtInfo));
m_dX1Average = 0;
int nIndex;
for (nIndex= 0; nIndex < m_iPtNum; nIndex++)
{
dXData[nIndex] = nIndex * dSplit; //以放电的第一个点的位置为基准进行多项式的计算
m_dX1Average += dXData[nIndex];
dYData[nIndex] = atof(m_saOrgDataOne.GetAt(4 + m_iPtNum + nIndex));
}
m_dX1Average = m_dX1Average / m_iPtNum;
m_dChrVoltage1 = 0;
for (nIndex = 0; nIndex < 3; nIndex++)
{
m_dChrVoltage1 += atof(m_saOrgDataOne.GetAt(3+m_iPtNum-nIndex));
}
m_dChrVoltage1 = m_dChrVoltage1/3;
//获取第一段放电的多项式
get_fit_equation(dXData, dYData, m_iPtNum, m_dCoffient1, m_iPtNum-1, dtInfo);
//得到第二次放电的的多项式
memset(dXData, 0, sizeof(dXData));
memset(dYData, 0, sizeof(dYData));
memset(m_dCoffient2, 0, sizeof(m_dCoffient2));
memset(dtInfo, 0, sizeof(dtInfo));
//获取采样时窗
for (nIndex= 0; nIndex < m_iPtNum; nIndex++)
{
dXData[nIndex] = nIndex * dSplit; //以放电的第一个点的位置为基准进行多项式的计算
m_dX2Average += dXData[nIndex];
dYData[nIndex] = atof(m_saOrgDataOne.GetAt(4 + m_iPtNum*3 + nIndex));
}
m_dX2Average = m_dX2Average/m_iPtNum;
m_dChrVoltage2 = 0;
for (nIndex = 0; nIndex < 3; nIndex++)
{
m_dChrVoltage2 += atof(m_saOrgDataOne.GetAt(3+m_iPtNum-nIndex));
}
m_dChrVoltage2 = m_dChrVoltage2/3;
//计算第二段的多项式
get_fit_equation(dXData, dYData, m_iPtNum, m_dCoffient2, m_iPtNum-1, dtInfo);
// szTmp = m_saOrgDataOne.GetAt((nCount * 3) + 200);
// szArrayTwo.Add(szTmp);
// //判断X轴上方的线条的那段区间
// int nDis = -1; //区间0代表第一段 1代表第二段 2代表第三段 3代表第四段
// float nResult = 0;
// float fNumOne = 0, fNumTwo = 0;
// CString szTmp;
//
// for (int n = 0; n < 4; n++)
// {
// szTmp = m_saOrgData.GetAt((nCount * n) + (nCount / 3));
// fNumOne = atof(szTmp.GetBuffer(0));
//
// szTmp = m_saOrgData.GetAt((nCount * n) + (nCount / 3 * 2));
// fNumTwo = atof(szTmp.GetBuffer(0));
//
// if (fNumTwo < 0 || fNumOne < 0)
// {
// continue;
// }
//
// nResult = fNumOne - fNumTwo;
//
// if (nResult > 0)
// {
// nDis = n;
// break;
// }
// }
//
// if (nDis == -1)
// {
// nDis = 1;
// }
//
// CStringArray szArray;
//
// //取出那一段的值
// for(n = 0; n < nCount; n++)
// {
// if (nCount * nDis + n >= m_saOrgData.GetSize())
// {
// break;
// }
// szTmp = m_saOrgData.GetAt(nCount * nDis + n);
// szArray.Add(szTmp);
// }
// m_saOrgData.RemoveAll();
// m_saOrgData.Copy(szArray);
}