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

📄 coordinate.cpp

📁 自定义一些x,y坐标,可以模拟出一些光滑的曲线
💻 CPP
字号:
// Coordinate.cpp: implementation of the CCoordinate class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "BiJin.h"
#include "Coordinate.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCoordinate::CCoordinate()
{
	m_pPtrList = new CPtrList;
}

CCoordinate::~CCoordinate()
{
	for(int i=0;i<m_pPtrList->GetCount();i++)
	{
		POSITION pos;
		pos = m_pPtrList->FindIndex(i);
		CFoldPoint *pFoldPoint = (CFoldPoint *)m_pPtrList->GetAt(pos);
		m_pPtrList->RemoveAt(pos);
	}
	m_pPtrList->RemoveAll();
	delete m_pPtrList;
}
void CCoordinate::Getcoordinate(CStdioFile *pFile)
{
	int m_Length = pFile->GetLength();
	CFoldPoint *m_pFoldPoint = new CFoldPoint;
	CString pBuf;
	pFile->ReadString(pBuf);
	m_Length -= pBuf.GetLength();
	split(pBuf,m_dest,',');
	m_pFoldPoint->x = atof(m_dest.GetAt(0));
	m_pFoldPoint->y = atof(m_dest.GetAt(1));
	m_pPtrList->AddTail((CObject *)m_pFoldPoint);
	while(m_Length)
	{
		m_pFoldPoint = new CFoldPoint;
		pFile->ReadString(pBuf);
		m_Length -= (pBuf.GetLength()+2);
		split(pBuf,m_dest,',');
		m_pFoldPoint->x = atof(m_dest.GetAt(0));
		m_pFoldPoint->y = atof(m_dest.GetAt(1));
		m_pPtrList->AddTail((CObject *)m_pFoldPoint);
	}
	/*int m_nLength = pFile->GetLength();
	char *m_pBuf = new char[m_nLength];
	pFile->Read(m_pBuf,m_nLength);
	CFoldPoint *m_pFoldPoint;
	int m_nCount = 1;
	for(int i=0;i<m_nLength;i++)
	{
		if(m_pBuf[i] == 13)
			m_nCount++;
	}
	char *p1 = m_pBuf;
	char *p2 = m_pBuf;
	for(int j=0;j<m_nCount-1;j++)
	{
		m_pFoldPoint = new CFoldPoint;
		while((*p2) != ',')
			p2++;
		m_pFoldPoint->x = 0;
		while(p1 < p2)
		{
			m_pFoldPoint->x += (int)((*p1 - 48)*pow(10,p2-p1));
			p1++;
		}
		p1++;
		p2++;
		while((*p2) != 13)
			p2++;
		m_pFoldPoint->y  = 0;
		while(p1 < p2)
		{ 
			m_pFoldPoint->y  += (int)((*p1 - 48)*pow(10,p2-p1-1));
			p1++;
		}
		p1 +=2;
		p2 +=2;
		m_pPtrList->AddTail((CObject *)m_pFoldPoint);
	}
	m_pFoldPoint = new CFoldPoint;
	while((*p2) != ',')
		p2++;
	m_pFoldPoint->x = 0;
	while(p1 < p2)
	{
		m_pFoldPoint->x += (int)((*p1 - 48)*pow(10,p2-p1));
		p1++;
	}
	p1++;
	p2++;
	while((*p2) != '.')
		p2++;
	m_pFoldPoint->y = 0;
	while(p1 < p2)
	{
		m_pFoldPoint->y += (int)((*p1 - 48)*pow(10,p2-p1-1));
		p1++;
	}
	m_pPtrList->AddTail((CObject *)m_pFoldPoint);
	delete []m_pBuf;
	p1 = NULL;
	p2 = NULL;*/
}
void CCoordinate::split(CString source,CStringArray &dest ,char a)
{
	dest.RemoveAll();
	for(int i=0;i<source.GetLength();i++)
	{
		if(source.GetAt(i) == a)
		{
			dest.Add(source.Left(i));//去掉右边
			for(int j=0;j<dest.GetSize()-1;j++)
			{
				dest[dest.GetSize()-1] = dest[dest.GetSize()-1].Right(dest[dest.GetSize()-1].GetLength() 
					- dest[j].GetLength() - 1);//去掉左边
			}
		}
	}
	dest.Add(source);
	for(int j=0;j<dest.GetSize()-1;j++)
	{
		dest[dest.GetSize()-1] = dest[dest.GetSize()-1].Right(dest[dest.GetSize()-1].GetLength() 
					- dest[j].GetLength() - 1);
	}
}
bool CCoordinate::GetLowest()
{
	if(!m_pPtrList)return false;
	int size = m_pPtrList->GetCount();
	POSITION lowPos,tmpPos,lowPos1;
	double lowY;
	lowPos1 = lowPos = m_pPtrList->FindIndex(0);
	((CFoldPoint *)m_pPtrList->GetAt(lowPos))->m_bLow = true;
	for(int i=1;i<size-5;i++)
	{
		lowPos = m_pPtrList->FindIndex(i);
		CFoldPoint *pFoldPoint = (CFoldPoint *)m_pPtrList->GetAt(lowPos);
		lowY = pFoldPoint->y;
		for(int j=i;j<i+5;j++)
		{
			tmpPos = m_pPtrList->FindIndex(j);
			pFoldPoint = (CFoldPoint *)m_pPtrList->GetAt(tmpPos);
			if(pFoldPoint->y < lowY)
			{
				lowY = pFoldPoint->y;
				lowPos = tmpPos;
			}			
		}
		if(lowPos != lowPos1)
		{
			((CFoldPoint *)m_pPtrList->GetAt(lowPos))->m_bLow = true;
		}
		lowPos1 = lowPos;
	}
	lowPos = m_pPtrList->FindIndex(size-1);
	((CFoldPoint *)m_pPtrList->GetAt(lowPos))->m_bLow = true;
	return true;
}
CPtrList* CCoordinate::SPLine(CPtrList *pList,int SM)//计算pDestList的每个点的横,纵坐标
//三次样条插值算法
{
	CPtrList *pDestList = new CPtrList;
	CFoldPoint *pFoldHead,*pFoldTail;
	POSITION pos;
	CDoubleArray X,Y;
	double XI,YI,XX,YY;
	register long i;
	long RealSM;
	long Bei,Yu;
	CFoldPoint *pFold;
//file://赋初值
	long n=pList->GetCount();
	pos=pList->GetHeadPosition();
	for(i=0;i<n;i++)
	{
		pFold=(CFoldPoint *)pList->GetNext(pos);
		if(pFold->m_bLow == true)
		{
			X.Add(pFold->x);
			Y.Add(pFold->y);
		}
	}
	pFoldHead=(CFoldPoint *)pList->GetHead();
	pFoldTail=(CFoldPoint *)pList->GetTail();
//file://x连续
	YI=0;
	N = X.GetSize();
	RealSM = (N-1)*SM+N;
	for(i=0;i<RealSM;i++)
	{
		Bei=i/(SM+1);
		Yu=i%(SM+1);
		if(Yu!=0)
		{
			XI=X.GetAt(Bei)+(X.GetAt(Bei+1)-X.GetAt(Bei))/(SM+1)*Yu;
			SPLine4(&X,&Y,XI,YI);
			//SPLine1(&X,&Y,XI,YI);
			XX=XI;
			YY=YI;
		}
		else
		{
			XX=X.GetAt(Bei);
			YY=Y.GetAt(Bei);
		}
		pFold=new CFoldPoint;
		pFold->x=XX;
		pFold->y=YY;
		pDestList->AddTail(pFold);
	}
	return pDestList;
}
void CCoordinate::SPLine1(CDoubleArray *X,CDoubleArray *Y,double &XI,double &YI)//用直线拟合曲线,
//不保证光滑
{
	for(int i=1;i<N;i++)
	{
		if(XI>=X->GetAt(i-1) && XI<=X->GetAt(i))
		{
			double A = (X->GetAt(i) - XI)/(X->GetAt(i) - X->GetAt(i-1));
			double B = 1 - A;
			YI = A*Y->GetAt(i-1)+B*Y->GetAt(i); 
		}
	}
}
void CCoordinate::SPLine4(CDoubleArray *X,CDoubleArray *Y,double &XI,double &YI)//算法为三次样条插值
{
	//给定数组X和Y其中y(i)=x(i),0<x1<x2....<x(n)给指定的数据Xi
	double *A,*B,*C,*G;
	//MX = G中,A为M上副对角线元素,B为M主对角线元素,C为M下副对角线元素,G为方程的常量元素
	register long I;
	double W1,W2,H; 
	A = new double[N];
	B = new double[N];
	C = new double[N];
	G = new double[N];
	for(I=1;I<N;I++)
	{
		B[I]=X->GetAt(I) - X->GetAt(I-1);//B(I)为X(I) - X(I-1)
		C[I]=(Y->GetAt(I) - Y->GetAt(I-1))/B[I];//C(I)为(Y(I)-Y(I-1))/(X(I)-X(I-1))
	}
	for(I=0;I<N;I++)
	{
		A[I]=B[I]+B[I+1];
		G[I]=6*(C[I+1] - C[I])/A[I];
		A[I]=B[I]/A[I];
	}
	for(I=1;I<N;I++)
	{
		C[I]=1-A[I];
		B[I]=2;
	}
	//上述两个算法为三对角的分解循环,MX = G中,
	//A为M上副对角线元素,B为M主对角线元素,C为M下副对角线元素,G为方程的常量元素
	B[N-1]=X->GetAt(N-1);
	C[0]=1;
	A[N-1]=-1;
	A[0]=0;
	C[N-1]=0;
	ZG(A,B,C,&G);
	//所得到的矩阵方程(x(j)-x(j-1))*y''(j-1)/6+(x(j+1)-x(j-1))*y''(j)/3+(x(j+1)-x(j))*y''(j+1)/6
	//=(y(j+1)-y(j))/(x(j+1)-x(j)) - (y(j)-y(j-1))/(x(j)-x(j-1))
	for(I=1;I<N;I++)
	{
		if(XI>=X->GetAt(I-1) && XI<=X->GetAt(I))//GE LE
		{
			H=X->GetAt(I) - X->GetAt(I-1);
			W1=X->GetAt(I) - XI;
			W2=XI - X->GetAt(I-1);
			YI=W1*W1*W1*G[I-1]/6/H;
			YI=YI+W2*W2*W2*G[I]/6/H;
			YI=YI+W1*(Y->GetAt(I-1)-G[I-1]*H*H/6)/H;
			YI=YI+W2*(Y->GetAt(I)-G[I]*H*H/6)/H;
		}
	}
	delete []A;
	delete []B;
	delete []C;
	delete []G;
}
void CCoordinate::ZG(double *A,double *B,double *C,double **G) //MX = G,其中M
//含有上副对角元素A,主对角元素B,以及下副对角元素C,最终所得的解坐标保存到G中
{
	//追赶法
	register long I;
	C[0]=C[0]/B[0];
	for(I=1;I<N;I++)
	{
		B[I]=B[I]-A[I]*C[I-1];
		C[I]=C[I]/B[I];//分解
	}
	A[0]=0;
	C[N-1]=0;
	(*G)[0]=(*G)[0]/B[0];
	for(I=1;I<N;I++)
	{
		(*G)[I]=((*G)[I]-A[I]*(*G)[I-1])/B[I];//前代
	}
	for(I=N-2;I>-1;I--)//DO 30 I=N-1,1,-1
	{
		(*G)[I]=(*G)[I]-C[I]*(*G)[I+1];//回代
	}
}
double CCoordinate::NewY(CPtrList *pList,double XI)
{
	POSITION pos;
	CDoubleArray X,Y;
	double YI;
	register long i;
	CFoldPoint *pFold;
//file://赋初值
	long n=pList->GetCount();
	pos=pList->GetHeadPosition();
	for(i=0;i<n;i++)
	{
		pFold=(CFoldPoint *)pList->GetNext(pos);
		if(pFold->m_bLow == true)
		{
			X.Add(pFold->x);
			Y.Add(pFold->y);
		}
	}
//file://x连续
	YI=0;
	N = X.GetSize();
	SPLine4(&X,&Y,XI,YI);
	return YI;
}

⌨️ 快捷键说明

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