MFC绘制Bezier曲面拼接圆

MFC绘制Bezier曲面拼接圆

在这里插入图片描述
理论算法与代码参考《计算几何算法与实现》–孔令德
下面给出绘制代码:
1、在上一篇文章的代码基础上,继续进行添加,地址链接
2、添加描述曲面片的数据类CPatch

#pragma once
class CPatch
{
public:
	CPatch(void);
	~CPatch(void);
public:
	int pNumber;//表面顶点数
	int pIndex[4][4];//表面顶点索引号
};


#include "StdAfx.h"
#include "Patch.h"


CPatch::CPatch(void)
{
}


CPatch::~CPatch(void)
{
}

2、在Bezier曲面片绘制类中添加直角投影函数,并将原来的斜二测投影的地方更换为直角投影

CP2 CBicubicBezierPatch::ObliqueProjection(CP3 Point3)
{
	CP2 Point2;
	Point2.x=Point3.x-Point3.z*sqrt(2.0)/2.0;
	Point2.y=Point3.y-Point3.z*sqrt(2.0)/2.0;
	return Point2;
}

3、在View类中添加头文件,成员属性与成员函数

#include"Patch.h"
	CP3 Vertex[62];//读取拼接圆的61个顶点数据
	void ReadVertex(void);
	CPatch S[8];//曲面片的构成点
	void ReadPatch(void);//读取点
	void DrawBezierSphere(CDC*pDC);//绘制曲面片圆
	CBicubicBezierPatch patch;//实例化对象
void CDrawSewBezierView::ReadVertex(void)
{
	double r=200;//球的半径
	const double m=0.5523;//球半径计算的魔术常数
	//第一卦限控制点
	Vertex[0].x=0.0, Vertex[0].y=r, Vertex[0].z=0.0;
	Vertex[1].x=0.0, Vertex[1].y=r, Vertex[1].z=m*r;
	Vertex[2].x=0.0, Vertex[2].y=m*r, Vertex[2].z=r;
	Vertex[3].x=0.0, Vertex[3].y=0.0, Vertex[3].z=r;
	Vertex[4].x=m*m*r, Vertex[4].y=r, Vertex[4].z=m*r;
	Vertex[5].x=m*r, Vertex[5].y=m*r, Vertex[5].z=r;
	Vertex[6].x=m*r, Vertex[6].y=0, Vertex[6].z=r;
	Vertex[7].x=m*r, Vertex[7].y=r, Vertex[7].z=m*m*r;
	Vertex[8].x=r, Vertex[8].y=m*r, Vertex[8].z=m*r;
	Vertex[9].x=r, Vertex[9].y=0.0, Vertex[9].z=m*r;
	Vertex[10].x=m*r, Vertex[10].y=r, Vertex[10].z=0.0;
	Vertex[11].x=r, Vertex[11].y=m*r, Vertex[11].z=0.0;
	Vertex[12].x=r, Vertex[12].y=0.0, Vertex[12].z=0.0;

	//第二卦限控制点
	Vertex[13].x=m*r, Vertex[13].y=r, Vertex[13].z=-m*m*r;
	Vertex[14].x=r, Vertex[14].y=m*r, Vertex[14].z=-m*r;
	Vertex[15].x=r, Vertex[15].y=0.0, Vertex[15].z=-m*r;
	Vertex[16].x=m*m*r, Vertex[16].y=r, Vertex[16].z=-m*r;
	Vertex[17].x=m*r, Vertex[17].y=m*r, Vertex[17].z=-r;
	Vertex[18].x=m*r, Vertex[18].y=0.0, Vertex[18].z=-r;
	Vertex[19].x=0.0, Vertex[19].y=r, Vertex[19].z=-m*r;
	Vertex[20].x=0.0, Vertex[20].y=m*r, Vertex[20].z=-r;
	Vertex[21].x=0.0, Vertex[21].y=0.0, Vertex[21].z=-r;

	//第三卦限控制点
	Vertex[22].x=-m*m*r, Vertex[22].y=r, Vertex[22].z=-m*r;
	Vertex[23].x=-m*r, Vertex[23].y=m*r, Vertex[23].z=-r;
	Vertex[24].x=-m*r, Vertex[24].y=0.0, Vertex[24].z=-r;
	Vertex[25].x=-m*r, Vertex[25].y=r, Vertex[25].z=-m*m*r;
	Vertex[26].x=-r, Vertex[26].y=m*r, Vertex[26].z=-m*r;
	Vertex[27].x=-r, Vertex[27].y=0.0, Vertex[27].z=-m*r;
	Vertex[28].x=-m*r, Vertex[28].y=r, Vertex[28].z=0.0;
	Vertex[29].x=-r, Vertex[29].y=m*r, Vertex[29].z=0.0;
	Vertex[30].x=-r, Vertex[30].y=0.0, Vertex[30].z=0.0;

	//第四卦限控制点
	Vertex[31].x=-m*r, Vertex[31].y=r, Vertex[31].z=m*m*r;
	Vertex[32].x=-r, Vertex[32].y=m*r, Vertex[32].z=m*r;
	Vertex[33].x=-r, Vertex[33].y=0.0, Vertex[33].z=m*r;
	Vertex[34].x=-m*m*r, Vertex[34].y=r, Vertex[34].z=m*r;
	Vertex[35].x=-m*r, Vertex[35].y=m*r, Vertex[35].z=r;
	Vertex[36].x=-m*r, Vertex[36].y=0.0, Vertex[36].z=r;

	//第五卦限控制点
	Vertex[37].x=0.0, Vertex[37].y=-m*r, Vertex[37].z=r;
	Vertex[38].x=0.0, Vertex[38].y=-r, Vertex[38].z=m*r;
	Vertex[39].x=m*r, Vertex[39].y=-m*r, Vertex[39].z=r;
	Vertex[40].x=m*m*r, Vertex[40].y=-r, Vertex[40].z=m*r;
	Vertex[41].x=r, Vertex[41].y=-m*r, Vertex[41].z=m*r;
	Vertex[42].x=m*r, Vertex[42].y=-r, Vertex[42].z=m*m*r;
	Vertex[43].x=r, Vertex[43].y=-m*r, Vertex[43].z=0.0;
	Vertex[44].x=m*r, Vertex[44].y=-r, Vertex[44].z=0.0;

	//第六卦限控制点
	Vertex[45].x=r, Vertex[45].y=-m*r, Vertex[45].z=-m*r;
	Vertex[46].x=m*r, Vertex[46].y=-r, Vertex[46].z=-m*m*r;
	Vertex[47].x=m*r, Vertex[47].y=-m*r, Vertex[47].z=-r;
	Vertex[48].x=m*m*r, Vertex[48].y=-r, Vertex[48].z=-m*r;
	Vertex[49].x=0.0, Vertex[49].y=-m*r, Vertex[49].z=-r;
	Vertex[50].x=0.0, Vertex[50].y=-r, Vertex[50].z=-m*r;

	//第七卦限控制点
	Vertex[51].x=-m*r, Vertex[51].y=-m*r, Vertex[51].z=-r;
	Vertex[52].x=-m*m*r, Vertex[52].y=-r, Vertex[52].z=-m*r;
	Vertex[53].x=-r, Vertex[53].y=-m*r, Vertex[53].z=-m*r;
	Vertex[54].x=-m*r, Vertex[54].y=-r, Vertex[54].z=-m*m*r;
	Vertex[55].x=-r, Vertex[55].y=-m*r, Vertex[55].z=0.0;
	Vertex[56].x=-m*r, Vertex[56].y=-r, Vertex[56].z=0.0;

	//第八卦限控制点
	Vertex[57].x=-r, Vertex[57].y=-m*r, Vertex[57].z=m*r;
	Vertex[58].x=-m*r, Vertex[58].y=-r, Vertex[58].z=m*m*r;
	Vertex[59].x=-m*r, Vertex[59].y=-m*r, Vertex[59].z=r;
	Vertex[60].x=-m*m*r, Vertex[60].y=-r, Vertex[60].z=m*r;
	Vertex[61].x=0.0, Vertex[61].y=-r, Vertex[61].z=0.0;
}


void CDrawSewBezierView::ReadPatch(void)
{
	//第一卦限的曲面片
	S[0].pNumber=16;//曲面片上的控制点数控制点数
	S[0].pIndex[0][0]=0, S[0].pIndex[0][1]=1, S[0].pIndex[0][2]=2, S[0].pIndex[0][3]=3;
	S[0].pIndex[1][0]=0, S[0].pIndex[1][1]=4, S[0].pIndex[1][2]=5, S[0].pIndex[1][3]=6;
	S[0].pIndex[2][0]=0, S[0].pIndex[2][1]=7, S[0].pIndex[2][2]=8, S[0].pIndex[2][3]=9;
	S[0].pIndex[3][0]=0, S[0].pIndex[3][1]=10, S[0].pIndex[3][2]=11, S[0].pIndex[3][3]=12;

	//第二卦限的曲面片
	S[1].pNumber=16;//曲面片上的控制点数控制点数
	S[1].pIndex[0][0]=0, S[1].pIndex[0][1]=10, S[1].pIndex[0][2]=11, S[1].pIndex[0][3]=12;
	S[1].pIndex[1][0]=0, S[1].pIndex[1][1]=13, S[1].pIndex[1][2]=14, S[1].pIndex[1][3]=15;
	S[1].pIndex[2][0]=0, S[1].pIndex[2][1]=16, S[1].pIndex[2][2]=17, S[1].pIndex[2][3]=18;
	S[1].pIndex[3][0]=0, S[1].pIndex[3][1]=19, S[1].pIndex[3][2]=20, S[1].pIndex[3][3]=21;

	//第三卦限的曲面片
	S[2].pNumber=16;//曲面片上的控制点数控制点数
	S[2].pIndex[0][0]=0, S[2].pIndex[0][1]=19, S[2].pIndex[0][2]=20, S[2].pIndex[0][3]=21;
	S[2].pIndex[1][0]=0, S[2].pIndex[1][1]=22, S[2].pIndex[1][2]=23, S[2].pIndex[1][3]=24;
	S[2].pIndex[2][0]=0, S[2].pIndex[2][1]=25, S[2].pIndex[2][2]=26, S[2].pIndex[2][3]=27;
	S[2].pIndex[3][0]=0, S[2].pIndex[3][1]=28, S[2].pIndex[3][2]=29, S[2].pIndex[3][3]=30;

	//第四卦限的曲面片
	S[3].pNumber=16;//曲面片上的控制点数控制点数
	S[3].pIndex[0][0]=0, S[3].pIndex[0][1]=28, S[3].pIndex[0][2]=29, S[3].pIndex[0][3]=30;
	S[3].pIndex[1][0]=0, S[3].pIndex[1][1]=31, S[3].pIndex[1][2]=32, S[3].pIndex[1][3]=33;
	S[3].pIndex[2][0]=0, S[3].pIndex[2][1]=34, S[3].pIndex[2][2]=35, S[3].pIndex[2][3]=36;
	S[3].pIndex[3][0]=0, S[3].pIndex[3][1]=1, S[3].pIndex[3][2]=2, S[3].pIndex[3][3]=3;

	//第五卦限的曲面片
	S[4].pNumber=16;//曲面片上的控制点数控制点数
	S[4].pIndex[0][0]=3, S[4].pIndex[0][1]=37, S[4].pIndex[0][2]=38, S[4].pIndex[0][3]=61;
	S[4].pIndex[1][0]=6, S[4].pIndex[1][1]=39, S[4].pIndex[1][2]=40, S[4].pIndex[1][3]=61;
	S[4].pIndex[2][0]=9, S[4].pIndex[2][1]=41, S[4].pIndex[2][2]=42, S[4].pIndex[2][3]=61;
	S[4].pIndex[3][0]=12, S[4].pIndex[3][1]=43, S[4].pIndex[3][2]=44, S[4].pIndex[3][3]=61;

	//第六卦限的曲面片
	S[5].pNumber=16;//曲面片上的控制点数控制点数
	S[5].pIndex[0][0]=12, S[5].pIndex[0][1]=43, S[5].pIndex[0][2]=44, S[5].pIndex[0][3]=61;
	S[5].pIndex[1][0]=15, S[5].pIndex[1][1]=45, S[5].pIndex[1][2]=46, S[5].pIndex[1][3]=61;
	S[5].pIndex[2][0]=18, S[5].pIndex[2][1]=47, S[5].pIndex[2][2]=48, S[5].pIndex[2][3]=61;
	S[5].pIndex[3][0]=21, S[5].pIndex[3][1]=49, S[5].pIndex[3][2]=50, S[5].pIndex[3][3]=61;

	//第七卦限的曲面片
	S[6].pNumber=16;//曲面片上的控制点数控制点数
	S[6].pIndex[0][0]=21, S[6].pIndex[0][1]=49, S[6].pIndex[0][2]=50, S[6].pIndex[0][3]=61;
	S[6].pIndex[1][0]=24, S[6].pIndex[1][1]=51, S[6].pIndex[1][2]=52, S[6].pIndex[1][3]=61;
	S[6].pIndex[2][0]=27, S[6].pIndex[2][1]=53, S[6].pIndex[2][2]=54, S[6].pIndex[2][3]=61;
	S[6].pIndex[3][0]=30, S[6].pIndex[3][1]=55, S[6].pIndex[3][2]=56, S[6].pIndex[3][3]=61;

	//第八卦限的曲面片
	S[7].pNumber=16;//曲面片上的控制点数控制点数
	S[7].pIndex[0][0]=30, S[7].pIndex[0][1]=55, S[7].pIndex[0][2]=56, S[7].pIndex[0][3]=61;
	S[7].pIndex[1][0]=33, S[7].pIndex[1][1]=57, S[7].pIndex[1][2]=58, S[7].pIndex[1][3]=61;
	S[7].pIndex[2][0]=36, S[7].pIndex[2][1]=59, S[7].pIndex[2][2]=60, S[7].pIndex[2][3]=61;
	S[7].pIndex[3][0]=3, S[7].pIndex[3][1]=37, S[7].pIndex[3][2]=38, S[7].pIndex[3][3]=61;
}


void CDrawSewBezierView::DrawBezierSphere(CDC*pDC)
{
	for(int nPatch=0;nPatch<8;nPatch++)
	{
		for(int i=0;i<4;i++)
		{
			for(int j=0;j<4;j++)
			{
				P3[i][j]=Vertex[S[nPatch].pIndex[i][j]];
			}
		}
		patch.ReadControlPoint(P3);
		patch.DrawControlGrid(pDC);
		patch.DrawCurvedPatch(pDC);
	}
}

4、最后在OnDraw函数中添加代码,完成调用


	ReadVertex();
	ReadPatch();
	DrawBezierSphere(pDC);
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值