在图形模式下显示3D图形绕任意轴旋转的程序,物体的每一个顶点的坐标都储存在外部变量point中了,比如说第一个顶点就是point[0],他的坐标是(point[0][0],point[0][1],point[0][2])。整个步骤我想在程序的注释中讲得很清楚了。我qq是164449625,欢迎留言。最好用WINTC编译。
#include \"stdio.h\"
#include \"Conio.h\"
#include \"graphics.h\"
#include \"math.h\"
#define closegr closegraph
#define PI 3.1415926
#define I 30
double point[I][3]={{300,260,100},{200,260,100},{200,160,100},{300,160,100},{300,260,100},
{300,260,120},{200,260,120},{200,160,120},{300,160,120},{300,260,120},
{300,260,140},{200,260,140},{200,160,140},{300,160,140},{300,260,140},
{300,260,160},{200,260,160},{200,160,160},{300,160,160},{300,260,160},
{300,260,180},{200,260,180},{200,160,180},{300,160,180},{300,260,180},
{300,260,200},{200,260,200},{200,160,200},{300,160,200},{300,260,200}
}, /*用来存放物体各个顶点的坐标*/
chp[I][3],
vector[3]; /* 运动轴的方向矢量,该矢量的起点是原点,三个元素用来存放终点的坐标*/
void initgr(void)
{int gd=DETECT,gm=0;
registerbgidriver(EGAVGA_driver);
initgraph(&gd,&gm,\"\");
}
main()
{
double x,y,z,x1,y1,z1,t,io=1,
angle1,angle2,axletree[2][3],i,f[3];
int s=0,e=27; /*这里设定转动轴的终点point[e][x]和起点point[s][x]*/
vector[0]=point[e][0]-point[s][0]; /*该运动轴由点point[7]和point[0]作为终点和起点*/
vector[1]=point[e][1]-point[s][1];
vector[2]=point[e][2]-point[s][2];
for(i=-1,t=0;t<2;t++) /*得到运动轴上的两个点用来显示轴*/
{
x=point[e][0]+(i*vector[0]);
y=point[e][1]+(i*vector[1]);
z=point[e][2]+(i*vector[2]);
axletree[t][0]=x;
axletree[t][1]=y;
axletree[t][2]=z;
i+=15;
}
if(vector[0]<=0) /*如果vector[0]==0&&vector[1]==0方向矢量的angle1不存在*/
{
if(!vector[0]&&!vector[1])
{
angle1=10000;
angle2=0.5*PI;
}
else
angle1=PI-asin(vector[1]/sqrt((vector[0]*vector[0])+(vector[1]*vector[1]))); /*注意这里的vector[1]取正或者取负都成立*/
[NextPage]
}
else
angle1=2*PI+asin(vector[1]/sqrt((vector[0]*vector[0])+(vector[1]*vector[1]))); /*angle1是转动轴的矢量在平面x,y上的投影与y+的夹角,从z-方向观察顺时针方向为正方向*/
if(angle2!=0.5*PI)
angle2=asin(vector[2]/sqrt((vector[0]*vector[0])+(vector[1]*vector[1])+(vector[2]*vector[2])));
initgr();
getch();
for(t=0,i=0;;) /*t存放的是转动的弧度*/
{
i=0;
while(i<I)
{
x=point[i][0]-axletree[0][0]; /*将顶点平移其平移的量由转动轴的起点到坐标原点的距离决定*/
y=point[i][1]-axletree[0][1];
z=point[i][2]-axletree[0][2];
if(angle1!=10000) /*假若轴矢量与z轴不重合则先绕z轴顺时针转动angle1个弧度(从z+方向观察)*/
{
x1=(x*cos(angle1))-(y*sin(-angle1));
y1=(x*sin(-angle1))+(y*cos(angle1));
z1=z;
}
else x1=x,y1=y,z1=z;
x=(z1*sin(angle2))+(x1*cos(angle2)); /*绕y轴顺时针转动angle2个弧度(从y-方向观察)*/
y=y1;
z=(z1*cos(angle2))-(x1*sin(angle2));
x1=x; /*绕x轴顺时针转动t个弧度(从x-方向观察)*/
y1=(y*cos(t))-(z*sin(t));
z1=(y*sin(t))+(z*cos(t));
x=(z1*sin(-angle2))+(x1*cos(angle2)); /*逆运算,恢复原状*/
y=y1;
z=(z1*cos(angle2))-(x1*sin(-angle2));
if(angle1!=10000)
{
x1=(x*cos(angle1))-(y*sin(angle1));
y1=(x*sin(angle1))+(y*cos(angle1));
z1=z;
}
else x1=x,y1=y,z1=z;
x=x1+axletree[0][0];
y=y1+axletree[0][1];
z=z1+axletree[0][2];
[NextPage]
chp[i][0]=x,chp[i][1]=y,chp[i][2]=z;
i++;
}
for(i=0;i<I;i++) /*绘制图形并连接各个顶点*/
{
setcolor(15);
if(i!=0)
line(chp[i-1.0][0],chp[i-1.0][1],chp[i][0],chp[i][1]);
}
line(axletree[0][0],axletree[0][1],axletree[1][0],axletree[1][1]);
delay(400);
for(i=0;i<I;i++) /*用背景色覆盖图形*/
{
setcolor(0);
if(i!=0)
line(chp[i-1.0][0],chp[i-1.0][1],chp[i][0],chp[i][1]);
}
if(t>2*PI) t=0;
if(bioskey(1)!=NULL)
{
if(bioskey(1)==0x11b) break;
else
io=!io;
bioskey(0);
}
if(io) t=t+0.01;
}
closegr();
}