19.04.27--3D场景实现的点置换
void cube_change(CUBE_point ob,CUBE_point a,CUBE_point center,CUBE_point boundary,int radius,CUBE_point &c)
{
double ia,ib,ic,ix,cx,cy,cz,t_cos/*,cos_width,cos_height*/,cos_y,sin_y;
double ear_x,ear_y,ear_z,head_x,head_y,head_z,test_x,test_y;
double mem_x,mem_y,mem_z,buf_x,buf_y,buf_z;
int direction;
{
double ia,ib,ic,ix,cx,cy,cz,t_cos/*,cos_width,cos_height*/,cos_y,sin_y;
double ear_x,ear_y,ear_z,head_x,head_y,head_z,test_x,test_y;
double mem_x,mem_y,mem_z,buf_x,buf_y,buf_z;
int direction;
/*和视线的角度(新算法)*/
t_cos=(double)((a.x-ob.x)*(boundary.x-ob.x)+(a.y-ob.y)*(boundary.y-ob.y)+(a.z-ob.z)*(boundary.z-ob.z))/
sqrt(pow((double)(a.x-ob.x),2)+pow((double)(a.y-ob.y),2)+pow((double)(a.z-ob.z),2))/
sqrt(pow((double)(boundary.x-ob.x),2)+pow((double)(boundary.y-ob.y),2)+pow((double)(boundary.z-ob.z),2));
/*和视线的角度*/
t_cos=(double)((a.x-ob.x)*(boundary.x-ob.x)+(a.y-ob.y)*(boundary.y-ob.y)+(a.z-ob.z)*(boundary.z-ob.z))/
sqrt(pow((double)(a.x-ob.x),2)+pow((double)(a.y-ob.y),2)+pow((double)(a.z-ob.z),2))/
sqrt(pow((double)(boundary.x-ob.x),2)+pow((double)(boundary.y-ob.y),2)+pow((double)(boundary.z-ob.z),2));
/*和视线的角度*/
/*求视野宽度(旧算法)*/
//求出视角边缘临界线(向量)
/* ia=3*pow((double)(boundary.y-ob.y),2)-pow((double)(boundary.x-ob.x),2);
ib=8*(double)((boundary.y-ob.y)*(boundary.x-ob.x));
ic=3*pow((double)(boundary.x-ob.x),2)-pow((double)(boundary.y-ob.y),2);
ix=sqrt(pow(ib,2)-4*ia*ic);
//求出视角边缘临界线(向量)
/* ia=3*pow((double)(boundary.y-ob.y),2)-pow((double)(boundary.x-ob.x),2);
ib=8*(double)((boundary.y-ob.y)*(boundary.x-ob.x));
ic=3*pow((double)(boundary.x-ob.x),2)-pow((double)(boundary.y-ob.y),2);
ix=sqrt(pow(ib,2)-4*ia*ic);
//求出K可以算出与圆的的交点
cz=(-ib+ix)/2/ia;//K
cz=(-ib+ix)/2/ia;//K
//列直线与圆相交方程并求出交点
ia=1+pow(cz,2);
ib=-2*((double)center.x+pow(cz,2)*(double)ob.x+cz*(double)(center.y-ob.y));
ic=pow((double)center.x,2)+pow((double)(ob.y-center.y)-cz*(double)ob.x,2)-pow((double)radius,2);
// x0=pow(ib,2)-4*ia*ic;
ix=sqrt(pow(ib,2)-4*ia*ic);
cx=(-ib+ix)/2/ia;//视线向量(boundary.x-ob.x,boundary.y-ob.y)
cy=cz*(cx-(double)ob.x)+(double)ob.y;//视野边缘向量(cx-(double)center.x,cy-(double)center.y)
ia=1+pow(cz,2);
ib=-2*((double)center.x+pow(cz,2)*(double)ob.x+cz*(double)(center.y-ob.y));
ic=pow((double)center.x,2)+pow((double)(ob.y-center.y)-cz*(double)ob.x,2)-pow((double)radius,2);
// x0=pow(ib,2)-4*ia*ic;
ix=sqrt(pow(ib,2)-4*ia*ic);
cx=(-ib+ix)/2/ia;//视线向量(boundary.x-ob.x,boundary.y-ob.y)
cy=cz*(cx-(double)ob.x)+(double)ob.y;//视野边缘向量(cx-(double)center.x,cy-(double)center.y)
//求出临界弧度(角度)
cos_width=((cx-(double)center.x)*(double)(boundary.x-ob.x)+(cy-(double)center.y)*(double)(boundary.y-ob.y))/
sqrt(pow(cx-(double)center.x,2)+pow(cy-(double)center.y,2))/
sqrt(pow((double)(boundary.x-ob.x),2)+pow((double)(boundary.y-ob.y),2));*/
// x0=cos_width;
/*求视野宽度*/
cos_width=((cx-(double)center.x)*(double)(boundary.x-ob.x)+(cy-(double)center.y)*(double)(boundary.y-ob.y))/
sqrt(pow(cx-(double)center.x,2)+pow(cy-(double)center.y,2))/
sqrt(pow((double)(boundary.x-ob.x),2)+pow((double)(boundary.y-ob.y),2));*/
// x0=cos_width;
/*求视野宽度*/
/*求视野高度(旧算法)*/
//求出视角边缘临界线(向量)
/* ia=(1-pow(cos(2*PI/9),2))*pow((double)(boundary.y-ob.y),2)-pow(cos(2*PI/9),2)*pow((double)(boundary.x-ob.x),2);
ib=2*(double)((boundary.y-ob.y)*(boundary.x-ob.x));
ic=(1-pow(cos(2*PI/9),2))*pow((double)(boundary.x-ob.x),2)-pow(cos(2*PI/9),2)*pow((double)(boundary.y-ob.y),2);
// x0=pow(ib,2)-4*ia*ic;
ix=sqrt(pow(ib,2)-4*ia*ic);
//求出视角边缘临界线(向量)
/* ia=(1-pow(cos(2*PI/9),2))*pow((double)(boundary.y-ob.y),2)-pow(cos(2*PI/9),2)*pow((double)(boundary.x-ob.x),2);
ib=2*(double)((boundary.y-ob.y)*(boundary.x-ob.x));
ic=(1-pow(cos(2*PI/9),2))*pow((double)(boundary.x-ob.x),2)-pow(cos(2*PI/9),2)*pow((double)(boundary.y-ob.y),2);
// x0=pow(ib,2)-4*ia*ic;
ix=sqrt(pow(ib,2)-4*ia*ic);
//求出K可以算出与圆的的交点
cz=(-ib+ix)/2/ia;//K
cz=(-ib+ix)/2/ia;//K
//列直线与圆相交方程并求出交点
ia=1+pow(cz,2);
ib=-2*((double)center.x+pow(cz,2)*(double)ob.x+cz*(double)(center.y-ob.y));
ic=pow((double)center.x,2)+pow((double)(ob.y-center.y)-cz*(double)ob.x,2)-pow((double)radius,2);
ix=sqrt(pow(ib,2)-4*ia*ic);
cx=(-ib+ix)/2/ia;//视线向量(boundary.x-ob.x,boundary.y-ob.y)
cy=cz*(cx-(double)ob.x)+(double)ob.y;//视野边缘向量(cx-(double)center.x,cy-(double)center.y)
ia=1+pow(cz,2);
ib=-2*((double)center.x+pow(cz,2)*(double)ob.x+cz*(double)(center.y-ob.y));
ic=pow((double)center.x,2)+pow((double)(ob.y-center.y)-cz*(double)ob.x,2)-pow((double)radius,2);
ix=sqrt(pow(ib,2)-4*ia*ic);
cx=(-ib+ix)/2/ia;//视线向量(boundary.x-ob.x,boundary.y-ob.y)
cy=cz*(cx-(double)ob.x)+(double)ob.y;//视野边缘向量(cx-(double)center.x,cy-(double)center.y)
//求出临界弧度(角度)
cos_height=((cx-(double)center.x)*(double)(boundary.x-ob.x)+(cy-(double)center.y)*(double)(boundary.y-ob.y))/
sqrt(pow(cx-(double)center.x,2)+pow(cy-(double)center.y,2))/
sqrt(pow((double)(boundary.x-ob.x),2)+pow((double)(boundary.y-ob.y),2));*/
// x0=cos_height;
/*求视野高度*/
cos_height=((cx-(double)center.x)*(double)(boundary.x-ob.x)+(cy-(double)center.y)*(double)(boundary.y-ob.y))/
sqrt(pow(cx-(double)center.x,2)+pow(cy-(double)center.y,2))/
sqrt(pow((double)(boundary.x-ob.x),2)+pow((double)(boundary.y-ob.y),2));*/
// x0=cos_height;
/*求视野高度*/
/*判断方向*/
//视线向量((double)(boundary.x-ob.x),(double)(boundary.y-ob.y),(double)(boundary.z-ob.z))
//耳朵向量(ear_x,ear_y,ear_z)
if(boundary.x-ob.x==0)
ear_x=1;
else
ear_x=(double)ob.x+pow((double)(boundary.y-ob.y),2)/sqrt(pow((double)(ob.x-boundary.x),4)+
pow((double)(boundary.y-ob.y),4));
if(boundary.y-ob.y==0)
ear_y=0;
else
ear_y=(double)(boundary.x-ob.x)*(ob.x-1)/(double)(boundary.y-ob.y);
ear_z=0;
//视线向量((double)(boundary.x-ob.x),(double)(boundary.y-ob.y),(double)(boundary.z-ob.z))
//耳朵向量(ear_x,ear_y,ear_z)
if(boundary.x-ob.x==0)
ear_x=1;
else
ear_x=(double)ob.x+pow((double)(boundary.y-ob.y),2)/sqrt(pow((double)(ob.x-boundary.x),4)+
pow((double)(boundary.y-ob.y),4));
if(boundary.y-ob.y==0)
ear_y=0;
else
ear_y=(double)(boundary.x-ob.x)*(ob.x-1)/(double)(boundary.y-ob.y);
ear_z=0;
//头顶向量(head_x,head_y,head_z)
head_y=(double)(boundary.z-ob.z)*(1-(double)ob.x);
if(boundary.y-ob.y==0)
{
head_x=0;
head_z=1;
}
else
{
head_x=(double)((boundary.x-ob.x)*(boundary.z-ob.z))/(double)(boundary.y-ob.y)*(1-(double)ob.x);
head_z=(pow((double)(boundary.y-ob.y),2)+pow((double)(boundary.y-ob.y),2))*
((double)ob.x-1)/(double)(boundary.y-ob.y);
}
if(boundary.x-ob.x==0)
head_z=1;
else
head_z=-(pow((double)(boundary.x-ob.x),2)+pow((double)(boundary.y-ob.y),2))*(1-pow((double)ob.x,2))/
(double)(boundary.x-ob.x)/(double)(boundary.z-ob.z)-ob.z;
head_y=(double)(boundary.z-ob.z)*(1-(double)ob.x);
if(boundary.y-ob.y==0)
{
head_x=0;
head_z=1;
}
else
{
head_x=(double)((boundary.x-ob.x)*(boundary.z-ob.z))/(double)(boundary.y-ob.y)*(1-(double)ob.x);
head_z=(pow((double)(boundary.y-ob.y),2)+pow((double)(boundary.y-ob.y),2))*
((double)ob.x-1)/(double)(boundary.y-ob.y);
}
if(boundary.x-ob.x==0)
head_z=1;
else
head_z=-(pow((double)(boundary.x-ob.x),2)+pow((double)(boundary.y-ob.y),2))*(1-pow((double)ob.x,2))/
(double)(boundary.x-ob.x)/(double)(boundary.z-ob.z)-ob.z;
//判断锐角或钝角得出方向
test_x=((double)(a.x-ob.x)*ear_x+(double)(a.y-ob.y)*ear_y+(double)(a.z-ob.z)*ear_z)/
sqrt(pow((double)(a.x-ob.x),2)+pow((double)(a.y-ob.y),2)+pow((double)(a.z-ob.z),2))/
sqrt(pow(ear_x,2)+pow(ear_y,2)+pow(ear_z,2));
test_y=((double)(a.x-ob.x)*head_x+(double)(a.y-ob.y)*head_y+(double)(a.z-ob.z)*head_z)/
sqrt(pow((double)(a.x-ob.x),2)+pow((double)(a.y-ob.y),2)+pow((double)(a.z-ob.z),2))/
sqrt(pow(head_x,2)+pow(head_y,2)+pow(head_z,2));
if(test_x<0&&test_y>=0)
direction=1;
else if(test_x>=0&&test_y>=0)
direction=2;
else if(test_x<0&&test_y<0)
direction=3;
else if(test_x>=0&&test_y<0)
direction=4;
/*判断方向*/
test_x=((double)(a.x-ob.x)*ear_x+(double)(a.y-ob.y)*ear_y+(double)(a.z-ob.z)*ear_z)/
sqrt(pow((double)(a.x-ob.x),2)+pow((double)(a.y-ob.y),2)+pow((double)(a.z-ob.z),2))/
sqrt(pow(ear_x,2)+pow(ear_y,2)+pow(ear_z,2));
test_y=((double)(a.x-ob.x)*head_x+(double)(a.y-ob.y)*head_y+(double)(a.z-ob.z)*head_z)/
sqrt(pow((double)(a.x-ob.x),2)+pow((double)(a.y-ob.y),2)+pow((double)(a.z-ob.z),2))/
sqrt(pow(head_x,2)+pow(head_y,2)+pow(head_z,2));
if(test_x<0&&test_y>=0)
direction=1;
else if(test_x>=0&&test_y>=0)
direction=2;
else if(test_x<0&&test_y<0)
direction=3;
else if(test_x>=0&&test_y<0)
direction=4;
/*判断方向*/
/*求视网膜交点*/
//列直线与球相交方程
ia=1+(pow((double)(a.y-ob.y),2)+pow((double)(a.z-ob.z),2))/pow((double)(a.x-ob.x),2);
ib=-2*((double)((a.y-ob.y)*(ob.x*a.y-a.x*ob.y)+(a.z-ob.z)*(ob.x*a.z-a.x*ob.z))/pow((double)(a.x-ob.x),2)+
(double)(center.x*(a.x-ob.x)+center.y*(a.y-ob.y)+center.z*(a.z-ob.z))/(double)(a.x-ob.x));
ic=2*(double)(boundary.y*(ob.x*a.y-a.x*ob.y)+boundary.z*(ob.x*a.z-a.x*ob.z))/(double)(a.x-ob.x)+
pow((double)boundary.x,2)+pow((double)boundary.y,2)+pow((double)boundary.z,2)-
pow((double)radius,2);
mem_x=pow(ib,2)-4*ia*ic;
if(mem_x>=0)
ix=sqrt(pow(ib,2)-4*ia*ic);
//列直线与球相交方程
ia=1+(pow((double)(a.y-ob.y),2)+pow((double)(a.z-ob.z),2))/pow((double)(a.x-ob.x),2);
ib=-2*((double)((a.y-ob.y)*(ob.x*a.y-a.x*ob.y)+(a.z-ob.z)*(ob.x*a.z-a.x*ob.z))/pow((double)(a.x-ob.x),2)+
(double)(center.x*(a.x-ob.x)+center.y*(a.y-ob.y)+center.z*(a.z-ob.z))/(double)(a.x-ob.x));
ic=2*(double)(boundary.y*(ob.x*a.y-a.x*ob.y)+boundary.z*(ob.x*a.z-a.x*ob.z))/(double)(a.x-ob.x)+
pow((double)boundary.x,2)+pow((double)boundary.y,2)+pow((double)boundary.z,2)-
pow((double)radius,2);
mem_x=pow(ib,2)-4*ia*ic;
if(mem_x>=0)
ix=sqrt(pow(ib,2)-4*ia*ic);
//求出交点
cx=(-ib+ix)/2/ia;
if(direction==1||direction==3)//选取正确的点
cx=(-ib-ix)/2/ia;
cy=(double)ob.y+(double)(a.y-ob.y)*(cx-(double)ob.x)/(double)(a.x-ob.x);
cz=(double)ob.z+(double)(a.z-ob.z)*(cx-(double)ob.x)/(double)(a.x-ob.x);
/*求视网膜交点*/
cx=(-ib+ix)/2/ia;
if(direction==1||direction==3)//选取正确的点
cx=(-ib-ix)/2/ia;
cy=(double)ob.y+(double)(a.y-ob.y)*(cx-(double)ob.x)/(double)(a.x-ob.x);
cz=(double)ob.z+(double)(a.z-ob.z)*(cx-(double)ob.x)/(double)(a.x-ob.x);
/*求视网膜交点*/
/*求空间余弦(两个分量)*/
//点圆心向量(cx-(double)center.x,cy-(double)center.y,cz-(double)center.z)
//方向向量->[视线向量,耳朵向量,头顶向量]
//以视线向量为法向量的平面即为屏幕((double)(boundary.x-ob.x),(double)(boundary.y-ob.y),(double)(boundary.z-ob.z))
buf_x=(double)(boundary.y-ob.y)*(cz-(double)center.z)-(double)(boundary.z-ob.z)*(cy-(double)center.y);
buf_y=(double)(boundary.z-ob.z)*(cx-(double)center.x)-(double)(boundary.x-ob.x)*(cz-(double)center.z);
buf_z=(double)(boundary.x-ob.x)*(cy-(double)center.y)-(double)(boundary.y-ob.y)*(cx-(double)center.x);
mem_x=buf_y*(cz-(double)center.z)-buf_z*(cy-(double)center.y);
mem_y=buf_z*(cx-(double)center.x)-buf_x*(cz-(double)center.z);
mem_z=buf_x*(cy-(double)center.y)-buf_y*(cx-(double)center.x);
cos_y=fabs((mem_x*ear_x+mem_y*ear_y+mem_z*ear_z)/
sqrt(pow(mem_x,2)+pow(mem_y,2)+pow(mem_z,2))/
sqrt(pow(ear_x,2)+pow(ear_y,2)+pow(ear_z,2)));
sin_y=sqrt(1-pow(cos_y,2));
/* cos_y=(mem_x*ear_x+mem_y*ear_y+mem_z*ear_z)/
sqrt(pow(mem_x,2)+pow(mem_y,2)+pow(mem_z,2))/
sqrt(pow(ear_x,2)+pow(ear_y,2)+pow(ear_z,2));*/
// x1=cos_y;
/*求空间余弦*/
//点圆心向量(cx-(double)center.x,cy-(double)center.y,cz-(double)center.z)
//方向向量->[视线向量,耳朵向量,头顶向量]
//以视线向量为法向量的平面即为屏幕((double)(boundary.x-ob.x),(double)(boundary.y-ob.y),(double)(boundary.z-ob.z))
buf_x=(double)(boundary.y-ob.y)*(cz-(double)center.z)-(double)(boundary.z-ob.z)*(cy-(double)center.y);
buf_y=(double)(boundary.z-ob.z)*(cx-(double)center.x)-(double)(boundary.x-ob.x)*(cz-(double)center.z);
buf_z=(double)(boundary.x-ob.x)*(cy-(double)center.y)-(double)(boundary.y-ob.y)*(cx-(double)center.x);
mem_x=buf_y*(cz-(double)center.z)-buf_z*(cy-(double)center.y);
mem_y=buf_z*(cx-(double)center.x)-buf_x*(cz-(double)center.z);
mem_z=buf_x*(cy-(double)center.y)-buf_y*(cx-(double)center.x);
cos_y=fabs((mem_x*ear_x+mem_y*ear_y+mem_z*ear_z)/
sqrt(pow(mem_x,2)+pow(mem_y,2)+pow(mem_z,2))/
sqrt(pow(ear_x,2)+pow(ear_y,2)+pow(ear_z,2)));
sin_y=sqrt(1-pow(cos_y,2));
/* cos_y=(mem_x*ear_x+mem_y*ear_y+mem_z*ear_z)/
sqrt(pow(mem_x,2)+pow(mem_y,2)+pow(mem_z,2))/
sqrt(pow(ear_x,2)+pow(ear_y,2)+pow(ear_z,2));*/
// x1=cos_y;
/*求空间余弦*/
/*求屏幕投影坐标(焦距:FOCUS)*/
if(t_cos==0)t_cos=0.00001;
if(direction==1)
{
c.x=(int)(WINDOW_WIDTH/2-FOCUS_x*sqrt(1/pow(t_cos,2)-1)*cos_y);
c.z=(int)(WINDOW_HEIGHT/2-FOCUS_y*sqrt(1/pow(t_cos,2)-1)*sin_y);
}
else if(direction==2)
{
c.x=(int)(WINDOW_WIDTH/2+FOCUS_x*sqrt(1/pow(t_cos,2)-1)*cos_y);
c.z=(int)(WINDOW_HEIGHT/2-FOCUS_y*sqrt(1/pow(t_cos,2)-1)*sin_y);
}
else if(direction==3)
{
c.x=(int)(WINDOW_WIDTH/2-FOCUS_x*sqrt(1/pow(t_cos,2)-1)*cos_y);
c.z=(int)(WINDOW_HEIGHT/2+FOCUS_y*sqrt(1/pow(t_cos,2)-1)*sin_y);
}
else if(direction==4)
{
c.x=(int)(WINDOW_WIDTH/2+FOCUS_x*sqrt(1/pow(t_cos,2)-1)*cos_y);
c.z=(int)(WINDOW_HEIGHT/2+FOCUS_y*sqrt(1/pow(t_cos,2)-1)*sin_y);
}
x0=c.x/*c.x*/;
yy=c.z/*c.z*/;
z0=ic/*c.x*/;
c.y=0;
/*求屏幕投影坐标*/
}
if(t_cos==0)t_cos=0.00001;
if(direction==1)
{
c.x=(int)(WINDOW_WIDTH/2-FOCUS_x*sqrt(1/pow(t_cos,2)-1)*cos_y);
c.z=(int)(WINDOW_HEIGHT/2-FOCUS_y*sqrt(1/pow(t_cos,2)-1)*sin_y);
}
else if(direction==2)
{
c.x=(int)(WINDOW_WIDTH/2+FOCUS_x*sqrt(1/pow(t_cos,2)-1)*cos_y);
c.z=(int)(WINDOW_HEIGHT/2-FOCUS_y*sqrt(1/pow(t_cos,2)-1)*sin_y);
}
else if(direction==3)
{
c.x=(int)(WINDOW_WIDTH/2-FOCUS_x*sqrt(1/pow(t_cos,2)-1)*cos_y);
c.z=(int)(WINDOW_HEIGHT/2+FOCUS_y*sqrt(1/pow(t_cos,2)-1)*sin_y);
}
else if(direction==4)
{
c.x=(int)(WINDOW_WIDTH/2+FOCUS_x*sqrt(1/pow(t_cos,2)-1)*cos_y);
c.z=(int)(WINDOW_HEIGHT/2+FOCUS_y*sqrt(1/pow(t_cos,2)-1)*sin_y);
}
x0=c.x/*c.x*/;
yy=c.z/*c.z*/;
z0=ic/*c.x*/;
c.y=0;
/*求屏幕投影坐标*/
}