空间圆弧作图算法,基于OpenGL实现!

/
int CGLBasic::DrawCircle(XPoint ps, XPoint pe, XPoint pc, ColorRGB clr)
{
	const float inc_a=0.001f;			// 精度系数

	ps.x *= (m_ZoomRate*ONE_OF_HUNDRED);
	ps.y *= (m_ZoomRate*ONE_OF_HUNDRED);
	ps.z *= (m_ZoomRate*ONE_OF_HUNDRED);

	pe.x *= (m_ZoomRate*ONE_OF_HUNDRED);
	pe.y *= (m_ZoomRate*ONE_OF_HUNDRED);
	pe.z *= (m_ZoomRate*ONE_OF_HUNDRED);

	pc.x *= (m_ZoomRate*ONE_OF_HUNDRED);
	pc.y *= (m_ZoomRate*ONE_OF_HUNDRED);
	pc.z *= (m_ZoomRate*ONE_OF_HUNDRED);

	float as_xy,as_zy,ae_xy,ae_zy,as_xz,ae_xz;	// 保存角度
	size_t count;						// 
	float xy_inc;						// xy平面上角度增长步长	
	float zy_inc;						// zy平面上角度增长步长
	float xz_inc;						// xz平面上的角度增长步长
	float R;							// 圆弧半径
	
	float x,y,z;

	// 计算圆弧半径
	R=sqrt((ps.x-pc.x)*(ps.x-pc.x)
		+(ps.y-pc.y)*(ps.y-pc.y)
		+(ps.z-pc.z)*(ps.z-pc.z));

	// xy平面上起点、终点的角度
	as_xy = CalAngle(ps.x, ps.y, pc.x, pc.y);
	ae_xy = CalAngle(pe.x, pe.y, pc.x, pc.y);
	if ( ae_xy <= as_xy )
	{
		ae_xy += 2*PI;
	}

	// 计算zy平面上起点、终点的角度,此时z轴相当于xy平面上的x轴
	as_zy = CalAngle(ps.z, ps.y ,pc.z, pc.y);
	ae_zy = CalAngle(pe.z, pe.y, pc.z, pc.y);
	if ( ae_zy <= as_zy )
	{
		ae_zy += 2*PI;
	}

	// 计算xz平面上起点、终点的角度
	as_xz = CalAngle(ps.x, ps.z, pc.x, pc.z);
	ae_xz = CalAngle(pe.x, pe.z, pc.x, pc.z);
	if ( ae_xz < as_xz )
	{
		ae_xz += 2*PI;
	}
	
	// xy平面为主平面的情况
	if ( (pe.x-ps.x) && (pe.y-ps.y) )
	{
		// 分别计算两平面上角度增长的步长
		if ( (ae_xy-as_xy) > (ae_zy-as_zy) )
		{
			xy_inc = inc_a;
			count  = (size_t)(ae_xy-as_xy)/xy_inc;
			zy_inc = (ae_zy-as_zy)/count;
		}
		else
		{
			zy_inc = inc_a;
			count  = (size_t)(ae_zy-as_zy)/zy_inc;
			xy_inc = (ae_xy-as_xy)/count;
		}

		// 微分思想计算画圆弧所需的点坐标
		glBegin(GL_LINE_STRIP);
		glColor3f(clr.r, clr.g, clr.b);
		int i=0;
		for ( float a_xy=as_xy, a_zy=as_zy; 
				a_xy<=ae_xy && a_zy<=ae_zy; 
				a_xy+=xy_inc,a_zy+=zy_inc,i++ )
		{
			x = pc.x + R*cos(a_xy);
			y = pc.y + R*sin(a_xy);
			z = pc.z + R*cos(a_zy);
			glVertex3f(x,y,z);
		}
		glEnd();
		glFlush();
	}
	// xz为主平面的情况
	else if ( (pe.x-ps.x) && (pe.z-ps.z) )
	{
		if ( (ae_xz-as_xz) > (ae_zy-as_zy) )
		{
			xz_inc = inc_a;
			count  = (size_t)(ae_xz-as_xz)/xz_inc;
			zy_inc = (ae_zy-as_zy)/count;
		}
		else
		{
			zy_inc = inc_a;
			count  = (size_t)(ae_zy-as_zy)/zy_inc;
			xz_inc = (ae_xz-as_xz)/count;
		}
		
		glBegin(GL_LINE_STRIP);
		glColor3f(clr.r, clr.g, clr.b);
		int i=0;
		for ( float a_xz=as_xz,a_zy=as_zy; 
				a_xz<=ae_xz && a_zy<=ae_zy; 
				a_xz+=xz_inc,a_zy+=zy_inc,i++ )
		{
			x = pc.x + R*cos(a_xz);
			y = pc.y + R*sin(a_zy);
			z = pc.z + R*sin(a_xz);
			glVertex3f(x,y,z);
		}
		glEnd();
		glFlush();
	}
	// zy为主平面的情况
	else if ( (pe.y-ps.y) && (pe.z-ps.z) )
	{
		if ( (ae_zy-as_zy) > (ae_xy-as_xy) )
		{
			zy_inc = inc_a;
			count  = (size_t)(ae_zy-as_zy)/zy_inc;
			xy_inc = (ae_xy-as_xy)/count;
		}
		else
		{
			xy_inc = inc_a;
			count  = (size_t)(ae_xy-as_xy)/xy_inc;
			zy_inc = (ae_zy-as_zy)/count;
		}

		glBegin(GL_LINE_STRIP);
		glColor3f(clr.r,clr.g,clr.b);
		int i=0;
		for ( float a_xy=as_xy,a_zy=as_zy; 
				a_xy<=ae_xy && a_zy<=ae_zy; 
				a_xy+=xy_inc,a_zy+=zy_inc,i++ )
		{
			x = pc.x + R*cos(a_xy);
			y = pc.y + R*sin(a_zy);
			z = pc.z + R*cos(a_zy);
			glVertex3f(x,y,z);
		}
		glEnd();
		glFlush();
	}
	else
	{
		return 0;		// 不能在任何平面构成圆弧则返回
	}
	
	return 0;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值