📄 3dgraphics1_toushi.c
字号:
#include"stdio.h";
#include"graphics.h"
#include"math.h"
#include"dos.h"
#include"time.h"
/********************/
/* */
/* 二维图形 */
/* */
/********************/
typedef struct Point /* 点 */
{
int x;
int y;
}Point;
typedef struct Line /* 线 */
{
Point A;/*起点*/
Point B;/*终点*/
int color; /*颜色*/
}Line;
typedef struct Yuan /* 圆 */
{
Point o; /*圆心*/
int r; /*半径*/
int color;/*颜色*/
}Yuan;
typedef struct TuoYuan /*椭 圆*/
{
Point o;/*中心*/
int a; /*长轴*/
int b; /*短轴*/
int color;/*颜色*/
}TuoYuan;
typedef struct Qiu /* 球 */
{
Point o;/*中心*/
int r;
int color; /*颜色*/
}Qiu;
typedef struct Rect /* 矩形*/
{
Point LeftTop;
Point RightDown;
int color;
}Rect;
/********************************/
/**** 二维基本变换 ******/
/********************************/
/* 点的平移变换 */
void PinYi(int * x,int * y,int tx,int ty)
{
*x = *x + tx;
*y = *y + ty;
}
/* 点的旋转变换 */
void XuanZhuan(int * x,int * y,float q)
{
int m ;
int n;
float Q;
Q = (3.1415926/180)*q;
m = (*x);
n = (*y);
*x = m * cos(Q) - n * sin(Q);
*y = m * sin(Q) + n * cos(Q);
}
/* 绕任意点的旋转变换 */
void XuanZhuan_RY(int m,int n,int * x,int * y,float q)/* 绕(m,n)的旋转*/
{
PinYi(x,y,-m,-n);
XuanZhuan(x,y,q);
PinYi(x,y,m,n);
}
/* 点的放缩变换 */
void FangSuo(int * x,int * y,float sx,float sy)
{
*x =*x * sx;
*y =*y * sy;
}
/* 以任意点的放缩变换 */
void FangSuo_RY(int m,int n,int * x,int * y,float sx,float sy) /*以(m,n)为参考点*/
{
PinYi(x,y,-m,-n);
FangSuo(x,y,sx,sy);
PinYi(x,y,m,n);
}
/* 点的错切变换 */
void CuoQie(int * x,int * y,float q,int flag)
{
float Q;
Q = (3.1415926/180) * q;
if(flag==0)/* y为依赖轴 */
{
*x = *x + tan(Q)*(*y);
*y = *y;
}
else
{
*y = *y + tan(Q)*(*x);
*x = *x;
}
}
/* 以任意点的错切变换 */
void CuoQie_RY(int m,int n,int * x,int * y,float q,int flag) /* 以为(m,n)参考点*/
{
PinYi(x,y,-m,-n);
CuoQie(x,y,q,flag);
PinYi(x,y,m,n);
}
/***********************/
/* */
/* 三维图形 */
/* */
/***********************/
typedef struct Point3D /* 点 */
{
int x;
int y;
int z;
}Point3D;
typedef struct CFT /*长方体*/
{
Point3D A;/*正方体的中心*/
int a; /* 长 */
int b; /* 宽 */
int h; /* 高 */
}CFT;
typedef struct SLZ /*四棱锥*/
{
Point3D A;/*四棱锥底面的中心*/
int r; /* 底面边长 */
int h; /* 高 */
}SLZ;
typedef struct SLZU /*三棱柱*/
{
Point3D A;/*三棱锥底面的中心*/
int r; /* 底面边长 */
int h; /* 高 */
}SLZU;
/********************************/
/**** ******/
/**** 三维基本变换 ******/
/**** ******/
/********************************/
/* 点的平移变换 */
void PinYi3D(int * x,int * y,int * z,int tx,int ty,int tz)
{
*x = *x + tx;
*y = *y + ty;
*z = *z + tz;
}
/* 点旋转变换 */
void XuanZhuan3D(int * x,int * y,int *z,float q,int flag)
{
int m,n,t;
float Q;
m = (*x);
n = (*y);
t = (*z);
Q = (3.1415926/180)*q;
if(flag==1) /* 绕x轴旋转*/
{
*x = *x;
*y = n * cos(Q) - t * sin(Q);
*z = n * sin(Q) + t * cos(Q);
}
if(flag==2) /* 绕y轴旋转*/
{
*x = m * cos(Q) + t * sin(Q);
*y = *y;
*z = -m * sin(Q) + t * cos(Q);
}
if(flag==3) /* 绕z轴旋转*/
{
*x = m * cos(Q) - n * sin(Q);
*y = m * sin(Q) + n * cos(Q);
*z = *z;
}
}
/* 绕任意轴的点的旋转变换 */
void XuanZhuan3D_RY(int * x,int * y,int *z,float q,int i,int j,int k,int flag)
{
if(flag==1) /* 绕平行于X轴且过点(i,j,k)的直线的旋转*/
{
PinYi3D(x,y,z,-i,-j,-k);
XuanZhuan3D(x,y,z,q,flag);
PinYi3D(x,y,z,i,j,k);
}
if(flag==2) /* 绕平行于Y轴且过点(i,j,k)的直线的旋转*/
{
PinYi3D(x,y,z,-i,-j,-k);
XuanZhuan3D(x,y,z,q,flag);
PinYi3D(x,y,z,i,j,k);
}
if(flag==3) /* 绕平行于X轴且过点(i,j,k)的直线的旋转*/
{
PinYi3D(x,y,z,-i,-j,-k);
XuanZhuan3D(x,y,z,q,flag);
PinYi3D(x,y,z,i,j,k);
}
}
/* 点放缩变换 */
void FangSuo3D(int * x,int * y,int * z,float sx,float sy,float sz)
{
*x =*x * sx;
*y =*y * sy;
*z =*z * sz;
}
/* 以任意点的放缩变换 */
void FangSuo3D_RY(int m,int n,int t,int * x,int * y,int *z,float sx,float sy,float sz) /*以(m,n,t)为参考点*/
{
PinYi3D(x,y,z,-m,-n,-t);
FangSuo3D(x,y,z,sx,sy,sz);
PinYi3D(x,y,z,m,n,t);
}
/************************/
/* */
/* 三维坐标系的旋转变换 */
/* */
/************************/
void XuanZhuan3D_ZBX(int * x,int * y,int *z,float q,int flag)
{
int m,n,t;
float Q;
m = (*x);
n = (*y);
t = (*z);
Q = (3.1415926/180 )*q;
if(flag==1) /* x,y轴的旋转*/
{
*x = m * cos(Q) + n * sin(Q);
*y = m * cos(Q) - n * sin(Q);
*z = *z;
}
if(flag==2) /* y,z的轴旋转*/
{
*x = *x;
*y = n * cos(Q) + t * sin(Q);
*z = n * sin(Q) - t * cos(Q);
}
if(flag==3) /* z,x的轴旋转*/
{
*x = t * sin(Q) - m * cos(Q);
*y = *y;
*z = t * cos(Q) + m * sin(Q);
}
}
/************************************/
/* */
/* 三维空间点到二维平面点的透视投影 */
/* */
/************************************/
void Point3D_2D_TouShi(int * x,int * y,int * z,int d,float qx,float qy,float qz)/*投影方向为(qx,qy,qz)*/
{
/**/ XuanZhuan3D_RY(x,y,z,0,250,250,300,3);
XuanZhuan3D_ZBX(x,y,z,qx,1);
XuanZhuan3D_ZBX(x,y,z,qz,2);
if(d>(*z))
{
*x = (float)(d)*(*x)/(d-(*z)) + 800;
*y = (float)(d)*(*y)/(d-(*z)) + 100;
*x = 0.3 * (*x);
*y = 0.3 * (*y);
}
else
{
*x = -1;
*y = -1;
}
}
/***********************/
/* 直线的DDA 算法 */
/***********************/
void LineDDA(Point A,Point B,int color)
{
int x0,y0,x1,y1,x;
float dy,dx,y,m;
if(A.x<B.x)
{
x0 = A.x;
y0 = A.y;
x1 = B.x;
y1 = B.y;
dx = x1 - x0;
dy = y1 - y0;
m = dy/dx;
y = y0;
for(x = x0;x <= x1;x++)
{
putpixel(x,(int)(y + 0.5),color);
y = y + m;
}
}
if(A.x>B.x)
{
x0 = B.x;
y0 = B.y;
x1 = A.x;
y1 = A.y;
dx = x1 - x0;
dy = y1 - y0;
m = dy/dx;
y = y0;
for(x = x0;x <= x1;x++)
{
putpixel(x,(int)(y + 0.5),color);
y = y + m;
}
}
if(A.x==B.x)
{
if(A.y<=B.y)
{
x0 = A.x;
y0 = A.y;
while(y0<=B.y)
{
putpixel(x0,y0,color);
y0 = y0 +1;
}
}
else
{
x0 = B.x;
y0 = B.y;
while(y0<=A.y)
{
putpixel(x0,y0,color);
y0 = y0 +1;
}
}
}
}
/***********************/
/* 直线的中点算法 */
/***********************/
void MidPointLine(Point A,Point B,int color)
{
int dx,dy,incrE,incrNE,d,x,y,x0,y0,x1,y1;
if(A.x<B.x)
{
if((float)(B.y - A.y)/(B.x - A.x)<1.0)
{
x0 = A.x;
y0 = A.y;
x1 = B.x;
y1 = B.y;
dx = x1 - x0;
dy = y1 - y0;
d = dx - 2 * dy;
incrE = -2 * dy;
incrNE = 2 * (dx - dy);
x = x0,y = y0;
putpixel(x,y,color);
while(x <= x1)
{
if(d > 0)
d = d + incrE;
else
{
d = d + incrNE;
y++;
}
x++;
putpixel(x,y,color);
}
}
if((float)(B.y - A.y)/(B.x - A.x)>1.0)
{
x0 =A.y;
y0 =A.x;
x1 =B.y;
y1 =B.x;
dx = x1 - x0;
dy = y1 - y0;
d = dx - 2 * dy;
incrE = -2 * dy;
incrNE = 2 * (dx - dy);
x = x0,y = y0;
putpixel(y,x,color);
while(x <= x1)
{
if(d > 0)
d = d + incrE;
else
{
d = d + incrNE;
y++;
}
x++;
putpixel(y,x,color);
}
}
}
if(A.x>B.x)
{
if((float)(B.y - A.y)/(A.x - B.x)<1.0)
{
x0 = A.x;
y0 = A.y;
x1 = B.x;
y1 = B.y;
dx = x0 - x1;
dy = y1 - y0;
d = dx - 2 * dy;
incrE = -2 * dy;
incrNE = 2 * (dx - dy);
x = x0,y = y0;
putpixel(x,y,color);
while(x >= x1)
{
if(d > 0)
d = d + incrE;
else
{
d = d + incrNE;
y++;
}
x--;
putpixel(x,y,color);
}
}
if((float)(B.y - A.y)/(A.x - B.x)>1.0)
{
x0 =A.y;
y0 =A.x;
x1 =B.y;
y1 =B.x;
dx = x1 - x0;
dy = y0 - y1;
d = dx - 2 * dy;
incrE = -2 * dy;
incrNE = 2 * (dx - dy);
x = x0,y = y0;
putpixel(y,x,color);
while(x <= x1)
{
if(d > 0)
d = d + incrE;
else
{
d = d + incrNE;
y--;
}
x++;
putpixel(y,x,color);
}
}
}
if(A.x==B.x)
{
if(A.y<=B.y)
{
x0 = A.x;
y0 = A.y;
while(y0<=B.y)
{
putpixel(x0,y0,color);
y0 = y0 +1;
}
}
else
{
x0 = B.x;
y0 = B.y;
while(y0<=A.y)
{
putpixel(x0,y0,color);
y0 = y0 +1;
}
}
}
}
/*********************/
/* 圆的中点算法 */
/*********************/
/* 圆的8对称点的显示 */
void CirclePoints(int x0,int y0,int x,int y,int color)/* 圆心为(x0,y0);*/
{
putpixel(x,y,color); /*(x, y) */
putpixel(x0-y0+y,y0-x0+x,color); /*(y, x) */
putpixel(x0+y0-y,y0-x0+x,color); /*(-y, x) */
putpixel(2*x0-x,y,color); /*(-x, y) */
putpixel(x0-y0+y,y0+x0-x,color); /*(y, -x) */
putpixel(x,2*y0-y,color); /*(x, -y) */
putpixel(2*x0-x,2*y0-y,color); /*(-x,-y) */
putpixel(x0+y0-y,y0+x0-x,color); /*(-y,-x) */
}
/* 算法 1:圆的中点算法 */
void MidPointCircle_1(Point Q,int radius,int color)/* 圆心为 Q */
{
int x,y,x0,y0;
float d;
x0 = Q.x;
y0 = Q.y;
x = x0;
y = y0+radius;
d = 5.0/4.0 - radius;
CirclePoints(x0,y0,x,y,color);
while((y-y0)>(x-x0))
{
if(d<=0)
d = d + 2.0*(x-x0) + 3;
else
{
d = d + 2.0*((x-x0)-(y-y0)) + 5;
y--;
}
x++;
CirclePoints(x0,y0,x,y,color);
}
}
/* 算法 2 :消除了浮点运算的中点算法 */
void MidPointCircle_2(Point Q,int radius,int color)/* 圆心为(x0,y0);*/
{
int x,y,d,x0,y0;
x0 = Q.x;
y0 = Q.y;
x = x0;
y = y0 + radius;
d = 5 - 4*radius;
CirclePoints(x0,y0,x,y,color);
while((y-y0)>(x-x0))
{
if(d<=0)
d = d + 8*(x-x0) + 12;
else
{
d = d + 8*((x-x0)-(y-y0)) + 20;
y--;
}
x++;
CirclePoints(x0,y0,x,y,color);
}
}
/* 算法 3 :消除了乘法运算的中点算法 */
void MidPointCircle_3(Point Q,int radius,int color)/* 圆心为(x0,y0);*/
{
int x,y,d,deltaE,deltaSE,x0,y0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -