空間円弧作図アルゴリズム、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;
}