📄 cmath.cpp.svn-base
字号:
}
}
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;
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);//a,b,c同时扩大(pA*nny-pB*nnx)倍,防止a,b,c太小而出错
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)); //线段v1v2在平面法向量上的投影长度
double temp2=-plane.D-plane.A*v1.xpos-plane.B*v1.ypos-plane.C*v1.zpos; //点v1到平面的距离
///// 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::GetTwoNormalAdd(NORMAL normal1,NORMAL normal2)
{
NORMAL n;
n.nx=normal1.nx+normal2.nx;
n.ny=normal1.ny+normal2.ny;
n.nz=normal1.nz+normal2.nz;
return n;
}
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( (double)(n1.nx*n1.nx +n1.ny*n1.ny +n1.nz*n1.nz),0.5);
length2=pow( (double)(n2.nx*n2.nx +n2.ny*n2.ny +n2.nz*n2.nz),0.5);
return float(temp/(length1*length2));
}
float CMath::GetDotProduct(NORMAL n1,NORMAL n2)
{
float lenth1=GetMagnitude(n1);
float lenth2=GetMagnitude(n2);
float cosine=GetTwoVectorAngleCosine(n1,n2);
return lenth1*lenth2*cosine;
}
float CMath::GetDistance(VERTEX v1,VERTEX v2)
{
float dist;
dist=(float)pow((double)((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,VERzhuTEX point)
{
PLANE plane=GetPlaneEquation(lineV1,lineV2,VERTEX(lineV1.xpos,lineV1.ypos-200,lineV1.zpos));//将2d的线沿垂直方向扩展成一个平面
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));
}
float CMath::GetMagnitude(NORMAL normal)
{
return (float)sqrt(normal.nx*normal.nx + normal.ny*normal.ny+ normal.nz*normal.nz);
}
float CMath::GetMagnitude(VERTEX v1,VERTEX v2)
{
float x=v1.xpos-v2.xpos;
float y=v1.ypos-v2.ypos;
float z=v1.zpos-v2.zpos;
return (float)sqrt(x*x+y*y+z*z);
}
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;*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -