Minggu, 02 Februari 2020

Membuat Objek Kerucut 3D dengan Open GL

Membuat Kerucut 3D Gluth

Source Code
#include <math.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <stdio.h>


#define WIDTH 400
#define HEIGHT 400

typedef struct
{
float m[4][4];
} Matrix3D_t;

typedef struct
{
float v[4];
} Vector3D_t;

typedef struct
{
float x;
float y;
float z;
} Point3D_t;

typedef struct
{
float x;
float y;
} Point2D_t;

typedef struct
{
float r;
float g;
float b;
} Color_t;

Matrix3D_t createIdentity(void)
{
Matrix3D_t u;
int i, j;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++) u.m[i][j] = 0.;
u.m[i][i] = 1.;
}
return u;
}

Matrix3D_t operator *(Matrix3D_t a, Matrix3D_t b)
{
Matrix3D_t c;//c=a*b
int i, j, k;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
{
c.m[i][j] = 0;
for (k = 0; k < 4; k++) c.m[i][j] += a.m[i][k] * b.m[k][j];
}
return c;
}

Vector3D_t operator *(Matrix3D_t a, Vector3D_t b)
{
Vector3D_t c;//c=a*b
int i, j;
for (i = 0; i < 4; i++)
{
c.v[i] = 0;
for (j = 0; j < 4; j++) c.v[i] += a.m[i][j] * b.v[j];
}
return c;
}

Matrix3D_t rotationX(float theta)
{
Matrix3D_t rotate = createIdentity();
float cs = cos(theta);
float sn = sin(theta);
rotate.m[1][1] = cs;
rotate.m[1][2] = -sn;
rotate.m[2][1] = sn;
rotate.m[2][2] = cs;
return rotate;
}

Matrix3D_t rotationY(float theta)
{
Matrix3D_t rotate = createIdentity();
float cs = cos(theta);
float sn = sin(theta);
rotate.m[0][0] = cs;
rotate.m[0][2] = sn;
rotate.m[2][0] = -sn;
rotate.m[2][2] = cs;
return rotate;
}

Matrix3D_t rotationZ(float theta)
{
Matrix3D_t rotate = createIdentity();
float cs = cos(theta);
float sn = sin(theta);
rotate.m[0][0] = cs;
rotate.m[0][1] = -sn;
rotate.m[1][0] = sn;
rotate.m[1][1] = cs;
return rotate;
}

Point2D_t Vector2Point2D(Vector3D_t vec)
{
Point2D_t pnt;
pnt.x = vec.v[0];
pnt.y = vec.v[1];
return pnt;
}

Point3D_t Vector2Point3D(Vector3D_t vec)
{
Point3D_t pnt;
pnt.x = vec.v[0];
pnt.y = vec.v[1];
pnt.z = vec.v[2];
return pnt;
}

Vector3D_t Point2Vector(Point3D_t pnt)
{
Vector3D_t vec;
vec.v[0] = pnt.x;
vec.v[1] = pnt.y;
vec.v[2] = pnt.z;
vec.v[3] = 1.;
return vec;
}

float operator *(Vector3D_t a, Vector3D_t b)
{
float c;//c=a*b
int i;
c = 0;
for (i = 0; i < 3; i++)
{
c += a.v[i] * b.v[i];
}
return c;
}

Vector3D_t operator ^(Vector3D_t a, Vector3D_t b)
{
Vector3D_t c;//c=a*b
c.v[0] = a.v[1] * b.v[2] - a.v[2] * b.v[1];
c.v[1] = a.v[2] * b.v[0] - a.v[0] * b.v[2];
c.v[2] = a.v[0] * b.v[1] - a.v[1] * b.v[0];
c.v[3] = 1.;
return c;
}

Vector3D_t operator -(Vector3D_t v1, Vector3D_t v0)
{
Vector3D_t c;//c=v1-v0
c.v[0] = v1.v[0] - v0.v[0];
c.v[1] = v1.v[1] - v0.v[1];
c.v[2] = v1.v[2] - v0.v[2];
c.v[3] = 1.;
return c;
}

Vector3D_t operator -(Vector3D_t v)
{
Vector3D_t c;//c=-v
c.v[0] = -v.v[0];
c.v[1] = -v.v[1];
c.v[2] = -v.v[2];
c.v[3] = 1.;
return c;
}

void setColor(float red, float green, float blue)
{
glColor3f(red, green, blue);
}

void setColor(Color_t col)
{
glColor3f(col.r, col.g, col.b);
}

void drawDot(float x, float y)
{
glBegin(GL_POINTS);
glVertex2f(x, y);
glEnd();
}

void drawDot(Point2D_t p)
{
glBegin(GL_POINTS);
glVertex2f(p.x, p.y);
glEnd();
}

void drawLine(float x1, float y1, float x2, float y2)
{
glBegin(GL_LINES);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
glEnd();
}

void drawLine(Point2D_t p1, Point2D_t p2)
{
drawLine(p1.x, p1.y, p2.x, p2.y);
}

//n: number of points
void drawPolyline(Point2D_t pnt[], int n)
{
int i;
glBegin(GL_LINE_STRIP);
for (i = 0; i < n; i++)
{
glVertex2f(pnt[i].x, pnt[i].y);
}
glEnd();
}

//n: number of vertices
void drawPolygon(Point2D_t pnt[], int n)
{
int i;
glBegin(GL_LINE_LOOP);
for (i = 0; i < n; i++)
{
glVertex2f(pnt[i].x, pnt[i].y);
}
glEnd();
}

void fillPolygon(Point2D_t pnt[], int n, Color_t color)
{
int i;
setColor(color);
glBegin(GL_POLYGON);
for (i = 0; i < n; i++)
{
glVertex2f(pnt[i].x, pnt[i].y);
}
glEnd();
}

void gradatePolygon(Point2D_t pnt[], int num, Color_t col[])
{
int i;
glBegin(GL_POLYGON);
for (i = 0; i < num; i++)
{
setColor(col[i]);
glVertex2f(pnt[i].x, pnt[i].y);
}
glEnd();
}

//////////// End of OpenGL drawShape Functions ver 1 ////////////
void drawcharX(float x, float y)
{
drawLine(x, y, x + 10, y + 12);
drawLine(x, y + 12, x + 10, y);
}

void drawcharY(float x, float y)
{
drawLine(x + 5, y, x + 5, y + 7);
drawLine(x, y + 12, x + 5, y + 7);
drawLine(x + 10, y + 12, x + 5, y + 7);
}

void drawcharZ(float x, float y)
{
drawLine(x, y + 12, x + 10, y + 12);
drawLine(x + 10, y + 12, x, y);
drawLine(x, y, x + 10, y);
}

typedef struct
{
int numofVertices; //in the face
short int pnt[50];
Color_t col;
} Face_t;

typedef struct
{
int numofVertices; //of the object
Point3D_t pnt[1600];
Color_t col[1600];
int numofFaces; //of the object
Face_t fc[1000];
} Object3D_t;

void draw3D(Object3D_t obyek, Matrix3D_t mat)
{
Vector3D_t vec[32], vecbuff[32];
Vector3D_t vecNormal;
Point2D_t p[50];
int i, j;
for (i = 0; i < obyek.numofVertices; i++)
{
vec[i] = Point2Vector(obyek.pnt[i]);
vec[i] = mat * vec[i];
}
setColor(1, 0, 0);
for (i = 0; i < obyek.numofFaces; i++)
{
for (j = 0; j < obyek.fc[i].numofVertices; j++)
vecbuff[j] = vec[obyek.fc[i].pnt[j]];
vecNormal = (vecbuff[1] - vecbuff[0]) ^ (vecbuff[2] - vecbuff[0]);
if (vecNormal.v[2] < 0)
{
for (j = 0; j < obyek.fc[i].numofVertices; j++)
{
p[j] = Vector2Point2D(vecbuff[j]);
}
drawPolygon(p, obyek.fc[i].numofVertices);
}
}
setColor(0, 1, 1);
for (i = 0; i < obyek.numofFaces; i++)
{
for (j = 0; j < obyek.fc[i].numofVertices; j++)
vecbuff[j] = vec[obyek.fc[i].pnt[j]];
vecNormal = (vecbuff[1] - vecbuff[0]) ^ (vecbuff[2] - vecbuff[0]);
if (vecNormal.v[2] >= 0)
{
for (j = 0; j < obyek.fc[i].numofVertices; j++)
{
p[j] = Vector2Point2D(vecbuff[j]);
}
drawPolygon(p, obyek.fc[i].numofVertices);
}
}
}

void draw3D(Object3D_t obyek, Matrix3D_t mat, Color_t col)
{
Vector3D_t vec[1600], vecbuff[50];
Vector3D_t vecNormal;
Point2D_t p[50];
int i, j;
for (i = 0; i < obyek.numofVertices; i++)
{
vec[i] = Point2Vector(obyek.pnt[i]);
vec[i] = mat * vec[i];
}
setColor(col);
for (i = 0; i < obyek.numofFaces; i++)
{
for (j = 0; j < obyek.fc[i].numofVertices; j++)
vecbuff[j] = vec[obyek.fc[i].pnt[j]];
vecNormal = (vecbuff[1] - vecbuff[0]) ^ (vecbuff[2] - vecbuff[0]);
if (vecNormal.v[2] >= 0)
{
for (j = 0; j < obyek.fc[i].numofVertices; j++)
{
p[j] = Vector2Point2D(vecbuff[j]);
}
drawPolygon(p, obyek.fc[i].numofVertices);
}
}
}

void makeKerucut(Object3D_t& kerucut, int n, float h, float r)
{
float a = 6.28 / n;
int i;
kerucut.pnt[0].x = 0;
kerucut.pnt[0].y = h;
kerucut.pnt[0].z = 0;
for (i = 1; i <= n; i++) {
kerucut.pnt[i].x = r*cos(i*a);
kerucut.pnt[i].y = 0;
kerucut.pnt[i].z = r*sin(i*a);
}
for (i = 0; i<n; i++) {
kerucut.fc[i].numofVertices = 3;
kerucut.fc[i].pnt[0] = 0;
kerucut.fc[i].pnt[1] = i + 2;
kerucut.fc[i].pnt[2] = i + 1;
if (i == (n - 1)) kerucut.fc[i].pnt[1] = 1;
}
kerucut.fc[n].numofVertices = n;
for (i = 0; i<n; i++) kerucut.fc[n].pnt[i] = i + 1;
kerucut.numofVertices = n + 1;
kerucut.numofFaces = n + 1;
}

void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(1000, timer, 0);
}

void Initialize()
{
glClearColor(0.5, 0.5, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1 * (WIDTH / 2), WIDTH / 2, -1 * (HEIGHT / 2), HEIGHT / 2);
}
float sudut = 0.0;

void userdraw(void)
{
Matrix3D_t tilting = rotationX(170)*rotationY(sudut);
setColor(0, 1, 0);
Object3D_t kerucut;
makeKerucut(kerucut, 20, 100, 50);
setColor(1, 1, 1);
draw3D(kerucut, tilting);
sudut++;
if (sudut >= 360.0) sudut = 0.0;
glFlush();
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT);
userdraw();
glutSwapBuffers();
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(400, 400);
glutInitWindowPosition(200, 200);
glutCreateWindow("Kerucut");
Initialize();
glutDisplayFunc(display);
glutTimerFunc(1, timer, 0);
glutMainLoop();
return 0;
}


Hasil Run

Artikel Terkait


EmoticonEmoticon