">[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;
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZugzYMhzN5ADN4MjM4ITMfBzLcFjMvwFOwATMwIzLcRnbl1GajFGd0F2LcRXZu5ibkN3YukGavw1LcpDc0RHaiojIsJye.gif)