www.gusucode.com > VC++自定义图表控件及使用例子源码程序 > VC++自定义图表控件及使用例子源码程序\code\ChartCtrl_demo\ChartDemo\ChartCtrl\ChartXYSerie.cpp
//Download by http://www.NewXing.com /* * * ChartXYSerie.cpp * * Written by C閐ric Moonen (cedric_moonen@hotmail.com) * * * * This code may be used for any non-commercial and commercial purposes in a compiled form. * The code may be redistributed as long as it remains unmodified and providing that the * author name and this disclaimer remain intact. The sources can be modified WITH the author * consent only. * * This code is provided without any garanties. I cannot be held responsible for the damage or * the loss of time it causes. Use it at your own risks * * An e-mail to notify me that you are using this code is appreciated also. * * */ #include "stdafx.h" #include "ChartXYSerie.h" CChartXYSerie::CChartXYSerie(CChartCtrl* pParent) : CChartSerieBase<SChartXYPoint>(pParent) { } CChartXYSerie::~CChartXYSerie() { } void CChartXYSerie::AddPoint(double X, double Y) { SChartXYPoint newPoint(X, Y); CChartSerieBase<SChartXYPoint>::AddPoint(newPoint); } void CChartXYSerie::AddPoints(double* pX, double* pY, unsigned Count) { SChartXYPoint* pPoints = new SChartXYPoint[Count]; for (unsigned i=0; i<Count; i++) { pPoints[i].X = pX[i]; pPoints[i].Y = pY[i]; } CChartSerieBase<SChartXYPoint>::AddPoints(pPoints, Count); delete pPoints; } void CChartXYSerie::SetPoints(double* pX, double* pY, unsigned Count) { SChartXYPoint* pPoints = new SChartXYPoint[Count]; for (unsigned i=0; i<Count; i++) { pPoints[i].X = pX[i]; pPoints[i].Y = pY[i]; } CChartSerieBase<SChartXYPoint>::SetPoints(pPoints, Count); delete pPoints; } double CChartXYSerie::GetXPointValue(unsigned PointIndex) const { return m_vPoints[PointIndex].GetX(); } double CChartXYSerie::GetYPointValue(unsigned PointIndex) const { return m_vPoints[PointIndex].GetY(); } void CChartXYSerie::SetXPointValue(unsigned PointIndex, double NewVal) { m_vPoints[PointIndex].X = NewVal; m_vPoints.ReorderPoints(); RefreshAutoAxes(true); } void CChartXYSerie::SetYPointValue(unsigned PointIndex, double NewVal) { m_vPoints[PointIndex].Y = NewVal; m_vPoints.ReorderPoints(); RefreshAutoAxes(true); } #ifndef NO_USER_DATA void CChartXYSerie::SetUserData(unsigned uPointIndex, void* pData) { m_vPoints[uPointIndex].pUserData = pData; } void* CChartXYSerie::GetUserData(unsigned uPointIndex) { return m_vPoints[uPointIndex].pUserData; } #endif void CChartXYSerie::GetBezierControlPoints(unsigned uFirst, unsigned uLast, SChartXYPoint* &pKnots, SChartXYPoint* &pFirstControlPoints, SChartXYPoint* &pSecondControlPoints) const { int Count = uLast - uFirst - 1; if (Count < 1) { pFirstControlPoints = new SChartXYPoint[0]; pSecondControlPoints = new SChartXYPoint[0]; pKnots = new SChartXYPoint[0]; return; } pKnots = new SChartXYPoint[uLast-uFirst]; SChartXYPoint* pPoints = m_vPoints.GetInternalBuffer(); memcpy(pKnots, pPoints+uFirst, (uLast-uFirst)*sizeof(SChartXYPoint)); // Calculate first Bezier control points // Right hand side vector double* rhs = new double[Count]; // Set right hand side X values int i=0; for (i = 1; i < Count - 1; ++i) rhs[i] = 4 * pKnots[i].X + 2 * pKnots[i + 1].X; rhs[0] = pKnots[0].X + 2 * pKnots[1].X; rhs[Count - 1] = 3 * pKnots[Count - 1].X; // Get first control points X-values double* pFirstX = GetFirstControlPoints(rhs, Count); // Set right hand side Y values for (i = 1; i < Count - 1; ++i) rhs[i] = 4 * pKnots[i].Y + 2 * pKnots[i + 1].Y; rhs[0] = pKnots[0].Y + 2 * pKnots[1].Y; rhs[Count - 1] = 3 * pKnots[Count - 1].Y; // Get first control points Y-values double* pFirstY = GetFirstControlPoints(rhs, Count); // Fill output arrays. pFirstControlPoints = new SChartXYPoint[Count]; pSecondControlPoints = new SChartXYPoint[Count]; for (i = 0; i < Count; ++i) { // First control point pFirstControlPoints[i].X = pFirstX[i]; pFirstControlPoints[i].Y = pFirstY[i]; // Second control point if (i < Count - 1) { pSecondControlPoints[i].X = 2 * pKnots[i + 1].X - pFirstX[i + 1]; pSecondControlPoints[i].Y = 2 * pKnots[i + 1].Y - pFirstY[i + 1]; } else { pSecondControlPoints[i].X = (pKnots[Count].X + pFirstX[Count - 1]) / 2; pSecondControlPoints[i].Y = (pKnots[Count].Y + pFirstY[Count - 1]) / 2; } } delete[] rhs; delete[] pFirstX; delete[] pFirstY; } double* CChartXYSerie::GetFirstControlPoints(double* rhs, int Count) const { double* pPoints = new double[Count]; // Solution vector. double* pTemp = new double[Count]; // Temp workspace. double b = 2.0; pPoints[0] = rhs[0] / b; int i =0; for (i = 1; i < Count; i++) // Decomposition and forward substitution. { pTemp[i] = 1 / b; b = (i < Count - 1 ? 4.0 : 2.0) - pTemp[i]; pPoints[i] = (rhs[i] - pPoints[i - 1]) / b; } for (i = 1; i < Count; i++) pPoints[Count - i - 1] -= pTemp[Count - i] * pPoints[Count - i]; // Backsubstitution. delete[] pTemp; return pPoints; }