标题:从一本书上得来的超难程序,希望得到大家的帮助啊!
只看楼主
nunununu
Rank: 2
等 级:论坛游民
帖 子:22
专家分:32
注 册:2010-3-31
结帖率:100%
已结贴  问题点数:30 回复次数:10 
从一本书上得来的超难程序,希望得到大家的帮助啊!
#include<graphics.h>
#include<conio.h>
#include<dos.h>
#include<math.h>
#include<stdlib.h>
#define PI 3.1415926
int     A=50;
float w=0.2;
/*(X,Y)是小球运动轨迹的坐标点*/
double Y=0.0,X=10.0;
char ch;
/*R为球体半径,longitude、latitude分别为半径与经纬线的夹角*/
void Ball(float R,int longitude,int latitude)
{   
 /*定义旋转变换前点坐标数组x,y,z.以及旋转变换后点坐标数组x1,z1*/
 float x[4],y[4],z[4],x1[4],z1[4];   
 int i,j,k;
 /*定义坐标转换后的屏幕坐标数组sx,sy*/
 float sx[4],sy[4];
 /*定义存放了5个顶点坐标序列的数组*/
 int fillcolor[10];  
 double a1,a2,b1,b2,c,d,yn;
 /*设置每次旋转的角度*/
 c=longitude*PI/180.0;  
 d=latitude*PI/180.0;
 cleardevice();
 for(j=0;j<180;j=j+20)
 {
   a1=j*PI/180.0;
   a2=(j+20)*PI/180.0;
   for(i=0;i<360;i=i+20)
   {
    b1=i*PI/180;
    b2=(i+20)*PI/180;
    /*求出图形旋转前点的坐标*/
    x[0]=R*sin(a1)*cos(b1);y[0]=R*sin(a1)*sin(b1);z[0]=R*cos(a1);   
    x[1]=R*sin(a2)*cos(b1);y[1]=R*sin(a2)*sin(b1);z[1]=R*cos(a2);
    x[2]=R*sin(a2)*cos(b2);y[2]=R*sin(a2)*sin(b2);z[2]=R*cos(a2);
    x[3]=R*sin(a1)*cos(b2);y[3]=R*sin(a1)*sin(b2);z[3]=R*cos(a1);
    /*求出图形旋转后点的坐标*/
    for(k=0;k<4;k++)
    {
         x1[k]=x[k]*cos(c)-y[k]*sin(c);
         z1[k]=-x[k]*sin(c)*sin(d)-y[k]*cos(c)*sin(d)+z[k]*cos(d);
         /*将三维坐标转化为屏幕坐标*/
      sx[k]=100-x1[k];  
      sy[k]=100-z1[k];
      }
    yn=-(x1[2]-x1[0])*(z1[3]-z1[1])+(x1[3]-x1[1])*(z1[2]-z1[0]);
    /*对可见部分进行画线,实现消隐*/
    if(yn>=0.0)   
    {
      moveto(sx[0],sy[0]);
      lineto(sx[1],sy[1]);
      lineto(sx[2],sy[2]);
      lineto(sx[3],sy[3]);
      lineto(sx[0],sy[0]);
      fillcolor[0]=(int)sx[0],fillcolor[1]=(int)sy[0];
      fillcolor[2]=(int)sx[1],fillcolor[3]=(int)sy[1];
      fillcolor[4]=(int)sx[2],fillcolor[5]=(int)sy[2];
      fillcolor[6]=(int)sx[3],fillcolor[7]=(int)sy[3];
      fillcolor[8]=(int)sx[0],fillcolor[9]=(int)sy[0];
      setfillstyle(1,WHITE);
      /*用当前颜色填充多边形*/
      fillpoly(5,fillcolor);  
    }
   }
 }
}
/*轨迹方程函数*/
void Track()        
{
    X+=10.0;
     Y=200-A*sin(w*X);
     /*控制球体运动的最大坐标*/
     if(X>=500&&Y>=400)
     {
         X=10.0;
         Y=0.0;
     }
}/
int main()
{
    int gdrive=DETECT,gmode,k,t,i=0;
  int size; void *buf[10];
  initgraph(&gdrive,&gmode,"e:\\tc");
  setcolor(GREEN);  
  for(k=36;k<=360;k=k+36)
  {
      /*调用Ball函数*/
       Ball(50,k,k);  
       size=imagesize(50,40,150,150);
         /*将保护位图象所需的字节数赋值给size*/
    if(size!=-1)
         buf[i]=malloc(size);    /* 分配size字节的内存空间*/
    if(buf[i])
        getimage(50,40,150,150,buf[i]);  
        /*在屏幕指定的位置将一个位图保存到内存*/
        i++;
  }
  cleardevice();
  for(t=0;t<=40;t++)
  {  
      cleardevice();
      /*在指定位置以拷贝形式输出一个位图*/
    putimage(X,Y,buf[t%10],COPY_PUT);  
        /*设置球运动的时间间隔*/
    delay(100);
         Track();
  }
  /*释放内存空间*/
     for(i=0;i<10;i++)
      free(buf[i]);   
  getch();
  closegraph();
  return 0;
}     

/*完全想不通函数ball()是怎么运行的,完全看不懂啊,哪位大哥大姐能帮我解释一下呢*/

搜索更多相关主题的帖子: 旋转 void include double 经纬线 
2010-10-25 16:59
wujieru
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:1
帖 子:1108
专家分:1939
注 册:2010-10-9
得分:0 
呵呵 不错哈 我以前也写过一个类似的小游戏
2010-10-25 17:05
nunununu
Rank: 2
等 级:论坛游民
帖 子:22
专家分:32
注 册:2010-3-31
得分:0 
根本就不知道小球怎么画出来的,而且用到辅助角公式:x1[k]=x[k]*cos(c)-y[k]*sin(c),完全搞不清楚
2010-10-25 17:17
wujieru
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:1
帖 子:1108
专家分:1939
注 册:2010-10-9
得分:0 
很麻烦的
2010-10-25 17:18
nunununu
Rank: 2
等 级:论坛游民
帖 子:22
专家分:32
注 册:2010-3-31
得分:0 
大哥帮帮忙吧!谢谢你了 不胜感激!!
2010-10-25 17:21
yuanfeng1129
Rank: 2
等 级:论坛游民
帖 子:62
专家分:31
注 册:2010-8-7
得分:0 
算了,今天心情不好,本来要上课的,不去了,来帮你看看,解答不出莫怪
2010-10-25 19:46
yuanfeng1129
Rank: 2
等 级:论坛游民
帖 子:62
专家分:31
注 册:2010-8-7
得分:0 
话说还真长
2010-10-25 19:46
yuanfeng1129
Rank: 2
等 级:论坛游民
帖 子:62
专家分:31
注 册:2010-8-7
得分:0 
楼主能说说这个游戏是干什么的吗?
2010-10-25 19:48
树上月
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:114
专家分:154
注 册:2010-1-6
得分:0 
看不懂啊!!!!!!

每一个不曾起舞的日子,都是对未来的一种辜负......
2010-10-25 20:30
yuanfeng1129
Rank: 2
等 级:论坛游民
帖 子:62
专家分:31
注 册:2010-8-7
得分:30 
看了好半天总算有点头绪了,我也尝试过用TC来运行,可是出现问题,图形上就一个球,不动的,后来才明白是个地球的模型,地球在围绕太阳公转时既有自转又有公转,Ball函数是控制这个球体的自转的,Track是控制其公转的,程序执行过程大概是这样的,先初始化图形系统,然后进入循环,执行Ball函数......
我加了些注解
#include<graphics.h>   
#include<conio.h>   
#include<dos.h>      
#include<math.h>      
#include<stdlib.h>   
#define PI 3.1415926
int     A=50;
float w=0.2;
/*(X,Y)是小球运动轨迹的坐标点*/
double Y=0.0,X=10.0;
char ch;
/*R为球体半径,longitude、latitude分别为半径与经纬线的夹角*/
/*关于这个函数,我基本理解了,不过也许我表述不清晰,请见谅,
  首先执行循环,根据半径与X和Z轴的夹角求出坐标,然后再根据上一步
  求出旋转后的坐标,最后再根据这四个点绘制出封闭图形a1=j*PI/180.0;
   a2=(j+20)*PI/180.0;控制与Z轴夹角的增加,b1=i*PI/180;
    b2=(i+20)*PI/180; 控制与X轴夹角的增加,绘制图形的过程由两个FOR循环
  控制,逆时针绘制图形,绘制一圈后,在向下移,绘制下一圈,也就是说从上到下,逆时针绘制,
  经过一些循环,球体就绘制完毕了*/
void Ball(float R,int longitude,int latitude)
{   
/*定义旋转变换前点坐标数组x,y,z.以及旋转变换后点坐标数组x1,z1*/
float x[4],y[4],z[4],x1[4],z1[4];   
int i,j,k;
/*定义坐标转换后的屏幕坐标数组sx,sy*/
float sx[4],sy[4];
/*定义存放了5个顶点坐标序列的数组*/
int fillcolor[10];  
double a1,a2,b1,b2,c,d,yn;
/*设置每次旋转的角度*/
c=longitude*PI/180.0;  
d=latitude*PI/180.0;
cleardevice();
for(j=0;j<180;j=j+20)
{
   a1=j*PI/180.0;  //a1和a2为半径和Z轴的夹角
   a2=(j+20)*PI/180.0;  
   for(i=0;i<360;i=i+20)
   {
    b1=i*PI/180;  //b1和b2为半径和x轴的夹角
    b2=(i+20)*PI/180;
    /*求出图形旋转前点的坐标*/
    x[0]=R*sin(a1)*cos(b1);y[0]=R*sin(a1)*sin(b1);z[0]=R*cos(a1); //这里都是求坐标的公式x=r*sin(a)*sin(b),  
    x[1]=R*sin(a2)*cos(b1);y[1]=R*sin(a2)*sin(b1);z[1]=R*cos(a2); //r*sin(a)就是半径投影在XY平面后的长度;
    x[2]=R*sin(a2)*cos(b2);y[2]=R*sin(a2)*sin(b2);z[2]=R*cos(a2); //具体请参考上网查询怎样求圆上一点的坐标
    x[3]=R*sin(a1)*cos(b2);y[3]=R*sin(a1)*sin(b2);z[3]=R*cos(a1);
    /*求出图形旋转后点的坐标*/
    //关于下面一步的公式我也不懂,你只需明白这是求旋转后点的坐标
    for(k=0;k<4;k++)
    {
         x1[k]=x[k]*cos(c)-y[k]*sin(c);  
         z1[k]=-x[k]*sin(c)*sin(d)-y[k]*cos(c)*sin(d)+z[k]*cos(d);
         /*将三维坐标转化为屏幕坐标*/
      sx[k]=100-x1[k];  
      sy[k]=100-z1[k];
      }
    yn=-(x1[2]-x1[0])*(z1[3]-z1[1])+(x1[3]-x1[1])*(z1[2]-z1[0]);
    /*对可见部分进行画线,实现消隐*/
    //以下是画多边形的步骤,用绿色填充,白色画边框
    if(yn>=0.0)   
    {
      moveto(sx[0],sy[0]);
      lineto(sx[1],sy[1]);
      lineto(sx[2],sy[2]);
      lineto(sx[3],sy[3]);
      lineto(sx[0],sy[0]);
      fillcolor[0]=(int)sx[0],fillcolor[1]=(int)sy[0];
      fillcolor[2]=(int)sx[1],fillcolor[3]=(int)sy[1];
      fillcolor[4]=(int)sx[2],fillcolor[5]=(int)sy[2];
      fillcolor[6]=(int)sx[3],fillcolor[7]=(int)sy[3];
      fillcolor[8]=(int)sx[0],fillcolor[9]=(int)sy[0];
      setfillstyle(1,WHITE);
      /*用当前颜色填充多边形*/
      fillpoly(5,fillcolor);  
    }
   }
}
}
/*轨迹方程函数*/
void Track()        
{
    X+=10.0;
     Y=200-A*sin(w*X);
     /*控制球体运动的最大坐标*/
     if(X>=500&&Y>=400)
     {
         X=10.0;
         Y=0.0;
     }
}
int main()
{
    int gdrive=DETECT,gmode,k,t,i=0;
  int size; void *buf[10];
  initgraph(&gdrive,&gmode,"D:\\TC\\BGI");
  setcolor(GREEN);  
  for(k=36;k<=360;k=k+36)
  {
      /*调用Ball函数*/
       Ball(50,k,k);  
       size=imagesize(50,40,150,150);
         /*将保护位图象所需的字节数赋值给size*/
    if(size!=-1)
         buf[i]=malloc(size);    /* 分配size字节的内存空间*/
    if(buf[i])
        getimage(50,40,150,150,buf[i]);  
        /*在屏幕指定的位置将一个位图保存到内存*/
        i++;
  }
  cleardevice();
  for(t=0;t<=40;t++)
  {  
      cleardevice();
      /*在指定位置以拷贝形式输出一个位图*/
    putimage(X,Y,buf[t%10],COPY_PUT);  
        /*设置球运动的时间间隔*/
    delay(100);
         Track();
  }
  /*释放内存空间*/
     for(i=0;i<10;i++)
      free(buf[i]);   
  getch();
  closegraph();
  return 0;
}  
2010-10-25 21:41



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-323949-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.062855 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved