天天看點

tc 3D模型繪圖

">[email protected]*/

#include <math.h>

#include <stdio.h>

#include <graphics.h>

#define PI 3.1415926

#define MAXROW 32

#define MAXLINE 16

struct _3DPoint

{

 float x;

 float y;

 float z;

};

struct _3DObjPosition

{

 //空間位移坐标

 struct _3DPoint point;

 //觀衆姿态角

 double User_angelY;

 double User_angelZ;

 //自心姿态角

 double angelY;

 double angelZ;

};

struct _2DPoint

{

 float x;

 float y;

};

struct _ProccessBox

{

 struct _2DPoint point;

 int Longth;

 int Higth;

 int BackGColor;

 int MyColor;

 char MyText[13];

};

float GetResult(float r,float angel1,float angel2);

void GraphicsInit(int mode,int driver);       

void ProccessBoxInit(struct _ProccessBox *p);    

void ProccessBoxSet(int n,struct _ProccessBox *p); 

float HalfWay(float angel1,float angel2);      

void Init3DObj(struct _3DObjPosition *p);      

void Change3DObjPosition(char order,struct _3DObjPosition *p); 

void Change3dTO2D(struct _3DPoint SousePoint,struct _3DObjPosition P,struct _3DPoint *ArmPoint);

void ShowSmallMap(void);

void main(void)

{

 int i, j;                  

 int l, n, k=0;        

 char PressKey='6';

 float AngelArpha, AngelThetar;

 float r,SmallMap[2][2]={0}; 

 struct _ProccessBox Proccess;

 struct _3DPoint SourceData[MAXROW][MAXLINE];       

 struct _3DObjPosition Object;

 struct _3DPoint TempPoint;

  struct _3DPoint ChangedData[MAXROW][MAXLINE][2]={0};    

 ProccessBoxInit(&Proccess);

 Init3DObj(&Object);

  GraphicsInit(VGAHI,VGA);      

 cleardevice();           

 for(i=0; i<MAXROW; i++)        

 {

  ProccessBoxSet(3*i, &Proccess);

  delay(60); 

  for(j=0; j<MAXLINE; j++)

  {

   AngelThetar = (PI / (MAXLINE -1)) * (j- (MAXLINE -1)/2.0);

   AngelArpha = (PI / (MAXROW -1)) * i * 2;

   r=HalfWay(AngelThetar,AngelArpha);

   SourceData[i][j].x = r * cos(AngelThetar) * cos(AngelArpha);

   SourceData[i][j].y = r * cos(AngelThetar) * sin(AngelArpha);

   SourceData[i][j].z = r * sin(AngelThetar);

  }

 }

 cleardevice();

 l = 0;

 AngelThetar = 0;

 for( ; ; )

 {

  if(kbhit()) PressKey = getch();

  switch(PressKey)

  {

   case 'c': 

   case 'C': { 

         l = (l-1) * (l-1);

         PressKey = 'q';

         break;

        }

   case '0': { 

         exit(0);

         break;

        }

    default: { if(PressKey < '0' || PressKey > '9')

         {//非數字

          if(l==1)

          {//小寫

           if(PressKey<'a') PressKey += 'a' -'A';

          }else

          {//大寫

           if(PressKey>='a') PressKey -= 'a' -'A';

          }

         }

         Change3DObjPosition(PressKey, &Object);

        }

  }

  k = (1 - k) * (1 - k);

  for(i=0; i<MAXROW; i++)   

  {

   for(j=0; j<MAXLINE; j++)

   {

    Change3dTO2D(SourceData[i][j], Object,&TempPoint);

      ChangedData[i][j][k].x = TempPoint.x + 320; 

    ChangedData[i][j][k].y = TempPoint.y + 240; 

    ChangedData[i][j][k].z = TempPoint.z;

   }

  }

   n=(1-k) * (1-k);

   for(i=0; i<MAXROW; i++) 

   {

   for(j=0; j<MAXLINE-1; j++)

   {

    if((ChangedData[i][j + 1][n].z > 0) && (ChangedData[i][j][n].z > 0))

    {

     setcolor(0);

     line(ChangedData[i][j][n].x, ChangedData[i][j][n].y, ChangedData[i][j+1][n].x, ChangedData[i][j + 1][n].y);

    }

    if((ChangedData[i][j+1][k].z > 0) && (ChangedData[i][j][k].z > 0))

    {

     setcolor(9); 

     line(ChangedData[i][j][k].x, ChangedData[i][j][k].y, ChangedData[i][j+1][k].x, ChangedData[i][j + 1][k].y);

    }

    if(i < (MAXROW-1))

    {

     if((ChangedData[i+1][j][n].z > 0) && (ChangedData[i][j][n].z > 0))

     {

      setcolor(0);

      line(ChangedData[i][j][n].x, ChangedData[i][j][n].y, ChangedData[i + 1][j][n].x, ChangedData[i + 1][j][n].y);

     }

     if((ChangedData[i+1][j][k].z > 0) && (ChangedData[i][j][k].z > 0))

     {

      setcolor(9);

      line(ChangedData[i][j][k].x, ChangedData[i][j][k].y, ChangedData[i+1][j][k].x, ChangedData[i+1][j][k].y);

     }

    }

    if(i == MAXROW-1)

    {

     if((ChangedData[0][j][n].z > 0) && (ChangedData[i][j][n].z > 0))

     {

      setcolor(0);

      line(ChangedData[i][j][n].x, ChangedData[i][j][n].y, ChangedData[0][j][n].x, ChangedData[0][j][n].y);

     }

     if((ChangedData[0][j][k].z > 0) && (ChangedData[i][j][k].z > 0))

     {

      setcolor(9);

      line(ChangedData[i][j][k].x, ChangedData[i][j][k].y, ChangedData[0][j][k].x, ChangedData[0][j][k].y);

     }

    }

   }

  }

   SmallMap[k][0] = Object.point.x * cos(Object.User_angelZ) - Object.point.y * sin(Object.User_angelZ);

   SmallMap[k][1] = sin(Object.User_angelZ) * Object.point.x + cos(Object.User_angelZ) * Object.point.y;

   SmallMap[k][1] = SmallMap[k][1] * cos(Object.User_angelY);

   setcolor(0);

   circle (SmallMap[n][0] / 20 + 26 , 26 - SmallMap[n][1] / 20, 5);

   setcolor (12);

   circle (SmallMap[k][0] / 20 + 26, 26 - SmallMap[k][1] / 20, 5);

  ShowSmallMap();

 }

}

void ProccessBoxInit(struct _ProccessBox *p)

{

 //資料初始化

 (*p).point.x =230;

 (*p).point.y =240;

 (*p).Longth =100;

 (*p).Higth =10;

 (*p).BackGColor =0;

 (*p).MyColor =1;

 strcpy((*p).MyText,"complete   %");

}

void Init3DObj(struct _3DObjPosition *p)

{

 (*p).point.x =0;

 (*p).point.y =0;

 (*p).point.z =0;

 (*p).User_angelY =0;

 (*p).User_angelZ =0;

 (*p).angelY =0;

 (*p).angelZ =0;

}

void ShowSmallMap()

{

  setcolor (14);

  circle (26, 26, 25);

  line (21, 26, 31, 26);

  line (26, 21, 26, 31);

  line (310,240,330,240);

  line (320,230,320,250);

  setcolor (2);

  line (26, 26, 17, 5);

  line (26, 26, 35, 5);

}

void Change3dTO2D(struct _3DPoint SourcePoint,struct _3DObjPosition P,struct _3DPoint *ArmPoint)

{

 struct _3DPoint TempPoint[4];

 float Deep;

 TempPoint[0].x = SourcePoint.x;  

 TempPoint[0].y = SourcePoint.y;

 TempPoint[0].z = SourcePoint.z;

 TempPoint[1].x = TempPoint[0].x * cos(P.angelY) - TempPoint[0].z * sin(P.angelY);  

 TempPoint[1].z = sin(P.angelY) * TempPoint[0].x + cos(P.angelY) * TempPoint[0].z;

 TempPoint[1].y = TempPoint[0].y;

 TempPoint[2].x = TempPoint[1].x * cos(P.angelZ) - TempPoint[1].y * sin(P.angelZ) + P.point.x; 

 TempPoint[2].y = sin(P.angelZ) * TempPoint[1].x + cos(P.angelZ) * TempPoint[1].y + P.point.y;

 TempPoint[2].z = TempPoint[1].z + P.point.z;

 TempPoint[3].x = TempPoint[2].x * cos(P.User_angelZ) - TempPoint[2].y * sin(P.User_angelZ);  

 TempPoint[1].y = sin(P.User_angelZ) * TempPoint[2].x + cos(P.User_angelZ) * TempPoint[2].y;

 TempPoint[3].y = TempPoint[1].y * cos(P.User_angelY) - TempPoint[2].z * sin(P.User_angelY);

 TempPoint[2].z = sin(P.User_angelY) * TempPoint[1].y + cos(P.User_angelY) * TempPoint[2].z;

 Deep =  1/ (0.1+0.001*pow (TempPoint[3].x*TempPoint[3].x+TempPoint[3].y*TempPoint[3].y+TempPoint[2].z*TempPoint[2].z,0.5)); 

 TempPoint[2].x = TempPoint[3].x * Deep;

 TempPoint[2].z = TempPoint[2].z * Deep;

  (*ArmPoint).x=TempPoint[2].x;

  (*ArmPoint).y=TempPoint[2].z;

  (*ArmPoint).z=TempPoint[3].y;

}

void Change3DObjPosition(char order,struct _3DObjPosition *p)

{

  switch(order)

  {

   case 'w': {

         (*p).User_angelY -=0.002;      

         break;

        }

   case 'W': {

         if(pow ((*p).point.y-1, 2) + pow ((*p).point.x ,2) < 490000) (*p).point.y -= 1; 

         break;

        }

   case 'a': {

         (*p).User_angelZ -= 0.002;      

         break;

        } 

   case 'A': {

         if(pow ((*p).point.y, 2) + pow ((*p).point.x+1 ,2) < 490000) (*p).point.x += 1; 

         break;

        }

   case 's': {

         (*p).User_angelY +=0.002;      

         break;

        }

   case 'S': {

         if(pow ((*p).point.y+1, 2) + pow ((*p).point.x ,2) < 490000) (*p).point.y += 1; 

         break;

        }

   case 'd': {

         (*p).User_angelZ += 0.002;      

         break;

        }

   case 'D': {

         if(pow ((*p).point.y, 2) + pow ((*p).point.x-1 ,2) < 490000) (*p).point.x -= 1; 

         break;

        }

   case '6': {

         (*p).angelZ += 0.01;

         break;

        }

   case '8': {

         (*p).angelY += 0.01;

         break;

        }

   case '2': {

         (*p).angelY -= 0.01;

         break;

        }

   case '4': {

         (*p).angelZ -= 0.01;

         break;

        }

   case '9': {

         (*p).angelZ += 0.01;

         (*p).angelY += 0.01;

         break;

        }

   case '1': {

         (*p).angelZ -= 0.01;

         (*p).angelY -= 0.01;

         break;

         }

   case '7': {

         (*p).angelZ -= 0.01;

         (*p).angelY += 0.01;

         break;

        }

   case '3': {

         (*p).angelZ += 0.01;

         (*p).angelY -= 0.01;

         break;

        }

    default: ;

 }

}

float HalfWay(float angel1,float angel2)

{//該函數的求解範圍為0到150

 float HeadData,MilldData,EndData;

 float r[3];

 r[0] =0;

  HeadData = GetResult(r[0],angel1,angel2);

 r[1] =150;

 EndData = GetResult(r[1],angel1,angel2);

 r[2] =150;

 if(HeadData * EndData <0)

 {

  for(;;)

  {

   r[2] = (r[0] + r[1]) / 2;

   MilldData = GetResult(r[2],angel1,angel2);

   if(MilldData * MilldData < 0.00001) break;

   if(MilldData * HeadData >= 0)

   {

    HeadData = MilldData;

    r[0] = r[2];

   }else

   {

    EndData = MilldData;

    r[1] = r[2];

   }

  }

 }

 return r[2];

}

void ProccessBoxSet(int n,struct _ProccessBox *p)

{

 rectangle((*p).point.x -1, (*p).point.y -1, (*p).point.x + (*p).Longth +1, (*p).point.y +(*p).Higth +1);

 setfillstyle(1, (*p).MyColor);  

  bar((*p).point.x, (*p).point.y, (*p).point.x + (*p).Longth*n /100, (*p).point.y +(*p).Higth);

  (*p).MyText[10] = n % 10 +48;

  (*p).MyText[9] = n / 10 +48;

  setfillstyle(1, (*p).BackGColor);

  bar ((*p).point.x + (*p).Longth +10, (*p).point.y, (*p).point.x + (*p).Longth +10+104, (*p).point.y +(*p).Higth);

  outtextxy ((*p).point.x + (*p).Longth +10, (*p).point.y, (*p).MyText);

}

void GraphicsInit(int mode,int driver)

{

 registerbgidriver(EGAVGA_driver);

 initgraph(&driver, &mode, "//tc");   

}

float GetResult(float r,float angel1,float angel2)

{

 float result;

 struct _3DPoint point;

 point.x = r * cos(angel1) * cos(angel2);

 point.y = r * cos(angel1) * sin(angel2);

 point.z = r * sin(angel1);

 result = point.x * point.x + point.y * point.y + 50 * point.x

     - 50 * pow(point.x * point.x + point.y * point.y,0.5)

      + point.z * point.z - 1;

 return result;

}

tc 3D模型繪圖

繼續閱讀