CMath.cpp
上传用户:hkb425
上传日期:2007-06-16
资源大小:34191k
文件大小:24k
- // 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轴接近平行
- 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);
- ///////////包围盒判断
- 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++;
- }
- }
- if(count==index || count==-index)return false;
- ////////////// 4.判断cube的12条边中有没有与Quad相交的
- // VERTEX vList[4];
- if(IsLineSegmentCutByPolygon(cube.V0,cube.V1,&quad.V0,4))return true;
- if(IsLineSegmentCutByPolygon(cube.V0,cube.V4,&quad.V0,4))return true;
- if(IsLineSegmentCutByPolygon(cube.V0,cube.V3,&quad.V0,4))return true;
-
- if(IsLineSegmentCutByPolygon(cube.V6,cube.V7,&quad.V0,4))return true;
- if(IsLineSegmentCutByPolygon(cube.V6,cube.V2,&quad.V0,4))return true;
- if(IsLineSegmentCutByPolygon(cube.V6,cube.V5,&quad.V0,4))return true;
-
- if(IsLineSegmentCutByPolygon(cube.V7,cube.V3,&quad.V0,4))return true;
- if(IsLineSegmentCutByPolygon(cube.V7,cube.V4,&quad.V0,4))return true;
- if(IsLineSegmentCutByPolygon(cube.V5,cube.V4,&quad.V0,4))return true;
- if(IsLineSegmentCutByPolygon(cube.V5,cube.V1,&quad.V0,4))return true;
- if(IsLineSegmentCutByPolygon(cube.V2,cube.V1,&quad.V0,4))return true;
- if(IsLineSegmentCutByPolygon(cube.V2,cube.V3,&quad.V0,4))return true;
-
- return false;
- }
- PLANE CMath::GetPlaneEquation(VERTEX v1,VERTEX v2,PLANE p)
- {
- PLANE plane;
- ///////////// n12不能与plane垂直
- ////???????????????????????????
- ///////////////////////////////
- double nnx,nny,nnz ;
- nnx=v2.xpos-v1.xpos;
- nny=v2.ypos-v1.ypos;
- nnz=v2.zpos-v1.zpos;
- double pA,pB,pC,pD;
- pA=p.A; pB=p.B; pC=p.C; pD=p.D;
- double a,b,c;
- a=(pC*nny-pB*nnz)*(pA*nny-pB*nnx);
- b=(pC*nnx-pA*nnz)*(pB*nnx-pA*nny);
- c=(pB*nnx-pA*nny)*(pA*nny-pB*nnx);
- NORMAL n=Normalization(a,b,c);
- plane.A=n.nx;
- plane.B=n.ny;
- plane.C=n.nz;
- plane.D=-(plane.A*v1.xpos+plane.B*v1.ypos+plane.C*v1.zpos);
- return plane;
- }
- PLANE CMath::GetPlaneEquation(VERTEX *pVertices,int VerticesNumber)
- {
- PLANE plane;
- if(VerticesNumber<3)
- {
- plane.A=plane.B=plane.C=plane.D=0;
- }
- else
- {
- NORMAL N12,N13,N;
- ////////////calculate n12 n13
- N12.nx=pVertices[1].xpos-pVertices[0].xpos;
- N12.ny=pVertices[1].ypos-pVertices[0].ypos;
- N12.nz=pVertices[1].zpos-pVertices[0].zpos;
- N13.nx=pVertices[2].xpos-pVertices[0].xpos;
- N13.ny=pVertices[2].ypos-pVertices[0].ypos;
- N13.nz=pVertices[2].zpos-pVertices[0].zpos;
- ////////////////////////////
- N=GetTwoNormalProduct(N12,N13);
- plane.A=N.nx;
- plane.B=N.ny;
- plane.C=N.nz;
- plane.D= -(plane.A*pVertices->xpos+plane.B*pVertices->ypos+plane.C*pVertices->zpos);
- }
- return plane;
- }
- PLANE CMath::GetPlaneEquation(VERTEX v1,VERTEX v2,VERTEX v3)
- {
- PLANE plane;
- NORMAL N12,N13,N;
- ////////////calculate n12 n13
- N12.nx=v2.xpos-v1.xpos;
- N12.ny=v2.ypos-v1.ypos;
- N12.nz=v2.zpos-v1.zpos;
- N13.nx=v3.xpos-v1.xpos;
- N13.ny=v3.ypos-v1.ypos;
- N13.nz=v3.zpos-v1.zpos;
- N=GetTwoNormalProduct(N12,N13);
- plane.A=N.nx;
- plane.B=N.ny;
- plane.C=N.nz;
- plane.D= -(plane.A*v1.xpos+plane.B*v1.ypos+plane.C*v1.zpos);
- return plane;
- }
- PLANE CMath::GetPlaneEquation(VERTEX v,PLANE p1,PLANE p2)
- {
- PLANE plane;
- NORMAL n1,n2,normal;
- n1.nx=p1.A; n1.ny=p1.B; n1.nz=p1.C;
- n2.nx=p2.A; n2.ny=p2.B; n2.nz=p2.C;
- normal=GetTwoNormalProduct(n1,n2);
- plane.A=normal.nx;
- plane.B=normal.ny;
- plane.C=normal.nz;
- plane.D=-(plane.A*v.xpos+plane.B*v.ypos+plane.C*v.zpos);
- return plane;
- }
- VERTEX CMath::GetIntersection(VERTEX v1,VERTEX v2,PLANE plane)
- {
- VERTEX point;
- double temp1=(plane.A*(v2.xpos-v1.xpos)+plane.B*(v2.ypos-v1.ypos)+plane.C*(v2.zpos-v1.zpos));
- double temp2=-plane.D-plane.A*v1.xpos-plane.B*v1.ypos-plane.C*v1.zpos;
- ///// Line param is temp2/temp1
- point.xpos=v1.xpos+float((double(v2.xpos-v1.xpos)*temp2)/temp1);
- point.ypos=v1.ypos+float((double(v2.ypos-v1.ypos)*temp2)/temp1);
- point.zpos=v1.zpos+float((double(v2.zpos-v1.zpos)*temp2)/temp1);
-
- return point;
- }
- VERTEX CMath::GetProjection(VERTEX vertex,PLANE plane)
- {
- VERTEX v=VERTEX(vertex.xpos-plane.A,vertex.ypos-plane.B,vertex.zpos-plane.C);
- return GetIntersection(v,vertex,plane);
- }
- TEXCOORD CMath::GetIntersectionTexCoord(VERTEX pointA,TEXCOORD texcoordA,
- VERTEX pointB,TEXCOORD texcoordB, PLANE plane)
- {
- VERTEX intersect=GetIntersection(pointA,pointB,plane);
- float distA=GetDistance(pointA,intersect);
- float distAB=GetDistance(pointA,pointB);
- if(distAB<0.0001)return texcoordA; ///////safe
- TEXCOORD texcoord;
- texcoord.u=(texcoordA.u*distAB + distA*(texcoordB.u-texcoordA.u))/distAB;
- texcoord.v=(texcoordA.v*distAB + distA*(texcoordB.v-texcoordA.v))/distAB;
- return texcoord;
- }
- VERTEX CMath::GetPositionOnGrid(VERTEX *pQuads,float u,float v)
- {
- /////////u,v 的范围为0-1
- if(u<0)u=0; if(u>1)u=1;
- if(v<0)v=0; if(v>1)v=1;
- //////////////////////////////////////
- VERTEX v1,v2; //与u相关的两条边上的点
- v1=VERTEX(pQuads[0].xpos+(pQuads[1].xpos-pQuads[0].xpos)*u,
- pQuads[0].ypos+(pQuads[1].ypos-pQuads[0].ypos)*u,
- pQuads[0].zpos+(pQuads[1].zpos-pQuads[0].zpos)*u);
- v2=VERTEX(pQuads[3].xpos+(pQuads[2].xpos-pQuads[3].xpos)*u,
- pQuads[3].ypos+(pQuads[2].ypos-pQuads[3].ypos)*u,
- pQuads[3].zpos+(pQuads[2].zpos-pQuads[3].zpos)*u);
- ///////////////////////////////////////
- VERTEX vertex; ///所求的点
- vertex.xpos=v1.xpos+(v2.xpos-v1.xpos)*v;
- vertex.ypos=v1.ypos+(v2.ypos-v1.ypos)*v;
- vertex.zpos=v1.zpos+(v2.zpos-v1.zpos)*v;
- return vertex;
- }
- NORMAL CMath::GetTwoNormalProduct(NORMAL n1,NORMAL n2)
- {
- double n1x,n1y,n1z,n2x,n2y,n2z;
- n1x=n1.nx; n1y=n1.ny; n1z=n1.nz;
- n2x=n2.nx; n2y=n2.ny; n2z=n2.nz;
- double nx,ny,nz;
- nx= n1y*n2z-n2y*n1z;
- ny=-(n1x*n2z-n2x*n1z);
- nz= n1x*n2y-n2x*n1y;
- // return NORMAL(float(nx),float(ny),float(nz));
- return Normalization(nx,ny,nz);
- }
- NORMAL CMath::GetNormal(VERTEX v1,VERTEX v2,VERTEX v3)
- {
- NORMAL n1,n2;
- n1.nx=v2.xpos-v1.xpos;
- n1.ny=v2.ypos-v1.ypos;
- n1.nz=v2.zpos-v1.zpos;
- n2.nx=v3.xpos-v1.xpos;
- n2.ny=v3.ypos-v1.ypos;
- n2.nz=v3.zpos-v1.zpos;
- return GetTwoNormalProduct(n1,n2);
- }
- NORMAL CMath::GetNormal(float *v1,float *v2,float *v3)
- {
- NORMAL n1,n2;
- n1.nx=v2[0]-v1[0];
- n1.ny=v2[1]-v1[1];
- n1.nz=v2[2]-v1[2];
- n2.nx=v3[0]-v1[0];
- n2.ny=v3[1]-v1[1];
- n2.nz=v3[2]-v1[2];
- return GetTwoNormalProduct(n1,n2);
- }
- float CMath::GetTwoVectorAngleCosine(NORMAL na,NORMAL nb)
- {
- NORMAL n1,n2;
- n1=Normalization(na);
- n2=Normalization(nb);
- double temp,length1,length2;
- temp=n1.nx*n2.nx+n1.ny*n2.ny+n1.nz*n2.nz;
- length1=pow( n1.nx*n1.nx +n1.ny*n1.ny +n1.nz*n1.nz,0.5);
- length2=pow( n2.nx*n2.nx +n2.ny*n2.ny +n2.nz*n2.nz,0.5);
- return float(temp/(length1*length2));
- }
- float CMath::GetDistance(VERTEX v1,VERTEX v2)
- {
- float dist;
- dist=(float)pow((v2.xpos-v1.xpos)*(v2.xpos-v1.xpos)+
- (v2.ypos-v1.ypos)*(v2.ypos-v1.ypos)+
- (v2.zpos-v1.zpos)*(v2.zpos-v1.zpos),0.5);
- return dist;
- }
- float CMath::GetPointToLineDist2D(VERTEX lineV1,VERTEX lineV2,VERTEX point)
- {
- PLANE plane=GetPlaneEquation(lineV1,lineV2,VERTEX(lineV1.xpos,lineV1.ypos-200,lineV1.zpos));
- float dist=GetDistance(point,plane);
- if(dist<0)dist=-dist;
- return dist;
- }
- float CMath::GetDistance(VERTEX point,PLANE plane)
- {
- float abc=(float)sqrt(plane.A*plane.A+plane.B*plane.B+plane.C*plane.C);
- float dist=(plane.A*point.xpos+plane.B*point.ypos+plane.C*point.zpos+plane.D)/abc;
- // if(dist<0)dist=-dist;
- return dist;
- }
- float CMath::GetDistance(VERTEX point,PLANE plane,float powABC)
- {
- return (plane.A*point.xpos+plane.B*point.ypos+plane.C*point.zpos+plane.D)/powABC;
- }
- float CMath::GetTwoVectorAngleCosine(VERTEX v1,VERTEX vCenter,VERTEX v2)
- {
- double temp,length1,length2;
- double n1nx,n1ny,n1nz,n2nx,n2ny,n2nz;
- n1nx=v1.xpos-vCenter.xpos;
- n1ny=v1.ypos-vCenter.ypos;
- n1nz=v1.zpos-vCenter.zpos;
- n2nx=v2.xpos-vCenter.xpos;
- n2ny=v2.ypos-vCenter.ypos;
- n2nz=v2.zpos-vCenter.zpos;
- temp=n1nx*n2nx+n1ny*n2ny+n1nz*n2nz;
- length1=pow( n1nx*n1nx +n1ny*n1ny +n1nz*n1nz,0.5);
- length2=pow( n2nx*n2nx +n2ny*n2ny +n2nz*n2nz,0.5);
- return float(temp/(length1*length2));
- }
- int CMath::ClassifyTwoNormal(NORMAL n1,NORMAL n2)
- {
- float temp;
- temp=n1.nx*n2.nx+n1.ny*n2.ny+n1.nz*n2.nz;
- if(temp==0)return PERPENDICULAR;
- if(temp>0)return SHARP_ANGLE;
- if(temp<0)return OBTUSE_ANGLE;
- return UNKNOW;
- }
- int CMath::ClassifyTwoNormal(VERTEX v1,VERTEX vCenter,VERTEX v2)
- {
- float temp;
- NORMAL n1,n2;
- n1.nx=v1.xpos-vCenter.xpos;
- n1.ny=v1.ypos-vCenter.ypos;
- n1.nz=v1.zpos-vCenter.zpos;
- n2.nx=v2.xpos-vCenter.xpos;
- n2.ny=v2.ypos-vCenter.ypos;
- n2.nz=v2.zpos-vCenter.zpos;
- temp=n1.nx*n2.nx+n1.ny*n2.ny+n1.nz*n2.nz;
- if(temp==0)return PERPENDICULAR;
- if(temp>0)return SHARP_ANGLE;
- if(temp<0)return OBTUSE_ANGLE;
- return UNKNOW;
- }
- int CMath::ClassifyPointPlane(VERTEX point,PLANE plane)
- {
- float distance=plane.A*point.xpos+plane.B*point.ypos+plane.C*point.zpos+plane.D;
- if(distance==0)return COINCIDENT;
- if(distance>0)return IN_FRONT_OF;
- return IN_BACK_OF;
- }
- int CMath::ClassifyPolygonPlane(PLANE plane,VERTEX *vertices,int num)
- {
- if(num<3)return UNKNOW;
- int current=0;
- int dist=ClassifyPointPlane(vertices[0],plane);
- if(dist==IN_FRONT_OF)
- {
- current=1;
- while(current<num && dist!=IN_BACK_OF)
- {
- dist=ClassifyPointPlane(vertices[current],plane);
- current++;
- }
- if(current<num)return SPANNING;
- else if(dist==IN_BACK_OF) return SPANNING;
- else return IN_FRONT_OF;
- }
- else if(dist==IN_BACK_OF)
- {
- current=1;
- while(current<num && dist!=IN_FRONT_OF)
- {
- dist=ClassifyPointPlane(vertices[current],plane);
- current++;
- }
- if(current<num)return SPANNING;
- else if(dist==IN_FRONT_OF) return SPANNING;
- else return IN_BACK_OF;
- }
- else //First point in the plane
- {
- int front,back;
- front=back=0;
- int temp;
- for(int i=1;i<num;i++)
- {
- temp=ClassifyPointPlane(vertices[i],plane);
- if(temp==IN_FRONT_OF)front++;
- if(temp==IN_BACK_OF)back--;
- }
- if(front==0 && back==0)return COINCIDENT;
- if((front+back)==back)return IN_BACK_OF;
- if((front+back)==front)return IN_FRONT_OF;
- return SPANNING;
- }
- }
- NORMAL CMath::Normalization(NORMAL n)
- {
- NORMAL normal;
- double x,y,z;
- x=n.nx; y=n.ny; z=n.nz;
- double max=sqrt(x*x+y*y+z*z);
- if(max<0.0001)return NORMAL(0,1,0);
- x=x/max;
- y=y/max;
- z=z/max;
- normal.nx=float(x);
- normal.ny=float(y);
- normal.nz=float(z);
- return normal;
- }
- NORMAL CMath::Normalization(double x,double y,double z)
- {
- NORMAL normal=NORMAL(float(x),float(y),float(z));
- return Normalization(normal);
- /*
- double absX,absY,absZ;
- if(x<0)absX=-x;
- else absX=x;
- if(y<0)absY=-y;
- else absY=y;
- if(z<0)absZ=-z;
- else absZ=z;
- double max=absX>absY?absX:absY;
- max=max>absZ?max:absZ ;
-
- x=x/max;
- y=y/max;
- z=z/max;
- normal.nx=float(x);
- normal.ny=float(y);
- normal.nz=float(z);
- return normal;*/
- }