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

📄 cmath.cpp.svn-base

📁 自己做的小游戏
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
// CMath.cpp: implementation of the CMath class.
//
//////////////////////////////////////////////////////////////////////

//#include "stdafx.h"
#include "CMath.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMath::CMath()
{}
CMath::~CMath()
{}
/////////////////////////////
bool CMath::IsLineSegmentCutByPolygon(VERTEX v1 ,VERTEX v2,VERTEX* pv,int num)
{
	if(num<3)return false;
	PLANE plane;
	plane=GetPlaneEquation(pv,num);
	///////////如果两点在同一侧
	if((ClassifyPointPlane(v1,plane)*ClassifyPointPlane(v2,plane))> 0)
		return false;
	//////////////获得线段与平面的交点
	VERTEX intersection;
	intersection=GetIntersection(v1,v2,plane);
	///////////包围盒粗略判断
	float maxx,minx,  maxy,miny,  maxz,minz;
	maxx=minx=pv[0].xpos;
	maxy=miny=pv[0].ypos;
	maxz=minz=pv[0].zpos;
	for(int i=1;i<num;i++)
	{
		if(pv[i].xpos>maxx)maxx=pv[i].xpos;
		if(pv[i].xpos<minx)minx=pv[i].xpos;
		if(pv[i].ypos>maxy)maxy=pv[i].ypos;
		if(pv[i].ypos<miny)miny=pv[i].ypos;
		if(pv[i].zpos>maxz)maxz=pv[i].zpos;
		if(pv[i].zpos<minz)minz=pv[i].zpos;
	}
	if(intersection.xpos>maxx || intersection.xpos<minx)
		return false;
	if(intersection.ypos>maxy || intersection.ypos<miny)
		return false;
	if(intersection.zpos>maxz || intersection.zpos<minz)
		return false;
	//////////////找一个过交点intersection且与某一坐标轴垂直的平面
    PLANE  p(0,0,0,0);
    float absA,absB,absC;
	if(plane.A<0)absA=-plane.A;
	else absA=plane.A;
	if(plane.B<0)absB=-plane.B;
	else absB=plane.B;
	if(plane.C<0)absC=-plane.C;
	else absC=plane.C;

	if(absA<=absB && absA<=absC)
	{
		///////////平面与X轴接近平行(当与某一分量小到0时,就完全平行)
		p.A=1;
		p.D=-intersection.xpos;

		///////////////////////////////////////////
		if(absB>absC)
		{   //////比较 Z 轴坐标
            VERTEX sect[6];/////可能有重复的交点,如顶点
            int  index=0;
			for( i=0;i<(num-1);i++)
			{
				if(ClassifyPointPlane(pv[i],p)!=ClassifyPointPlane(pv[i+1],p))
				{
                     sect[index]=GetIntersection(pv[i],pv[i+1],p);
					 index++;
				}
			}
			if(ClassifyPointPlane(pv[0],p)!=ClassifyPointPlane(pv[num-1],p))
			{
                 sect[index]=GetIntersection(pv[0],pv[num-1],p);
				 index++;
			}
			/////////////////////////////
			float maxzz,minzz;
			maxzz=minzz=sect[0].zpos;
			for(i=0;i<index;i++)
			{
				if(sect[i].zpos>maxzz)maxzz=sect[i].zpos;
				if(sect[i].zpos<minzz)minzz=sect[i].zpos;
			}
			if(intersection.zpos>maxzz || intersection.zpos<minzz)return false;
			else 
				return true;
		}
		else
		{   //////比较 Y 轴坐标
            VERTEX sect[6];/////可能有重复的交点,如顶点
            int  index=0;
			for( i=0;i<(num-1);i++)
			{
				if(ClassifyPointPlane(pv[i],p)!=ClassifyPointPlane(pv[i+1],p))
				{
                     sect[index]=GetIntersection(pv[i],pv[i+1],p);
					 index++;
				}
			}
			if(ClassifyPointPlane(pv[0],p)!=ClassifyPointPlane(pv[num-1],p))
			{
                 sect[index]=GetIntersection(pv[0],pv[num-1],p);
				 index++;
			}
			/////////////////////////////
			float maxyy,minyy;
			maxyy=minyy=sect[0].ypos;
			for(i=0;i<index;i++)
			{
				if(sect[i].ypos>maxyy)maxyy=sect[i].ypos;
				if(sect[i].ypos<minyy)minyy=sect[i].ypos;
			}
			if(intersection.ypos>maxyy || intersection.ypos<minyy)return false;
			else 
				return true;
		}

	}
	else if(absB<=absA && absB<=absC)
	{
		///////////平面与Y轴接近平行
		p.B=1;
		p.D=-intersection.ypos;

		///////////////////////////////////////////
		if(absA>absC)
		{   //////比较 Z 轴坐标
            VERTEX sect[6];/////可能有重复的交点,如顶点
            int  index=0;
			for( i=0;i<(num-1);i++)
			{
				if(ClassifyPointPlane(pv[i],p)!=ClassifyPointPlane(pv[i+1],p))
				{
                     sect[index]=GetIntersection(pv[i],pv[i+1],p);
					 index++;
				}
			}
			if(ClassifyPointPlane(pv[0],p)!=ClassifyPointPlane(pv[num-1],p))
			{
                 sect[index]=GetIntersection(pv[0],pv[num-1],p);
				 index++;
			}
			/////////////////////////////
			float maxzz,minzz;
			maxzz=minzz=sect[0].zpos;
			for(i=0;i<index;i++)
			{
				if(sect[i].zpos>maxzz)maxzz=sect[i].zpos;
				if(sect[i].zpos<minzz)minzz=sect[i].zpos;
			}
			if(intersection.zpos>maxzz || intersection.zpos<minzz)return false;
			else 
				return true;
		}
		else
		{   //////比较 X 轴坐标
            VERTEX sect[6];/////可能有重复的交点,如顶点
            int  index=0;
			for( i=0;i<(num-1);i++)
			{
				if(ClassifyPointPlane(pv[i],p)!=ClassifyPointPlane(pv[i+1],p))
				{
                     sect[index]=GetIntersection(pv[i],pv[i+1],p);
					 index++;
				}
			}
			if(ClassifyPointPlane(pv[0],p)!=ClassifyPointPlane(pv[num-1],p))
			{
                 sect[index]=GetIntersection(pv[0],pv[num-1],p);
				 index++;
			}
			/////////////////////////////
			float maxxx,minxx;
			maxxx=minxx=sect[0].xpos;
			for(i=0;i<index;i++)
			{
				if(sect[i].xpos>maxxx)maxxx=sect[i].xpos;
				if(sect[i].xpos<minxx)minxx=sect[i].xpos;
			}
			if(intersection.xpos>maxxx || intersection.xpos<minxx)return false;
			else 
				return true;
		}
	}
	else  //(absC<absA && absC<absB)
	{
		///////////平面与Z轴接近平行
		p.C=1;
		p.D=-intersection.zpos;

		///////////////////////////////////////////
		if(absA>absB)
		{   //////比较 Y 轴坐标
            VERTEX sect[6];/////可能有重复的交点,如顶点
            int  index=0;
			for( i=0;i<(num-1);i++)
			{
				if(ClassifyPointPlane(pv[i],p)!=ClassifyPointPlane(pv[i+1],p))
				{
                     sect[index]=GetIntersection(pv[i],pv[i+1],p);
					 index++;
				}
			}
			if(ClassifyPointPlane(pv[0],p)!=ClassifyPointPlane(pv[num-1],p))
			{
                 sect[index]=GetIntersection(pv[0],pv[num-1],p);
				 index++;
			}
			/////////////////////////////
			float maxyy,minyy;
			maxyy=minyy=sect[0].ypos;
			for(i=0;i<index;i++)
			{
				if(sect[i].ypos>maxyy)maxyy=sect[i].ypos;
				if(sect[i].ypos<minyy)minyy=sect[i].ypos;
			}
			if(intersection.ypos>maxyy || intersection.ypos<minyy)return false;
			else 
				return true;
		}
		else
		{   //////比较 X 轴坐标
            VERTEX sect[6];/////可能有重复的交点,如顶点
            int  index=0;
			for( i=0;i<(num-1);i++)
			{
				if(ClassifyPointPlane(pv[i],p)!=ClassifyPointPlane(pv[i+1],p))
				{
                     sect[index]=GetIntersection(pv[i],pv[i+1],p);
					 index++;
				}
			}
			if(ClassifyPointPlane(pv[0],p)!=ClassifyPointPlane(pv[num-1],p))
			{
                 sect[index]=GetIntersection(pv[0],pv[num-1],p);
				 index++;
			}
			/////////////////////////////
			float maxxx,minxx;
			maxxx=minxx=sect[0].xpos;
			for(i=0;i<index;i++)
			{
				if(sect[i].xpos>maxxx)maxxx=sect[i].xpos;
				if(sect[i].xpos<minxx)minxx=sect[i].xpos;
			}
			if(intersection.xpos>maxxx || intersection.xpos<minxx)return false;
			else 
				return true;
		}

	}

	return true;
}
bool CMath::IsLineSegmentCutBy3DBoundary(VERTEX *v1 ,VERTEX *v2,BOUNDARY_3D *bd)
{
	if(v1->xpos>bd->maxx && v2->xpos>bd->maxx)return false;
	if(v1->xpos<bd->minx && v2->xpos<bd->minx)return false;
	if(v1->ypos>bd->maxy && v2->ypos>bd->maxy)return false;
	if(v1->ypos<bd->miny && v2->ypos<bd->miny)return false;
	if(v1->zpos>bd->maxz && v2->zpos>bd->maxz)return false;
	if(v1->zpos<bd->minz && v2->zpos<bd->minz)return false;
	/////////////
    VERTEX v[8];

	v[0]=VERTEX(bd->minx,bd->miny,bd->minz);
	v[1]=VERTEX(bd->maxx,bd->miny,bd->minz);
	v[2]=VERTEX(bd->maxx,bd->maxy,bd->minz);
	v[3]=VERTEX(bd->minx,bd->maxy,bd->minz);

	v[4]=VERTEX(bd->minx,bd->miny,bd->maxz);
	v[5]=VERTEX(bd->maxx,bd->miny,bd->maxz);
	v[6]=VERTEX(bd->maxx,bd->maxy,bd->maxz);
	v[7]=VERTEX(bd->minx,bd->maxy,bd->maxz);
    ///////////////
    if(IsLineSegmentCutByStardQuad(*v1,*v2, v[0],v[1],v[2],v[3]))return true;
    if(IsLineSegmentCutByStardQuad(*v1,*v2, v[4],v[5],v[6],v[7]))return true;
    if(IsLineSegmentCutByStardQuad(*v1,*v2, v[2],v[3],v[7],v[6]))return true;
    if(IsLineSegmentCutByStardQuad(*v1,*v2, v[1],v[0],v[4],v[5]))return true;
    if(IsLineSegmentCutByStardQuad(*v1,*v2, v[1],v[2],v[6],v[5]))return true;
    if(IsLineSegmentCutByStardQuad(*v1,*v2, v[0],v[3],v[7],v[4]))return true;
    ///////////////
    return false;
}
bool CMath::IsLineSegmentCutBy3DBoundary(VERTEX v1 ,VERTEX v2,BOUNDARY_3D bd)
{
	if(v1.xpos>bd.maxx && v2.xpos>bd.maxx)return false;
	if(v1.xpos<bd.minx && v2.xpos<bd.minx)return false;
	if(v1.ypos>bd.maxy && v2.ypos>bd.maxy)return false;
	if(v1.ypos<bd.miny && v2.ypos<bd.miny)return false;
	if(v1.zpos>bd.maxz && v2.zpos>bd.maxz)return false;
	if(v1.zpos<bd.minz && v2.zpos<bd.minz)return false;
	/////////////
    VERTEX v[8];

	v[0]=VERTEX(bd.minx,bd.miny,bd.minz);
	v[1]=VERTEX(bd.maxx,bd.miny,bd.minz);
	v[2]=VERTEX(bd.maxx,bd.maxy,bd.minz);
	v[3]=VERTEX(bd.minx,bd.maxy,bd.minz);

	v[4]=VERTEX(bd.minx,bd.miny,bd.maxz);
	v[5]=VERTEX(bd.maxx,bd.miny,bd.maxz);
	v[6]=VERTEX(bd.maxx,bd.maxy,bd.maxz);
	v[7]=VERTEX(bd.minx,bd.maxy,bd.maxz);
    ///////////////
    if(IsLineSegmentCutByStardQuad(v1,v2, v[0],v[1],v[2],v[3]))return true;
    if(IsLineSegmentCutByStardQuad(v1,v2, v[4],v[5],v[6],v[7]))return true;
    if(IsLineSegmentCutByStardQuad(v1,v2, v[2],v[3],v[7],v[6]))return true;
    if(IsLineSegmentCutByStardQuad(v1,v2, v[1],v[0],v[4],v[5]))return true;
    if(IsLineSegmentCutByStardQuad(v1,v2, v[1],v[2],v[6],v[5]))return true;
    if(IsLineSegmentCutByStardQuad(v1,v2, v[0],v[3],v[7],v[4]))return true;
    ///////////////
    return false;
}

bool CMath::IsLineSegmentCutByStardQuad(VERTEX v1 ,VERTEX v2,VERTEX va,VERTEX vb,VERTEX vc,VERTEX vd)
{
	PLANE plane;
	plane=GetPlaneEquation(va,vb,vc);
	///////////如果两点在同一侧
	if((ClassifyPointPlane(v1,plane)*ClassifyPointPlane(v2,plane))>=0)
		return false;
	//////////////获得线段与平面的交点
	VERTEX intersection;
	intersection=GetIntersection(v1,v2,plane);
	///////////包围盒判断,仅对aabb包围盒有效
	float maxx,minx,  maxy,miny,  maxz,minz;
	maxx=minx=va.xpos;
	maxy=miny=va.ypos;
	maxz=minz=va.zpos;

		if(vb.xpos>maxx)maxx=vb.xpos;
		if(vb.xpos<minx)minx=vb.xpos;
		if(vb.ypos>maxy)maxy=vb.ypos;
		if(vb.ypos<miny)miny=vb.ypos;
		if(vb.zpos>maxz)maxz=vb.zpos;
		if(vb.zpos<minz)minz=vb.zpos;

		if(vc.xpos>maxx)maxx=vc.xpos;
		if(vc.xpos<minx)minx=vc.xpos;
		if(vc.ypos>maxy)maxy=vc.ypos;
		if(vc.ypos<miny)miny=vc.ypos;
		if(vc.zpos>maxz)maxz=vc.zpos;
		if(vc.zpos<minz)minz=vc.zpos;

		if(vd.xpos>maxx)maxx=vd.xpos;
		if(vd.xpos<minx)minx=vd.xpos;
		if(vd.ypos>maxy)maxy=vd.ypos;
		if(vd.ypos<miny)miny=vd.ypos;
		if(vd.zpos>maxz)maxz=vd.zpos;
		if(vd.zpos<minz)minz=vd.zpos;

	if(intersection.xpos>maxx || intersection.xpos<minx)  
		return false;
	if(intersection.ypos>maxy || intersection.ypos<miny)
		return false;
	if(intersection.zpos>maxz || intersection.zpos<minz)
		return false;

    return true;
}
bool CMath::IsLineSegmentCutByStardQuad(VERTEX v1 ,VERTEX v2,VERTEX *pv)
{
	return IsLineSegmentCutByStardQuad(v1,v2,pv[0],pv[1],pv[2],pv[3]);
}
bool CMath::IsVertexInsideCube(VERTEX vertex , CUBE cube )
{
    if(vertex.xpos < cube.V0.xpos)return false;
    if(vertex.xpos > cube.V1.xpos)return false;
    if(vertex.ypos < cube.V0.ypos)return false;
    if(vertex.ypos > cube.V4.ypos)return false;
    if(vertex.zpos < cube.V3.zpos)return false;
    if(vertex.zpos > cube.V0.zpos)return false;
	return true;
}
bool CMath::IsVertexInsideCube(VERTEX *vertex , BOUNDARY_3D *boundary)
{
    if(vertex->xpos > boundary->maxx || vertex->xpos < boundary->minx)return false;
    if(vertex->ypos > boundary->maxy || vertex->ypos < boundary->miny)return false;
    if(vertex->zpos > boundary->maxz || vertex->zpos < boundary->minz)return false;

	return true;

}
bool CMath::IsCubeCutByQuad(CUBE cube , QUAD quad)  
{
	////////////// 1.如果Quad上有一个点在cube内,则相交
    if(IsVertexInsideCube(quad.V0,cube))return true;
    if(IsVertexInsideCube(quad.V1,cube))return true;
    if(IsVertexInsideCube(quad.V2,cube))return true;
    if(IsVertexInsideCube(quad.V3,cube))return true;
	////////////// 2. 如果quad的四个点都在cube的某一点的外侧,则不相交
	if(quad.V0.xpos < cube.V0.xpos && 
       quad.V1.xpos < cube.V0.xpos && 
	   quad.V2.xpos < cube.V0.xpos && 
	   quad.V3.xpos < cube.V0.xpos    )return false;
	if(quad.V0.xpos > cube.V1.xpos && 
       quad.V1.xpos > cube.V1.xpos && 
	   quad.V2.xpos > cube.V1.xpos && 
	   quad.V3.xpos > cube.V1.xpos    )return false;
	if(quad.V0.ypos < cube.V0.ypos && 
       quad.V1.ypos < cube.V0.ypos && 
	   quad.V2.ypos < cube.V0.ypos && 
	   quad.V3.ypos < cube.V0.ypos    )return false;
	if(quad.V0.ypos > cube.V4.ypos && 
       quad.V1.ypos > cube.V4.ypos && 
	   quad.V2.ypos > cube.V4.ypos && 
	   quad.V3.ypos > cube.V4.ypos    )return false;
	if(quad.V0.zpos < cube.V2.zpos && 
       quad.V1.zpos < cube.V2.zpos && 
	   quad.V2.zpos < cube.V2.zpos && 
	   quad.V3.zpos < cube.V2.zpos    )return false;
	if(quad.V0.zpos > cube.V1.zpos && 
       quad.V1.zpos > cube.V1.zpos && 
	   quad.V2.zpos > cube.V1.zpos && 
	   quad.V3.zpos > cube.V1.zpos    )return false;
	/////////////// 3.现在判断cube上的8个点是否在Quad的同一侧
	int side[8];
	side[0] = ClassifyPointPlane(cube.V0,quad.plane);
	side[1] = ClassifyPointPlane(cube.V1,quad.plane);
	side[2] = ClassifyPointPlane(cube.V2,quad.plane);
	side[3] = ClassifyPointPlane(cube.V3,quad.plane);
	side[4] = ClassifyPointPlane(cube.V4,quad.plane);
	side[5] = ClassifyPointPlane(cube.V5,quad.plane);
	side[6] = ClassifyPointPlane(cube.V6,quad.plane);
	side[7] = ClassifyPointPlane(cube.V7,quad.plane);

	int count = 0;
	int index = 0;
	for(int i=0;i<8;i++)
	{
//		if(side[i] !=0 )
		{
			count+=side[i];
			index++;

⌨️ 快捷键说明

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