#define GLUT_DISABLE_ATEXIT_HACK
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#define SHIFT 0.7
#define MAX 10
struct Point
{
int x;
int y;
};
struct D3Point
{
int x;
int y;
int z;
};
void LineDDA(int x0, int y0, int x1, int y1)
{
float dy, dx, x, y, m;
if(x0 > x1)
{
int temp;
temp = x0;
x0 = x1;
x1 = temp;
temp = y0;
y0 = y1;
y1 = temp;
}
dx = x1 - x0;
dy = y1 - y0;
if(dx != 0)
{
m = dy / dx;
if(m <= 1 && m >= -1)
{
y = y0;
for(int i = 0; i <= (int)fabs((float)(x1 - x0)); i++)
{
glVertex2i(i + x0, int(y + 0.5));
y += m;
}
}
if(m >= 1 || m <= -1)
{
m = 1 / m;
x = x0;
for(int j = 0; j <= (int)fabs((float)(y1 - y0)); j++)
{
glVertex2i(int(x + 0.5), j + y0);
x += m;
}
}
}
else
{
int x = x0, y;
y = (y0 <= y1) ? y0 : y1;
int d = fabs((double)(y0 - y1));
while(d >= 0)
{
glVertex2i(x, y);
y++;
d--;
}
}
}
void LineDDA1(int x0, int y0, int x1, int y1)
{
float dy, dx, x, y, m;
if(x0 > x1)
{
int temp;
temp = x0;
x0 = x1;
x1 = temp;
temp = y0;
y0 = y1;
y1 = temp;
}
dx = x1 - x0;
dy = y1 - y0;
if(dx != 0)
{
m = dy / dx;
if(m <= 1 && m >= -1)
{
y = y0;
for(x = x0; x <= x1; x++)
{
glVertex2i(x, int(y + 0.5));
y += m;
}
}
if(m >= 1 || m <= -1)
{
m = 1 / m;
x = x0;
for(y = y0; y <= y1; y++)
{
glVertex2i(int(x + 0.5), y);
x += m;
}
}
}
else
{
int x = x0, y;
y = (y0 <= y1) ? y0 : y1;
int d = fabs((double)(y0 - y1));
while(d >= 0)
{
glVertex2i(x, y);
y++;
d--;
}
}
}
void Draw3D(D3Point tp3[], int npt)
{
Point tp2[MAX];
int i;
for(i = 0; i < npt; i++)
{
tp2[i].x = tp3[i].x - SHIFT * tp3[i].z;
tp2[i].y = tp3[i].y - SHIFT * tp3[i].z;
}
for(i = 0; i < npt; i++)
{
tp2[i].x = 200 + tp2[i].x;
tp2[i].y = 200 + tp2[i].y;
}
for(i = 0; i < npt - 1; i++)
{
LineDDA(tp2[i].x, tp2[i].y, tp2[i + 1].x, tp2[i + 1].y);
}
LineDDA(tp2[4].x, tp2[4].y, tp2[7].x, tp2[7].y);
LineDDA(tp2[1].x, tp2[1].y, tp2[6].x, tp2[6].y);
LineDDA(tp2[3].x, tp2[3].y, tp2[0].x, tp2[0].y);
LineDDA(tp2[7].x, tp2[7].y, tp2[2].x, tp2[2].y);
LineDDA(tp2[5].x, tp2[5].y, tp2[0].x, tp2[0].y);
}
void Draw3D_R(D3Point tp3[], int npt)
{
Point tp2[MAX];
int i;
for(i = 0; i < npt; i++)
{
tp2[i].x = tp3[i].x - SHIFT * tp3[i].z;
tp2[i].y = tp3[i].y - SHIFT * tp3[i].z;
}
for(i = 0; i < npt; i++)
{
tp2[i].x = 200 + tp2[i].x;
tp2[i].y = 200 + tp2[i].y;
}
for(i = 0; i < npt - 1; i++)
{
LineDDA(tp2[i].x, tp2[i].y, tp2[i + 1].x, tp2[i + 1].y);
}
LineDDA(tp2[4].x, tp2[4].y, tp2[7].x, tp2[7].y);
LineDDA(tp2[1].x, tp2[1].y, tp2[6].x, tp2[6].y);
LineDDA(tp2[3].x, tp2[3].y, tp2[0].x, tp2[0].y);
LineDDA(tp2[7].x, tp2[7].y, tp2[2].x, tp2[2].y);
LineDDA(tp2[5].x, tp2[5].y, tp2[0].x, tp2[0].y);
}
void MultiplyMatrixAxB(int a[4][4], int b[4][4], int c[4][4], int npt)
{
int i, j, k, sum;
for(i = 0; i < npt; i++)
{
for(k = 0; k < 4; k++)
{
sum = 0;
for(j = 0; j < 4; j++)
{
sum += a[i][j] * b[j][k];
}
c[i][k] = sum;
}
}
}
void Translation(D3Point tp3[], D3Point Rtp3[], int npt, int deltax, int deltay, int deltaz)
{
int ta = 0, tb = 0, tc = 0, td = 0, te = 0, tf = 0, tj = 0, th = 0,
ti = 0, tl = 0, tm = 0, tn = 0, tp = 0, tq = 0, tr = 0, ts = 0;
ta = te = ti = ts = 1;
tl = deltax;
tm = deltay;
tn = deltaz;
int trans3d[4][4] = {ta, tb, tc, tp, td, te, tf, tq, tj, th, ti, tr, tl, tm, tn, ts};
int pnt3d[1][4] = {0, 0, 0, 1};
int i;
int result[1][4] = {0};
for(i = 0; i < npt; i++)
{
pnt3d[0][0] = tp3[i].x;
pnt3d[0][1] = tp3[i].y;
pnt3d[0][2] = tp3[i].z;
MultiplyMatrixAxB(pnt3d, trans3d, result, 1);
Rtp3[i].x = result[0][0];
Rtp3[i].y = result[0][1];
Rtp3[i].z = result[0][2];
}
}
void TranslationSegment()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POINTS);
LineDDA1(10, 200, 400, 200);
LineDDA1(395, 195, 400, 200);
LineDDA1(395, 205, 400, 200);
LineDDA1(200, 50, 200, 450);
LineDDA1(195, 445, 200, 450);
LineDDA1(205, 445, 200, 450);
LineDDA1(10, 10, 400, 400);
LineDDA1(10, 10, 15, 10);
LineDDA1(10, 10, 10, 15);
int npt = 8;
D3Point srcdata[8] = {{0, 0, 0}, {50, 0, 0}, {50, 50 ,0}, {0, 50, 0}, {0, 50, 50}, {0, 0, 50}, {50, 0, 50}, {50, 50, 50}};
D3Point objdata[8];
Translation(srcdata, objdata, npt, 100, 0, 0);
Draw3D(srcdata, npt);
glColor3f(1.0, 0.0, 0.0);
Draw3D_R(objdata, npt);
glEnd();
glFlush();
}
void main(int argc, char * argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(50, 100);
glutInitWindowSize(500, 500);
glutCreateWindow("三维平移");
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 500.0, 0.0, 500.0);
glutDisplayFunc(TranslationSegment);
glutMainLoop();
}