⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 curvectrl.cpp

📁 功能非常强大的数据采集系统
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// 功能:connect neighbor points by drawing lines(画所有曲线)
// 参数:无
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::DrawCurve(CDC *pdc)
{
	CPen		Pen;
	CBrush		brush;
	CPen*		pOldPen;
	CBrush*		pOldBrush;
	CCurve*		pCurve;

	int		iPoint;
	CRect	rect;
	int		nRadius;
	for (int iCurve = 0; iCurve < m_ArrCurve.GetSize(); iCurve++)
	{		
		pCurve = m_ArrCurve[iCurve];
		if ((!pCurve->IsVisible()) || (pCurve->m_ArrPoint.GetSize() < 1))
			continue;

		// create pen using CCurve's member variables
		Pen.CreatePen(pCurve->m_iStyle, pCurve->m_nWidth, pCurve->m_crColor);
		pOldPen = pdc->SelectObject(&Pen);		
		brush.CreateSolidBrush(pCurve->m_crColor);
		pOldBrush = pdc->SelectObject(&brush);	
		nRadius = pCurve->m_nWidth + 1;

		if ((1 == pCurve->m_ArrPoint.GetSize()) && (pCurve->m_ArrPoint[0] != INVALID_POINT))
		{
			// if there is only one point in m_ArrPoint, draw it 
			rect.top	= pCurve->m_ArrPoint[0].y - nRadius / 2;
			rect.bottom = pCurve->m_ArrPoint[0].y + nRadius / 2;
			rect.left	= pCurve->m_ArrPoint[0].x - nRadius / 2;
			rect.right	= pCurve->m_ArrPoint[0].x + nRadius / 2;

			pdc->Rectangle(rect);			
		}
		else   // draw connected line between neighbor key points in m_ArrPoint
		{
			// flag for whether already begin draw line
			BOOL	bStart = FALSE;		

			// make sure that line get to margin line if there are points outside drawing area 
			for (iPoint = 0; iPoint < pCurve->m_ArrPoint.GetSize(); iPoint++)
			{
					// if point in drawing area(INVALID_POINT)
					if (pCurve->m_ArrPoint[iPoint] == INVALID_POINT)
					{
							if (!bStart)  // if not begin drawing,then INVALID_PINT is foregoing points, don't draw it
							{
								continue;
							}
							else if (iPoint != pCurve->m_ArrPoint.GetUpperBound())  // if already beginning, then INVALID_PINT isback points
							{
								CPoint ptside;

								// using line equation to calculate value , and then point in pixel
								// k = (y2 - y1) / (x2 - x1)
								float k = float(pCurve->m_fArrVertValue[iPoint] - pCurve->m_fArrVertValue[iPoint + 1]) 
										  / float(pCurve->m_fArrHoriValue[iPoint] - pCurve->m_fArrHoriValue[iPoint + 1]);
								//b = (x2 * y1 - x1 * y2) / (x2 - x1)
								float b = float(pCurve->m_fArrHoriValue[iPoint] * pCurve->m_fArrVertValue[iPoint + 1]
												 - pCurve->m_fArrHoriValue[iPoint + 1] * pCurve->m_fArrVertValue[iPoint]) 
										 / float(pCurve->m_fArrHoriValue[iPoint] - pCurve->m_fArrHoriValue[iPoint + 1]);
								float fVside = k * m_fHoriEnd + b;
								
								CalculatePoint(m_fHoriEnd, fVside, ptside);
//								pdc->LineTo(ptside);
							}

							break;   // return if connect to margin line
					}// end INVALID_POINT 

					if (!bStart) // begin drawing after first validate point
					{
						bStart = TRUE;

						// if the first validate point is out of drawing area, draw line to margin line
						if (iPoint > 0)
						{
							CPoint   ptside;
							if (fabs(pCurve->m_fArrHoriValue[iPoint] - pCurve->m_fArrHoriValue[iPoint - 1]) > CURVE_EPSILON)
							{
								// k = (y2 - y1) / (x2 - x1)
								float k = float(pCurve->m_fArrVertValue[iPoint] - pCurve->m_fArrVertValue[iPoint - 1]) 
										  / float(pCurve->m_fArrHoriValue[iPoint] - pCurve->m_fArrHoriValue[iPoint - 1]);
								//b = (x2 * y1 - x1 * y2) / (x2 - x1)
								float b = float(pCurve->m_fArrHoriValue[iPoint] * pCurve->m_fArrVertValue[iPoint - 1]
												 - pCurve->m_fArrHoriValue[iPoint - 1] * pCurve->m_fArrVertValue[iPoint]) 
										 / float(pCurve->m_fArrHoriValue[iPoint] - pCurve->m_fArrHoriValue[iPoint - 1]);
								float fVside = k * m_fHoriBegin + b;

								CalculatePoint(m_fHoriBegin, fVside, ptside);
							}
							else
							{
								ptside = CPoint(m_RectCoord.left, pCurve->m_ArrPoint[iPoint-1].y);
							}
							pdc->MoveTo(ptside);
						}
						else
							pdc->MoveTo(pCurve->m_ArrPoint[iPoint]);
					} // end first validate point
				
					// connect line between neighbor points
					pdc->LineTo(pCurve->m_ArrPoint[iPoint]);
					if (pCurve->m_bSelected)
					{
						rect.top	= pCurve->m_ArrPoint[iPoint].y - nRadius;
						rect.bottom = pCurve->m_ArrPoint[iPoint].y + nRadius;
						rect.left	= pCurve->m_ArrPoint[iPoint].x - nRadius;
						rect.right	= pCurve->m_ArrPoint[iPoint].x + nRadius;
						pdc->Ellipse(rect);
					}
			} //end for pCurve->m_ArrPoint 
		}
		pdc->SelectObject(pOldBrush);
		pdc->SelectObject(pOldPen);
		brush.DeleteObject();
		Pen.DeleteObject();	
	} // end for m_ArrCurve 
}

//-------------------------------------------------------------------------------------------------
// 功能:add a curve
// 参数:strName -- curve name, must not empty
//       color   -- curve line color
//       iStyle  -- curve line style
//       nWidth  -- curve line width
// 返回:index of the added curve in CCurveCtrl
//-------------------------------------------------------------------------------------------------
int	CCurveCtrl::AddCurve(const CString& strName, COLORREF color, int iStyle, int nWidth)
{
	if (strName.IsEmpty())
		return -1;
	for (int iCurve = 0; iCurve < m_ArrCurve.GetSize(); iCurve++)
	{
		if (strName == m_ArrCurve[iCurve]->m_strName)
			return -1;
	}

	CCurve*	pCurve = new CCurve;
	pCurve->m_strName = strName;
	pCurve->m_crColor = color;
	pCurve->m_iStyle = iStyle;
	pCurve->m_nWidth = nWidth;

	// restore zoom
	m_iZoom = 0;
	
	return m_ArrCurve.Add(pCurve);
}

//-------------------------------------------------------------------------------------------------
// 功能:add data to an exist curve
// 参数:strName    -- curve name
//       fHoriValue -- horizontal value
//       fVertValue -- vertical value
// 返回:TRUE: data added to curve; FALSE: curve is empty or there are no curve named as strName
//-------------------------------------------------------------------------------------------------
BOOL CCurveCtrl::AddData(const CString& strName, float fHoriValue, float fVertValue)
{
	if (strName.IsEmpty()) 
		return FALSE;

	CCurve*		pCurve = NULL;
	for (int iCurve = 0; iCurve < m_ArrCurve.GetSize(); iCurve++)
	{
		if (strName == m_ArrCurve[iCurve]->m_strName)
		{
			pCurve = m_ArrCurve[iCurve];
			break;
		}
	}

	// following AddData(...) will check whether pCurve is NULL
	return AddData(pCurve, fHoriValue, fVertValue);
}

// description  : add data to an exist curve
// in parameter : pCurve     -- curve pointer in this CCurveCtrl
//                fHoriValue -- horizontal value
//                fVertValue -- vertical value
// return value : TRUE: data added to curve; FALSE: pointer of curve invalidate
BOOL CCurveCtrl::AddData(CCurve* pCurve, float fHori, float fVert)
{
	if (!pCurve)
		return FALSE;

	// ad data to array, inserted position decided by horizontal value
	ASSERT(pCurve->m_fArrHoriValue.GetSize() == pCurve->m_fArrVertValue.GetSize());
	InsertDataToCurve(pCurve, fHori, fVert);

	// save max and min values in horizontal
//	m_fHoriMax = max(m_fHoriMax, fHori);
//	m_fHoriMin = min(m_fHoriMin, fHori);

	CalculateVertRange(fVert, TRUE);
	CalculateVertRange(fVert, FALSE);
//	m_fHoriBegin = m_fHoriMin;
//	m_fHoriEnd   = m_fHoriMax;

	return TRUE;	
}

// decription  : insert data to data array which already sorted by horizontal value
// in parameter: pCurve -- Curve object pointer
//               fHori  -- horizontal value 
//               fVert  -- vertical value
//               point  -- corresponding point in pixel
// return value: index of the added data in data array
int CCurveCtrl::InsertDataToCurve(CCurve* pCurve, float fHori, float fVert, CPoint point)
{
	if (!pCurve)
		return -1;
	ASSERT(pCurve->m_fArrHoriValue.GetSize() == pCurve->m_fArrVertValue.GetSize());
	ASSERT(pCurve->m_fArrHoriValue.GetSize() == pCurve->m_ArrPoint.GetSize());
	
	for (int iIndex = pCurve->m_fArrHoriValue.GetUpperBound(); iIndex >= 0; iIndex--)
	{
		if (pCurve->m_fArrHoriValue[iIndex] < fHori)
		{
			break;
		}		
	}

	if (iIndex == pCurve->m_fArrHoriValue.GetUpperBound())
	{
		pCurve->m_ArrPoint.Add(point);
		pCurve->m_fArrHoriValue.Add(fHori);
		pCurve->m_fArrVertValue.Add(fVert);
	}
	else
	{
		pCurve->m_ArrPoint.InsertAt(iIndex + 1, point);
		pCurve->m_fArrHoriValue.InsertAt(iIndex + 1, fHori);
		pCurve->m_fArrVertValue.InsertAt(iIndex + 1, fVert);
	}
		
	return iIndex + 1;
}

// decription  : add one curve and copy it's data to data array
// in parameter: strName -- curve name
//               ArrHori -- data array of horizontal value
//               ArrVert -- data array of vertical value
// return value: TRUE if success
BOOL CCurveCtrl::AddCurveData(const CString& strName, const CArray< float, float >& ArrHori, const CArray< float, float >& ArrVert)
{
	int iCurve = AddCurve(strName);
	if (iCurve < 0 || (ArrHori.GetSize() != ArrVert.GetSize()))
		return FALSE;		

	// copy data
	m_ArrCurve[iCurve]->m_fArrHoriValue.Copy(ArrHori);
	m_ArrCurve[iCurve]->m_fArrVertValue.Copy(ArrVert);
	// make sure point array has the same size as the data arrays
	m_ArrCurve[iCurve]->m_ArrPoint.SetSize(ArrHori.GetSize()); 

	// remember the max and min value
	int iIndex;
	for (iIndex = 0; iIndex < ArrHori.GetSize(); iIndex++)
	{
		m_fHoriMax = max(m_fHoriMax, ArrHori[iIndex]);
		m_fHoriMin = min(m_fHoriMin, ArrHori[iIndex]);
	}

	// to adjust max and min value in vertical for mouse editing
	float fVMax = -FLT_MAX / 2;
	float fVMin = FLT_MAX / 2;
	for (iIndex = 0; iIndex < ArrVert.GetSize(); iIndex++)
	{
		fVMax = max(fVMax, ArrVert[iIndex]);
		fVMin = min(fVMin, ArrVert[iIndex]);		
	}
		
	SortCurveData(m_ArrCurve[iCurve]);

	CalculateVertRange(fVMax, TRUE);
	CalculateVertRange(fVMin, FALSE);

	m_fHoriBegin = m_fHoriMin;
	m_fHoriEnd   = m_fHoriMax;
	
	return TRUE;
}

// decription  : sort data to make sure all arrays order by horizontal value
void CCurveCtrl::SortCurveData(CCurve* pCurve)
{
	int nCount = pCurve->m_fArrHoriValue.GetSize();
	
	ASSERT(nCount == pCurve->m_fArrVertValue.GetSize());
	ASSERT(nCount == pCurve->m_ArrPoint.GetSize());

	int		iPos;
	float	fTemp;
	CPoint	PtTemp;
	for (int iPre = 0; iPre < nCount - 1; iPre++)
	{
		iPos = iPre;
		for (int iAft = iPre + 1; iAft < nCount; iAft++)
		{
			if (pCurve->m_fArrHoriValue[iPre] > pCurve->m_fArrHoriValue[iAft])
			{
				iPos = iAft;				
			}
		}

		// exchange
		if (iPos != iPre)
		{
			// horizontal value
			fTemp = pCurve->m_fArrHoriValue[iPre];
			pCurve->m_fArrHoriValue[iPre] = pCurve->m_fArrHoriValue[iPos];
			pCurve->m_fArrHoriValue[iPos] = fTemp;

			// vertical value
			fTemp = pCurve->m_fArrVertValue[iPre];
			pCurve->m_fArrVertValue[iPre] = pCurve->m_fArrVertValue[iPos];
			pCurve->m_fArrVertValue[iPos] = fTemp;

			// point
			PtTemp = pCurve->m_ArrPoint[iPre];
			pCurve->m_ArrPoint[iPre] = pCurve->m_ArrPoint[iPos];
			pCurve->m_ArrPoint[iPos] = PtTemp;
		}
	}
}

// decription  : get CCurve object pointer by its index in this CCurveCtrl 
CCurve* CCurveCtrl::GetCurve(int iIndex)
{
	if (iIndex > m_ArrCurve.GetUpperBound() || iIndex < 0)
		return NULL;

	return m_ArrCurve[iIndex];
}

// decription  : get CCurve object pointer by its name
CCurve* CCurveCtrl::GetCurve(const CString& strName)
{
	CCurve*		pCurve = NULL;
	for (int iCurve = 0; iCurve < m_ArrCurve.GetSize(); iCurve++)
	{
		if (strName == m_ArrCurve[iCurve]->m_strName)
		{
			pCurve = m_ArrCurve[iCurve];
			break;			
		}
	}

	return pCurve;
}

// decription  : get index in this CCurveCtrl by CCurve object pointer
int	CCurveCtrl::GetIndex(const CCurve* pCurve)
{
	int iPos = -1;
	for (int iCur = 0; iCur < m_ArrCurve.GetSize(); iCur++)
	{
		if (pCurve == m_ArrCurve[iCur])
		{
			iPos = iCur;
			break;
		}
	}

	return iPos;
}

// decription  : remove one curve by its index
BOOL CCurveCtrl::Remove(int index)
{
	if (index < 0 || index > m_ArrCurve.GetUpperBound())
		return FALSE;

	delete m_ArrCurve[index];
	m_ArrCurve[index] = NULL;
	m_ArrCurve.RemoveAt(index);

	// disable edit mode if no curve selected
	if (GetSelectedCount() < 1)
		m_bEdit = FALSE;

	return TRUE;
}

// decription  : remove one curve by its name
BOOL CCurveCtrl::Remove(const CString& strName)
{
	for (int iCurve = 0; iCurve < m_ArrCurve.GetSize(); iCurve++)
	{
		if (strName == m_ArrCurve[iCurve]->m_strName)
		{
			delete m_ArrCurve[iCurve];
			m_ArrCurve[iCurve] = NULL;
			m_ArrCurve.RemoveAt(iCurve);

			return TRUE;
		}
	}

	return FALSE;
}

// decription  : remove all curve object in this CCurveCtrl
void CCurveCtrl::RemoveAll()
{
	for (int iC = 0; iC < m_ArrCurve.GetSize(); iC++)
	{
		delete m_ArrCurve[iC];
		m_ArrCurve[iC] = NULL;		
	}
	m_ArrCurve.RemoveAll();

	// there are no curve, so disable edit
	m_bEdit = FALSE;
}

// decription  : get curve count in this CCurveCtrl
int	CCurveCtrl::GetCurveCount() 
{
	return m_ArrCurve.GetSize(); 
}

// decription  : get selected curve count
int	CCurveCtrl::GetSelectedCount()
{
	int nSelected = 0;
	
	for (int iCurve = 0; iCurve < m_ArrCurve.GetSize(); iCurve++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -