包围球的计算

//【Ritter90】逼近包围球的计算----------------------------------------------------------------------
//查找相隔最远的两个顶点
void MostSeparatedPointsOnAABB(int &imin, int &imax, Vector3 pt[], int numPts)
{
	int minx = 0, maxx = 0, miny = 0, maxy = 0, minz = 0, maxz = 0;
	for(unsigned int i = 1; i  pt[maxx].x) maxx = i;
		if(pt[i].y < pt[miny].y) miny = i;
		if(pt[i].y > pt[maxy].y) maxy = i;
		if(pt[i].z < pt[minz].z) minz = i;
		if(pt[i].z > pt[maxz].z) maxz = i;
	}

	float dist2x = (pt[maxx]-pt[minx]).dotProduct(pt[maxx]-pt[minx]);
	float dist2y = (pt[maxy]-pt[miny]).dotProduct(pt[maxy]-pt[miny]);
	float dist2z = (pt[maxz]-pt[minz]).dotProduct(pt[maxz]-pt[minz]);

	imin = minx;
	imax = maxx;

	if(dist2y > dist2x && dist2y > dist2z)
	{
		imin = miny;
		imax = maxy;
	}
	if(dist2z > dist2x && dist2z > dist2y)
	{
		imin = minz;
		imax = maxz;
	}
}
//计算包围球的半径和球心
void SphereFromDistantPoints(Sphere &s, Vector3 pt[], int numPts)
{
	int imin, imax;
	MostSeparatedPointsOnAABB(imin, imax, pt, numPts);
	s.center = ((pt[imin] + pt[imax]) * 0.5f);
	s.r = (pt[imax] - s.center).dotProduct(pt[imax] - s.center);
	s.r = Math::Sqrt(s.r);
}
//循环所有顶点更新包围球体
void SphereOfSphereAndPt(Sphere &s, Vector3 &p)
{
	Vector3 d = p-s.center;
	float dist2 = d.dotProduct(d);

	if(dist2 > s.r * s.r)
	{
		float dist = Math::Sqrt(dist2);
		float newRadius = (s.r + dist) * 0.5f;
		float k = (newRadius - s.r) / dist;
		s.r = newRadius;
		s.center += d * k;
	}
}
//综合上述过程计算包围球
void RitterSphere(Sphere &s, Vector3 pt[], int numPts)
{
	SphereFromDistantPoints(s, pt, numPts);
	for(unsigned int i = 0; i < numPts; ++i)
		SphereOfSphereAndPt(s, pt[i]);
}

你可能感兴趣的:(Ogre)