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

📄 bsplineinterpolateobj.cpp

📁 B样条插值
💻 CPP
字号:
#include "stdafx.h"
#include "BSplineInterpolateObj.h"



CBSplineInterpolateObj::CBSplineInterpolateObj()
{
	m1 =0;
	n1= 0;
	PhiIJ = NULL;
	ScatteredPoint = NULL;
	ScatteredPointNumber = 0;
}
CBSplineInterpolateObj::~CBSplineInterpolateObj()
{
	m1 = 0;
	n1 = 0;
	if (PhiIJ) {
		delete []PhiIJ;
	}
	if (ScatteredPoint) {
		delete []ScatteredPoint;
	}
	ScatteredPointNumber = 0;
}
//=================控制点网格化函数,需要传入网格步长=============================//
//        入口:*ScatteredPnt(散乱点集数组),PntNum(散乱点集数组个数),Step(网格步长)
//        出口:M1(控制点网格φ:(m1+3)*(n1+3)),N1(控制点网格φ:(m1+3)*(n1+3)),
//        返回:1/0,成功/失败
//===============================================================================//
long CBSplineInterpolateObj::ControlPntTransform(G3D_Dot *ScatteredPnt,long PntNum,float XStep,float YStep, long &M1,long &N1)
{
	VECTOR_FLOAT ScateredPnt_X;
	VECTOR_FLOAT ScateredPnt_Y;
	int i =0;
	float temp;
	float StepX;
	float StepY;
	//存入向量,求出xy区域的最值
	for(i = 0;i<PntNum;i++)
	{
		temp = ScatteredPnt[i].x;
		ScateredPnt_X.push_back(temp);
		temp = ScatteredPnt[i].y;
		ScateredPnt_Y.push_back(temp);
	}
	sort(ScateredPnt_X.begin(),ScateredPnt_X.end());
	sort(ScateredPnt_Y.begin(),ScateredPnt_Y.end());
	
	StepX = (ScateredPnt_X[PntNum - 1])/(XStep);
	StepY = (ScateredPnt_Y[PntNum - 1])/(YStep);
	m1 = int(StepX) + 1;
	n1 = int(StepY) + 1;
	M1 = m1;
	N1 = n1;
	ScatteredPointNumber = PntNum;
	ScatteredPoint = new G3D_Dot[ScatteredPointNumber];
	for(i = 0;i<PntNum;i++)
	{
		ScatteredPoint[i].x = ScatteredPnt[i].x;
		ScatteredPoint[i].y = ScatteredPnt[i].y;
		ScatteredPoint[i].z = ScatteredPnt[i].z;
	}

	if (m1<=0||n1<=0||(ScatteredPointNumber == 0)||ScatteredPoint == NULL ) {
		return 0;
	}
	return 1;
}



//===========计算均匀单方向上的三次B样条基函数(B0(s),B1(s),B2(s),B3(s))==========//
//        入口:S(变量值)
//        出口:*BSplineValue(四个值的数组)
//        返回:1/0,成功/失败
//===============================================================================//
long CBSplineInterpolateObj::GetBasicBSplineFuction(float S,float *BSplineValue)
{
	if (!BSplineValue) {
		return  0;
	}
    BSplineValue[0] = (1.0f/6) * (1 + 3 * S - 3 * S * S + S * S * S);
	BSplineValue[1] = (1.0f/6) * (3 - 6 * S + 4 * S * S * S);
	BSplineValue[2] = (1.0f/6) * (-3 + 3 * S + 3 * S *S + S * S * S);
	BSplineValue[3] = 1;
	return 1;
}



//===========基本函数:计算Wkl函数值=============================================//
//        入口:k(0~3),l(0~3),s(Bk(s)),t(Bl(t))
//        出口:W(Wkl函数值)
//        返回:1/0,成功/失败
//===============================================================================//
long CBSplineInterpolateObj::CalculateW(int k,int l,float s,float t,float &W)
{
	float tempBValue1;
	float tempBValue2;
	if ((k == 0) && (l == 0)) {//k = 0,l = 0
		tempBValue1 = (1.0f/6) * (1 - 3 * s + 3 * s * s - s * s * s);
        tempBValue2 = (1.0f/6) * (1 - 3 * t + 3 * t * t - t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
	if ((k == 1) && (l == 1)) {//k = 1,l =1;
		tempBValue1 = (1.0f/6) * (4 - 6 * s * s + 3 * s * s * s);
        tempBValue2 = (1.0f/6) * (4 - 6 * t * t + 3 * t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
    if ((k == 2) && (l == 2)) {//k = 2; l =2;
		tempBValue1 = (1.0f/6) * (1 + 3 * s + 3 * s * s - 3 * s * s * s);
        tempBValue2 = (1.0f/6) * (1 + 3 * t + 3 * t * t - 3 * t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
	if ((k == 3) && (l == 3)) {//k = 3, l =3;
		tempBValue1 = (1.0f/6) * (s * s * s);
        tempBValue2 = (1.0f/6) * (t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
	if ((k == 0) && (l == 1)) {// k =0,l = 1;
		tempBValue1 = (1.0f/6) * (1 - 3 * s + 3 * s * s - s * s * s);
        tempBValue2 = (1.0f/6) * (4 - 6 * t * t + 3 * t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
	if ((k == 0) && (l == 2)) {//k = 0;l = 2;
		tempBValue1 = (1.0f/6) * (1 - 3 * s + 3 * s * s - s * s * s);
        tempBValue2 = (1.0f/6) * (1 + 3 * t + 3 * t * t - 3 * t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
    if ((k == 0) && (l == 3)) {// k = 0;l =3;
		tempBValue1 = (1.0f/6) * (1 - 3 * s + 3 * s * s - s * s * s);
        tempBValue2 = (1.0f/6) * (t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
    if ((k == 1) && (l == 0)) {// k = 1, l = 0;
		tempBValue1 = (1.0f/6) * (4 - 6 * s * s + 3 * s * s * s);
        tempBValue2 = (1.0f/6) * (1 - 3 * t + 3 * t * t - t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
	if ((k ==1) && (l == 2)) {// k = 1,l = 2;
		tempBValue1 = (1.0f/6) * (4 - 6 * s * s + 3 * s * s * s);
        tempBValue2 = (1.0f/6) * (1 + 3 * t + 3 * t * t - 3 * t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
    if ((k == 1) && (l == 3)) {// k = 1, l = 3;
		tempBValue1 = (1.0f/6) * (4 - 6 * s * s + 3 * s * s * s);
        tempBValue2 = (1.0f/6) * (t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
    if ((k == 2) && (l == 0)) {// k = 2, l = 0;
		tempBValue1 = (1.0f/6) * (1 + 3 * s + 3 * s * s - 3 * s * s * s);
        tempBValue2 = (1.0f/6) * (1 - 3 * t + 3 * t * t - t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
	if ((k == 2) && (l == 1)) {// k = 2, l = 1;
		tempBValue1 = (1.0f/6) * (1 + 3 * s + 3 * s * s - 3 * s * s * s);
        tempBValue2 = (1.0f/6) * (4 - 6 * t * t + 3 * t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
    if ((k == 2) && (l == 3)) {// k = 2, l = 3;
		tempBValue1 = (1.0f/6) * (1 + 3 * s + 3 * s * s - 3 * s * s * s);
        tempBValue2 = (1.0f/6) * (t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
    if ((k == 3) && (l == 0)) {//k = 3, l =0;
		tempBValue1 = (1.0f/6) * (s * s * s);
        tempBValue2 = (1.0f/6) * (1 - 3 * t + 3 * t * t - t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
    if ((k == 3) && (l == 1)) {//k = 3, l =1;
		tempBValue1 = (1.0f/6) * (s * s * s);
        tempBValue2 = (1.0f/6) * (4 - 6 * t * t + 3 * t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
	if ((k == 3) && (l == 2)) {//k = 3, l =2;
		tempBValue1 = (1.0f/6) * (s * s * s);
        tempBValue2 = (1.0f/6) * (1 + 3 * t + 3 * t * t - 3 * t * t * t);
		W = tempBValue1 * tempBValue2;
		return 1;
	}
	return 0 ;
}

//=====================计算控制点的φij值(先计算φc值)===========================//
//        入口:*ScatteredPnt(散乱点集数组),PntNum(散乱点集数组个数),
//              M1(0<=x<m1),N1(0<=y<n1)
//              Step(步长)
//        出口:*Phiij
//        返回:1/0,成功/失败
//===============================================================================//
long CBSplineInterpolateObj::GetPhiIJValue(G3D_Dot *ScatteredPnt,long PntNum,long M1, long N1,float XStep,float YStep,float *Phiij)
{
     if (!PhiIJ) {
		return 0;
	}
	VECTOR_FLOAT ScateredPnt_X;
	VECTOR_FLOAT ScateredPnt_Y;
    VECTOR_FLOAT ScateredPnt_Z;
    VECTOR_FLOAT Wab;
	VECTOR_FLOAT::iterator it;
	VECTOR_FLOAT TempWc;
	
    int i =0;
	int j =0;
	int n = 0;
	int k = 0;
	int l = 0;
	int m = 0;
	int p = 0;
	int Num = 0;
	int tempm = 0;
	int tempn = 0;
	float temp = 0;
	float FTemp = 0;
	float s = 0;
	float t = 0;
	float wc = 0;
	float numerator = 0;//分子
	float denominator  = 0;//分母
	float wab = 0;
	float PhiCTemp = 0;
	float Tempnumerator = 0;
	float Tempdenominator = 0;
	//矩形域上的控制点网格
    typedef struct ControlGrid {
		int M;
		int N;//(m1+3)*(n1+3)网格
		int Num;//邻近点集数目
		VECTOR_FLOAT IncludePnt;//邻近点数组(x,y,z三个一组,共3*Num个)
    }ControlGrid;
	ControlGrid * MN = new ControlGrid[sizeof(ControlGrid) * (m1+3) * (n1+3)];
	VECTOR_FLOAT PhiC;//中间变量φc
    //矩形域网格赋值
	for(i = 0;i<M1+3;i++)
	{
		for(j = 0;j<N1+3;j++)			
		{
            MN[i*(N1+3) + j].M = i - 1;      //矩形域
			MN[i*(N1+3) + j].N = j - 1;
			MN[i*(N1+3) + j].Num = 0;
		}
	}
	//散乱数据点值分别存入向量
	for(i = 0;i<PntNum;i++)
	{
		temp = ScatteredPnt[i].x;
		ScateredPnt_X.push_back(temp);
		temp = ScatteredPnt[i].y;
		ScateredPnt_Y.push_back(temp);
		temp = ScatteredPnt[i].z;
		ScateredPnt_Z.push_back(temp);
	}
	//邻近点集搜索,从-1开始到m+1,从-1开始到n+1
	for(i = 0;i<M1+3;i++)
	{
		for(j = 0;j<N1+3;j++)
		{
			tempm =  MN[i*(N1+3) + j].M;
			tempn =  MN[i*(N1+3) + j].N;
			for(k = 0;k<PntNum;k++)   
			{//找到4 × 4格子内的邻近点
				if(((ScatteredPnt[k].x - (tempm - 2)*XStep)>=0)&&((ScatteredPnt[k].x - (tempm + 2)*XStep)<0)
					&&((ScatteredPnt[k].y - (tempn -2)*YStep)>=0)&&((ScatteredPnt[k].y - (tempn + 2)*YStep)<0)) {
                    temp = ScatteredPnt[k].x;
					MN[i*(N1+3) + j].IncludePnt.push_back(temp);
					temp = ScatteredPnt[k].y;
					MN[i*(N1+3) + j].IncludePnt.push_back(temp);
					temp = ScatteredPnt[k].z;
					MN[i*(N1+3) + j].IncludePnt.push_back(temp);
					MN[i*(N1+3) + j].Num += 1;
				} 
			}
		}
	}
	CBSplineInterpolateObj tempObj;
	//开始计算φc,对于每一个点,必须从其邻近点集里面计算,最后给φij赋值
	for( i = 0;i<M1+3;i++)
	{
		for( j = 0;j<N1+3;j++)
		{
            Num = MN[i*(N1+3) + j].Num;
			if(Num == 0)
				Phiij[i * (N1+3) + j] = 0;
			else
			if(Num  == 1) {//一个邻近点时候直接将φc赋值给φij
                temp = MN[i*(N1+3) + j].IncludePnt[0]; 
				FTemp = MN[i*(N1+3) + j].IncludePnt[1];
				s = temp - int(temp);
				t = FTemp - int(FTemp);
				//计算分子,调用基本函数
				temp = temp / XStep;
				FTemp = FTemp / YStep;
				k = MN[i*(N1+3) +j].M + 1  - int(temp);
				l = MN[i*(N1+3) +j].N + 1  - int(FTemp);
                //计算Wc
                tempObj.CalculateW(k,l,s,t,wc);
                numerator = wc * MN[i * (N1+3) + j].IncludePnt[2];
				//计算分母
                for(m = 0;m<4;m++)
				{
					for(p = 0;p<4;p++)
					{
						tempObj.CalculateW(m,p,s,t,wab);
						wab = wab * wab;
						Wab.push_back(wab);
					}				
				}
				for(it = Wab.begin();it != Wab.end();it++)
				{
                    denominator += *it;
				}
				PhiCTemp = numerator / denominator;
				Phiij[i * (N1+3)+ j] = PhiCTemp;
				Wab.clear();
				numerator = 0;
				denominator = 0;
			}
			else
			if(Num>1)
			{//多个点用最小二乘法求解φij
			 for(n = 0;n<Num;n++)
			 {//每一个点φc
                 temp = MN[i*(N1+3) + j].IncludePnt[3*n + 0];
				 FTemp = MN[i*(N1+3)+ j].IncludePnt[3*n + 1];
				 s = temp - int(temp);
				 t = FTemp - int(FTemp);
				 //计算分子,调用基本函数
				 temp = temp / XStep;
				 FTemp = FTemp / YStep;
				 k = MN[i*(N1+3) +j].M + 1  - int(temp);
				 l = MN[i*(N1+3) +j].N + 1  - int(FTemp);
				 //计算Wc
                 tempObj.CalculateW(k,l,s,t,wc);
				 TempWc.push_back(wc);
				 //计算分子
				 numerator = wc * MN[i * (N1+3) + j].IncludePnt[3*n + 2];
				 //计算分母
				 for( m = 0 ;m<4;m++)
				 {
					 for(p = 0 ;p<4;p++)
					 {
						 tempObj.CalculateW(m,p,s,t,wab);
						 wab = wab * wab;
						 Wab.push_back(wab);
					 }
				 }
				 for(it = Wab.begin();it != Wab.end();it++)
				 {
					 denominator += *it;
				 }
				 PhiCTemp = numerator / denominator;
				 PhiC.push_back(PhiCTemp);
				 Wab.clear();
                 numerator = 0;
				 denominator = 0;
			 }
			 //最小二乘法求φij
			 temp = 0;//清零作叠加
			 FTemp = 0;
			 PhiCTemp = 0;
			 for(n = 0;n<Num;n++)
			 {
				 temp += TempWc[n] * TempWc[n] * PhiC[n];
				 FTemp += TempWc[n] * TempWc[n];
			 }
			 PhiCTemp = (temp) / (FTemp);
			 Phiij[i * (N1+3) + j] = PhiCTemp; 
			}
		}
	}	
    if (MN) {
		delete []MN;
		MN = NULL;
    }
    PhiIJ = new float[(m1 +3)*(n1 +3)];
	for(i = 0;i<m1+3;i++)
	{
		for(j = 0;j<n1+3;j++)
		{
			PhiIJ[i * (n1+3) + j] = Phiij[i * (n1+3) + j];
		}
	}
	if (PhiIJ==NULL) {
		return 0;
	}
     return 1;
}
long CBSplineInterpolateObj::GetInterpolateValue(G3D_Dot * ScatteredPnt,
												 long PntNum,long M1,long N1,float XStep,float YStep,
												 double &Ix,double &Iy,double &Iz)
{
	if (!ScatteredPnt) {
		return 0;
	}
	int I;//下标i
	int J;//下标j
	int k;
	int l;
    float s;
	float t;
	float temp;
	float T = 0;
	float w;
	VECTOR_FLOAT PhiC;//中间变量φc
	VECTOR_FLOAT FxyTemp;
	VECTOR_FLOAT ::iterator it;

	if (PhiIJ == NULL) {
		return 0;
	}
	CBSplineInterpolateObj Obj;
	//求插值
	I = int(Ix / XStep) - 1 + 1;//插值点位置
	J = int(Iy / YStep) - 1 + 1;//插值点位置
	s = Ix - int(Ix);
	t = Iy - int(Iy);
	for(k = 0;k<4;k++)
	{
		for(l = 0;l<4;l++)
		{
            Obj.CalculateW(k,l,s,t,w);
			temp = w;
			temp = temp * PhiIJ[(I + k) * (n1 + 3) + (J + l)];
			FxyTemp.push_back(temp);
		}
	}
	for(it = FxyTemp.begin();it!=FxyTemp.end();it++)
	{
		T += *it;//求和
	}
	//导出f(x,y),即Iz
    Iz = T;
	/*
	for(p = 0;p<IntPntNum;p++)
	{	
	//*	
	I = int((InterpolatePnt[p].x) / Step)  - 1 + 1 ;//插值点位置
	J = int((InterpolatePnt[p].y) / Step)  - 1 + 1 ;//插值点位置
	s = InterpolatePnt[p].x - int(InterpolatePnt[p].x);
	t = InterpolatePnt[p].y - int(InterpolatePnt[p].y);
	
	  for(k = 0;k<4;k++)
	  {
	  for(l = 0;l<4;l++)
	  {
	  CalculateW(k,l,s,t,w);
	  temp = w;
	  temp = temp * PhiIJ[(I + k) * (n1+3) + (J + l)];
	  FxyTemp.push_back(temp);
	  }
	  }
	  for(it = FxyTemp.begin();it!=FxyTemp.end();it++)
	  {
	  T += *it;//求和
	  }
	  Fxy.push_back(T);
	  FxyTemp.clear();
	  T = 0;
	//*/
	return 1;
}

⌨️ 快捷键说明

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