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

📄 xgraphdataserie.cpp

📁 Displaying large amounts of technical data in a chart can be a frustrating task. You can find tons o
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	double fSum = 0.0;
    
	TDataPoint* pData;
	
	pData = new TDataPoint[m_nCount];

	pData[0].fXVal = m_pData[0].fXVal;
	pData[0].fYVal = m_pData[0].fYVal;
	
    for ( int i = 1; i < m_nCount; i++ )
    {
		p = min(i, span);

  	    if ( p <= span )
        {
            fSum = 0.0;

            for ( int y = 0; y < p; y++ )
                fSum += m_pData[i-y].fYVal;
        }
        else
            fSum = fSum - m_pData[i-p].fYVal + m_pData[i].fYVal;
		
        pData[i].fYVal = fSum / (double) p;
		pData[i].fXVal = m_pData[i].fXVal;
    }

    return pData;
}

TDataPoint* CXGraphDataSerie::GetExponentialMovingAverage(int span)
{
    double  se    = 2.0 / ((double)span + 1.0);
    double  le    = 1.0 - se;

	TDataPoint* pData;
	
	pData = new TDataPoint[m_nCount];

	pData[0].fXVal = m_pData[0].fXVal;
	pData[0].fYVal = m_pData[0].fYVal;

    for ( int i = 1; i < m_nCount; i++ )
	{
        pData[i].fYVal = m_pData[i].fYVal * se + pData[i-1].fYVal * le;
		pData[i].fXVal = m_pData[i].fXVal;
	}

    return pData;
}

TDataPoint* CXGraphDataSerie::GetLinearMovingAverage(int span)
{
    TDataPoint* pData;

	double  fSum = 0.0;
    double  fDiv = 0.0;
	int     p;
	
	pData = new TDataPoint[m_nCount];

	pData[0].fXVal = m_pData[0].fXVal;
	pData[0].fYVal = m_pData[0].fYVal;

    for ( int i = 1; i < m_nCount; i++ )
	{
        fSum = 0.0;
        p = min(i, span);

        if ( p <= span )
        {
            fDiv = 0.0;

            for ( int y = 1; y <= p; y++ )
                fDiv += (double) y;
        }

        for ( int y = 0; y < p; y++ )
            fSum += m_pData[i-y].fYVal * (p - y);

        pData[i].fYVal = fSum / fDiv;
		pData[i].fXVal = m_pData[i].fXVal;
    }

	return pData;
}

inline double W_BARTLETT(double n, double k, double d = 1.0)
{
    return (n == 0) ? 0 : (d * (1 - fabs((k - 0.5 * n) / (0.5 * n))));
}

TDataPoint* CXGraphDataSerie::GetTriangularMovingAverage(int span)
{
    TDataPoint* pData;

	double  fSum = 0.0;
    double  fDiv = 0.0;
	int     p;
	
	pData = new TDataPoint[m_nCount];

	pData[0].fXVal = m_pData[0].fXVal;
	pData[0].fYVal = m_pData[0].fYVal;

    for ( int i = 1; i < m_nCount; i++ )
	{
        fSum = 0.0;
        p    = min(i, span);

        if ( p <= span )
        {
            fDiv = 0.0;

            for ( int y = 1; y <= p; y++ )
                fDiv += W_BARTLETT(p+1, y, p);
        }

        for ( int y = 1; y <= p; y++ )
            fSum += m_pData[i-y+1].fYVal * W_BARTLETT(p+1, y, p);

        pData[i].fYVal = fSum / fDiv;
		pData[i].fXVal = m_pData[i].fXVal;
    }

    return pData;
}


TDataPoint* CXGraphDataSerie::GetSineWeightedMovingAverage(int span)
{
    TDataPoint* pData;

	double  fSum = 0.0;
    double  fDiv = 0.0;
	double  d    = 0.0;
	double  f    = _PI / (double) (span + 1);
	int     p;
	
	pData = new TDataPoint[m_nCount];

	pData[0].fXVal = m_pData[0].fXVal;
	pData[0].fYVal = m_pData[0].fYVal;

    for ( int i = 1; i < m_nCount; i++ )
	{
        fSum = 0.0;
        p    = min( i, span );

        for ( int y = 0; y < p; y++ )
            fSum += sin((double)(p - y) * f) * m_pData[i-y].fYVal;

        if ( i <= span )
        {
            d = 0.0;
            for ( int y = 1; y <= p; y++ )
                d += sin((double) y * f);
        }

        pData[i].fYVal = fSum / d;
		pData[i].fXVal = m_pData[i].fXVal;
    }

    return pData;
}

BOOL CXGraphDataSerie::HitTestLine(POINT pt0, POINT pt1, POINT ptMouse, int nWidth)
{
  VECTOR2D tt0, tt1;
  double   dist;
  int      nHalfWidth;
  //
  //Get the half width of the line to adjust for hit testing of wide lines.
  //
  nHalfWidth = (nWidth/2 < 1) ? 1 : nWidth/2;
  
  //
  //Convert the line into a vector using the two endpoints.
  //
  POINTS2VECTOR2D(pt0, pt1, tt0);
  
  //Convert the line from the left endpoint to the mouse point into a vector.
  //
  POINTS2VECTOR2D(pt0, ptMouse, tt1);
  //
  //Obtain the distance of the point from the line.
  //
  dist = vDistFromPointToLine(&pt0, &pt1, &ptMouse);
  //
  //Return TRUE if the distance of the point from the line is within the width 
  //of the line
  //

  BOOL bRet = (dist >= -nHalfWidth && dist <= nHalfWidth);
  
  return bRet;
}



void CXGraphDataSerie::Serialize( CArchive& archive )
{
	int nHelper;

	CXGraphObject::Serialize (archive);

    if( archive.IsStoring() )
    {
		archive << m_nCount;

		archive.Write (m_pData, sizeof(TDataPoint) * m_nCount);
		
		archive << m_nFirstVisible;
		archive << m_nLastVisible;
		archive << m_nXAxis;
		archive << m_nYAxis;
		archive << m_nIndex;
		archive << m_nLineSize;
		archive << m_nFillStyle;
		archive << m_nMarkerType;
		archive << m_nMarker;
		archive << m_nMarkerSize;
		archive << m_nLineStyle;
		archive << m_bShowMarker;
		archive << m_bFillBeneath;
		archive << m_bFillTransparent;
		archive << m_nFillCurve;
		archive << m_crFillColor;
		archive << m_cLabel;
		nHelper = (int) m_gtType;
		archive << nHelper;

		
    }
	else
    {
		archive >> m_nCount;

		m_bAutoDelete = true;

		m_pData = new TDataPoint[m_nCount];
		
		archive.Read (m_pData, sizeof(TDataPoint) * m_nCount);

		archive >> m_nFirstVisible;
		archive >> m_nLastVisible;
		archive >> m_nXAxis;
		archive >> m_nYAxis;
		archive >> m_nIndex;
		archive >> m_nLineSize;
		archive >> m_nFillStyle;
		archive >> m_nMarkerType;
		archive >> m_nMarker;
		archive >> m_nMarkerSize;
		archive >> m_nLineStyle;
		archive >> m_bShowMarker;
		archive >> m_bFillBeneath;
		archive >> m_bFillTransparent;
		archive >> m_nFillCurve;
		archive >> m_crFillColor;
		archive >> m_cLabel;
		archive >> nHelper;
		m_gtType = (EGraphType) nHelper;
    }
}


/////////////////////////////////////////////////////////////////

bool CPolynomialSolver::Solve(double a[], double b[], int n)
{
	for (int i = 0; i < n; i ++)
	{
		// find pivot
		double mag = 0;
		int pivot = -1;
		
		for (int j = i; j < n; j ++)
		{
			double mag2 = fabs(a[i + j * n]);
			if (mag2 > mag)
			{
				mag = mag2;
				pivot = j;
			}
		}
			
		// no pivot: error
		if (pivot == -1 || mag == 0) 
			return false;
		
		// move pivot row into position
		if (pivot != i)
		{
			double temp;
			for (int j = i; j < n; j ++)
			{
				temp = a[j + i * n];
				a[j + i * n] = a[j + pivot * n];
				a[j + pivot * n] = temp;
			}
				
			temp = b[i];
			b[i] = b[pivot];
			b[pivot] = temp;
		}
			
		// normalize pivot row
		mag = a[i + i * n];
		for (j = i; j < n; j ++) a[j + i * n] /= mag;
		b[i] /= mag;
		
		// eliminate pivot row component from other rows
		for (int i2 = 0; i2 < n; i2 ++)
		{
			if (i2 == i) continue;
			
			double mag2 = a[i + i2 * n];
			
			for (int j = i; j < n; j ++) 
				a[j + i2 * n] -= mag2 * a[j + i * n];
			
			b[i2] -= mag2 * b[i];
		}
	}

	return true;
}

bool CPolynomialSolver::Polyfit(int nRows, int nOrder, TDataPoint *pData)
{
	int rows   = nRows;
	int order  = nOrder;
	m_nGlobalO = order;

	double *base   = new double[order * rows];
	double *alpha  = new double[order * order];
	double *alpha2 = new double[order * order];
	double *beta   = new double[order];
			
	// calc base
	for (int i = 0; i < order; i ++)
	{
		for (int j = 0; j < rows; j ++)
		{
			int k = i + j * order;
			base[k] = i == 0 ? 1.0 : pData[j].fXVal * base[k - 1];
		}
	}
				
	// calc alpha2
	for (i = 0; i < order; i ++)
	{
		for (int j = 0; j <= i; j ++)
		{
			double sum = 0.0;
			for (int k = 0; k < rows; k ++)
			{
				int k2 = i + k * order;
				int k3 = j + k * order;
				sum += base[k2] * base[k3];
			}

			int k2 = i + j * order;

			alpha2[k2] = sum;
			
			if (i != j)
			{
				k2 = j + i * order;
				alpha2[k2] = sum;
			}
		}
	}
	
	// calc beta
	for (int j = 0; j < order; j ++)
	{
		double sum = 0;
		for (int k = 0; k < rows; k ++)
		{
			int k3 = j + k * order;
			sum += pData[k].fYVal  * base[k3];
		}

		beta[j] = sum;
	}
		
	// get alpha
	for (j = 0; j < order * order; j ++) 
		alpha[j] = alpha2[j];
	
	// solve for params
	bool bRes = Solve(alpha, beta, order);
				
	for (j = 0; j < order; j ++)
		m_fC[j] = beta[j];
	
	delete base;
	delete beta;
	delete alpha;
	delete alpha2;

	return bRes;
}


double CPolynomialSolver::GetValue(double fX)
{
	double fRes = 0.0;

	for (int i = 0; i < m_nGlobalO; i++)
		fRes += (m_fC[i] * pow(fX, i));

	return fRes;
}


⌨️ 快捷键说明

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