Grafika komputer Membuat Perubahan Bentuk Rumah dengan Morphing

Membuat Perubahan Bentuk Rumah dengan Morphing
clip_image002clip_image004
Oke , pada postingan kali ini aku akan menshare projek morphing yang merupakan implementasi dari materi
#include<windows.h>
#include <stdio.h>
#include <math.h>
#include <GL/glut.h>
#ifndef M_PI
#define M_PI 3.141592653589793
#endif
typedef struct {
float x;
float y;
} point2D_t;
typedef struct {
float r;
float g;
float b;
} color_t;
/**OBJEK 1*/
//81 titik
point2D_t rumah1_bangunan[]={
{-50,-50} , {-50,-45} , {-50,-40} , {-50,-35} , {-50,-30} , {-50,-25} , {-50,-20} , {-50,-15} , {-50,-10} , {-50,-5} , {-50,0} , {-50,5} , {-50,10} , {-50,15} , {-50,20} , {-50,25} , {-50,30} , {-50,35} , {-50,40} , {-50,45}
,{-50,50} , {-45,50} , {-40,50} , {-35,50} , {-30,50} , {-25,50} , {-20,50} , {-15,50} , {-10,50} , {-5,50} , {0,50} , {5,50} , {10,50} , {15,50} , {20,50} , {25,50} , {30,50} , {35,50} , {40,50} , {45,50}
,{50,50} , {50,45} , {50,40} , {50,35} , {50,30} , {50,25} , {50,20} , {50,15} , {50,10} , {50,5} , {50,0} , {50,-5} , {50,-10} , {50,-15} , {50,-20} , {50,-25} , {50,-30} , {50,-35} , {50,-40} , {50,-45}
,{50,-50,} , {45,-50} , {40,-50} , {35,-50} , {30,-50} , {25,-50} , {20,-50} , {15,-50} , {10,-50} , {5,-50} , {0,-50} , {-5,-50}, {-10,-50}, {-15,-50}, {-20,-50}, {-25,-50}, {-30,-50}, {-35,-50}, {-40,-50}, {-45,-50}
,{-50,-50}
};
//41 titik
point2D_t rumah1_pintu_1[] = {
{-20,-50} , {-20,-45} , {-20,-40} , {-20,-35} , {-20,-30} , {-20,-25} , {-20,-20} , {-20,-15} , {-20,-10} , {-20,-5} , {-20,0} , {-20,5}
,{-20,10} , {-15,10} , {-10,10} , {-5,10} , {0,10} , {5,10} , {10,10} , {15,10}
,{20,10} , {20,5} , {20,0} , {20,-5} , {20,-10} , {20,-15} , {20,-20} , {20,-25} , {20,-30} , {20,-35} , {20,-40}, {20,-45}
,{20,-50} , {15,-50} , {10,-50} , {5,-50} , {0,-50} , {-5,-50} , {-10,-50} , {-15,-50}
,{-20,-50}
};
//20 + 20 + 20 + 1 = 61 titik
point2D_t rumah1_atap[] = {
{-50,50} , {-45,50} , {-40,50} , {-35,50} , {-30,50} , {-25,50} , {-20,50} , {-15,50} , {-10,50} , {-5,50} , {0,50} , {5,50} , {10,50} , {15,50} , {20,50} , {25,50} , {30,50} , {35,50} , {40,50} , {45,50}
,{49.631,50} , {47.730,53.169} , {44.985,56.865} , {41.606,61.722} , {38.491,65.999} , {36.009,69.431} , {33.475,73.021} , {31.046,76.453} , {28.459,80.043} , {25.608,84.162} , {22.387,88.597} , {19.113,93.190} , {15.840,97.837} , {13.464,101.110} , {11.299,104.173} , {8.659,107.869} , {6.019, 111.564} , {3.590, 114.838} , {1.426, 118.059} , {0,120.000}
,{0,120.000} , {-1.426, 118.059 } , {-3.590, 114.838} , {-6.019, 111.564 } , {-8.659,107.869} , {-11.299,104.173} , {-13.464,101.110} , {-15.840,97.837} , {-19.113,93.190} , {-22.387,88.597} , {-25.608,84.162} , {-28.459,80.043} , {-31.046,76.453} , {-33.475,73.021} , {-36.009,69.431} , {-38.491,65.999} , {-41.606,61.722} , {-44.985,56.865} , {-47.730,53.169} , {-49.631,50.529}
,{-50,50}
};
//11 titik
point2D_t rumah1_jendela_1[] = {
{-40,40} , {-10,40} , {-10,20} , {-40,20}
,{-40,40} , {-25,40} , {-25,20} , {-10,20} , {-10,30} , {-40,30} , {-40,40}
};
//11 titik
point2D_t rumah1_jendela_2[] = {
{40,40} , {10,40} , {10,20} , {40,20}
,{40,40} , {25,40} , {25,20} , {10,20} , {10,30} , {40,30} , {40,40}
};
//11 titik
point2D_t rumah1_jendela_3[] = {
{40,40} , {10,40} , {10,20} , {40,20}
,{40,40} , {25,40} , {25,20} , {10,20} , {10,30} , {40,30} , {40,40}
};
//11 titik
point2D_t rumah1_jendela_4[] = {
{-40,40} , {-10,40} , {-10,20} , {-40,20}
,{-40,40} , {-25,40} , {-25,20} , {-10,20} , {-10,30} , {-40,30} , {-40,40}
};
/**OBJEK 2*/
point2D_t rumah2_bangunan[]={
{-85,-50} , {-85,-45} , {-85,-40} , {-85,-35} , {-85,-30} , {-85,-25} , {-85,-20} , {-85,-15} , {-85,-10} , {-85,-5} , {-85,0} , {-85,5} , {-85,10} , {-85,15} , {-85,20} , {-85,25} , {-85,30} , {-85,35} , {-85,40} , {-85,45}
,{-85,50} , {-45,50} , {-40,50} , {-35,50} , {-30,50} , {-25,50} , {-20,50} , {-15,50} , {-10,50} , {-5,50} , {0,50} , {5,50} , {10,50} , {15,50} , {20,50} , {25,50} , {30,50} , {35,50} , {40,50} , {45,50}
,{85,50} , {85,45} , {85,40} , {85,35} , {85,30} , {85,25} , {85,20} , {85,15} , {85,10} , {85,5} , {85,0} , {85,-5} , {85,-10} , {85,-15} , {85,-20} , {85,-25} , {85,-30} , {85,-35} , {85,-40} , {85,-45}
,{85,-50,} , {45,-50} , {40,-50} , {35,-50} , {30,-50} , {25,-50} , {20,-50} , {15,-50} , {10,-50} , {5,-50} , {0,-50} , {-5,-50}, {-10,-50}, {-15,-50}, {-20,-50}, {-25,-50}, {-30,-50}, {-35,-50}, {-40,-50}, {-45,-50}
,{-85,-50}
};
point2D_t rumah2_pintu_1[]={
{20,-50} , {20,30} , {20,30} , {20,30} , {20,30} , {20,30} , {20,30} , {20,30} , {20,30} , {20,30} , {20,30} , {20,30}
,{20,30} , {60,30} , {60,30} , {60,30} , {60,30} , {60,30} , {60,30} , {60,30}
,{60,30} , {60,-50} , {60,-50} , {60,-50} , {60,-50} , {60,-50} , {60,-50} , {60,-50} , {60,-50} , {60,-50} , {60,-50}, {60,-50}
,{60,-50} , {20,-50} , {20,-50} , {20,-50} , {20,-50} , {20,-50} , {20,-50} , {20,-50}
,{20,-50}
};
//20 + 20 + 20 + 1 = 61 titik
point2D_t rumah2_atap[] = {
{-105,50} , {-55,90} , {55,90} , {105,50} , {-30,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50}
,{0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50}
,{0,50} , {0,50 } , {0,50} , {0,50 } , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50} , {0,50}
,{-105,50}
};
//11 titik
point2D_t rumah2_jendela_1[] = {
{-69.375,1.864} , {-69.375,28.136} , {-52.734,28.136} , {-52.734,1.864}
,{-69.375,1.864} , {-61.055,1.864} , {-61.055,28.136} , {-52.734,28.136} , {-52.734,15.000} , {-69.375,15.000} , {-69.375,1.864}
};
point2D_t rumah2_jendela_2[]={
{-41.641,1.864} , {-41.641,28.136} , {-25.000,28.136} , {-25.000,1.864}
,{-41.641,1.864} , {-33.320,1.864} , {-33.320,28.136} , {-25.000,28.136} , {-25.000,15.000} , {-41.641,15.000} , {-41.641,1.864}
};
point2D_t rumah2_jendela_3[]={
{-69.375,-28.787} , {-69.375,-2.515} , {-52.734,-2.515} , {-52.734,-28.787}
,{-69.375,-28.787} , {-61.055,-28.787} , {-61.055,-2.515} , {-52.734,-2.515} , {-52.734,-15.651} , {-69.375,-15.651} , {-69.375,-28.787}
};
point2D_t rumah2_jendela_4[]={
{-41.641,-28.787} , {-41.641,-2.515} , {-25.000,-2.515} , {-25.000,-28.787}
,{-41.641,-28.787} , {-33.320,-28.787} , {-33.320,-2.515} , {-25.000,-2.515} , {-25.000,-15.651} , {-41.641,-15.651} , {-41.641,-28.787}
};
////////////// OpenGL drawShape Functions ver 1 /////////////////
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 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++) {
glColor3f(0,0,1);
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();
}
// The function fillPolygon can fills only convex polygons
//n: number of vertices
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();
}
// The function gradatePolygon can fills only convex polygons
// The vertices will be painted with corresponding given colors.
// The points inside the polygon will be painted with the mixed color.
//n: number of vertices
void gradatePolygon(point2D_t pnt[],color_t col[],int num)
{
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 userdraw(void);
void display(void)
{
glClear( GL_COLOR_BUFFER_BIT);
userdraw();
glutSwapBuffers();
}
//////////////////////////////////////////////////////////////////
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 drawAxes(void)
{
drawLine(-310,0,310,0);drawLine(310,0,300,5);drawLine(310,0,300,-5);
drawcharX(300,-20);
drawLine(0,-230,0,230);drawLine(0,230,5,220);drawLine(0,230,-5,220);
drawcharY(-20,220);
}
//////////////////////////////////////////////////////////////////
point2D_t interpolate(point2D_t a, point2D_t b, float r)
{
// 0.0<=r<=1.0 AC:CB=r:(1-r)
if (r<0.0) r=0.0;
if (1.0<r) r=1.0;
point2D_t c;
float r1=1.0-r;
c.x=r1*a.x+r*b.x;
c.y=r1*a.y+r*b.y;
return c;
}
void makeSquare(point2D_t p[],float r)
{
int i,j;
for (i=0;i<5;i++) {
p[5*i].x=r*cos((0.5*i+0.25)*M_PI);
p[5*i].y=r*sin((0.5*i+0.25)*M_PI);
}
for (i=0;i<4;i++) {
for (j=1;j<5;j++) {
p[5*i+j]=interpolate(p[5*i],p[5*i+5],0.2*j);
}
}
}
void makePentagram(point2D_t p[],float r)
{
int i,j;
for (i=0;i<6;i++) {
p[4*i].x=r*cos((0.8*i+0.5)*M_PI);
p[4*i].y=r*sin((0.8*i+0.5)*M_PI);
}
for (i=0;i<5;i++) {
for (j=1;j<4;j++) {
p[4*i+j]=interpolate(p[4*i],p[4*i+4],0.25*j);
}
}
}
void make20gram(point2D_t p[],float r)
{
int i;
for (i=0;i<20;i++) {
p[i].x=r*cos(i*M_PI*18/19.);
p[i].y=r*sin(i*M_PI*18/19.);
}
}
void makeCircle(point2D_t lingkar[],int xp,int yp)
{
float r;
for(int i=0;i<360;i++){
float srad=(float)i/57.3;
r = 17;
lingkar[i].x=xp+r*cos(srad);
lingkar[i].y=yp+r*sin(srad);
}
}
void userdraw(void)
{
//kecepatan dari perubahan
static int tick=0;
int disp=(tick/100)%4;
float rtick=(tick%100)/80.;
//buat shape penampung rumah 1
point2D_t shape1[81]; //rumah1_bangunan
point2D_t shape2[41]; //rumah1_pintu1
point2D_t shape3[61]; //rumah1_atap
point2D_t shape4[11]; //rumah1_jendela1
point2D_t shape5[11]; //rumah1_jendela2
point2D_t shape6[11]; //rumah1_jendela3
point2D_t shape7[11]; //rumah1_jendela4
/**
drawPolyline(rumah2_bangunan,81); //rumah1_bangunan
drawPolyline(rumah2_pintu_1,41); //rumah1_pintu1
drawPolyline(rumah2_atap,61); //rumah1_atap
drawPolyline(rumah2_jendela_1,11); //rumah1_jendela1
drawPolyline(rumah2_jendela_2,11); //rumah1_jendela2
drawPolyline(rumah2_jendela_3,11); //rumah1_jendela3
drawPolyline(rumah2_jendela_4,11); //rumah1_jendela4
**/
int i;
setColor(1,1,1);
switch(disp) {
case 0:
for(i=0;i<81;i++) { //rumah1_bangunan
shape1[i]=interpolate(rumah1_bangunan[i],rumah1_bangunan[i],rtick);
}
for(i=0;i<41;i++) { //rumah1_pintu1
shape2[i]=interpolate(rumah1_pintu_1[i],rumah1_pintu_1[i],rtick);
}
for(i=0;i<61;i++) { //rumah1_atap
shape3[i]=interpolate(rumah1_atap[i],rumah1_atap[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela
shape4[i]=interpolate(rumah1_jendela_1[i],rumah1_jendela_1[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela1
shape5[i]=interpolate(rumah1_jendela_2[i],rumah1_jendela_2[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela2
shape6[i]=interpolate(rumah1_jendela_3[i],rumah1_jendela_3[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela2
shape7[i]=interpolate(rumah1_jendela_4[i],rumah1_jendela_4[i],rtick);
}
drawPolyline(shape1,81); //rumah1_bangunan
drawPolyline(shape2,41); //rumah1_pintu1
drawPolyline(shape3,61); //rumah1_atap
drawPolyline(shape4,11); //rumah1_jendela1
drawPolyline(shape5,11); //rumah1_jendela2
drawPolyline(shape6,11); //rumah1_jendela3
drawPolyline(shape7,11); //rumah1_jendela4
break;
case 1:
for(i=0;i<81;i++) { //rumah1_bangunan
shape1[i]=interpolate(rumah1_bangunan[i],rumah2_bangunan[i],rtick);
}
for(i=0;i<41;i++) { //rumah1_pintu1
shape2[i]=interpolate(rumah1_pintu_1[i],rumah2_pintu_1[i],rtick);
}
for(i=0;i<61;i++) { //rumah1_atap
shape3[i]=interpolate(rumah1_atap[i],rumah2_atap[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela
shape4[i]=interpolate(rumah1_jendela_1[i],rumah2_jendela_1[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela1
shape5[i]=interpolate(rumah1_jendela_2[i],rumah2_jendela_2[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela2
shape6[i]=interpolate(rumah1_jendela_3[i],rumah2_jendela_3[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela2
shape7[i]=interpolate(rumah1_jendela_4[i],rumah2_jendela_4[i],rtick);
}
drawPolyline(shape1,81); //rumah1_bangunan
drawPolyline(shape2,41); //rumah1_pintu1
drawPolyline(shape3,61); //rumah1_atap
drawPolyline(shape4,11); //rumah1_jendela1
drawPolyline(shape5,11); //rumah1_jendela2
drawPolyline(shape6,11); //rumah1_jendela3
drawPolyline(shape7,11); //rumah1_jendela4
break;
case 2:
for(i=0;i<81;i++) { //rumah1_bangunan
shape1[i]=interpolate(rumah2_bangunan[i],rumah2_bangunan[i],rtick);
}
for(i=0;i<41;i++) { //rumah1_pintu1
shape2[i]=interpolate(rumah2_pintu_1[i],rumah2_pintu_1[i],rtick);
}
for(i=0;i<61;i++) { //rumah1_atap
shape3[i]=interpolate(rumah2_atap[i],rumah2_atap[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela
shape4[i]=interpolate(rumah2_jendela_1[i],rumah2_jendela_1[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela1
shape5[i]=interpolate(rumah2_jendela_2[i],rumah2_jendela_2[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela2
shape6[i]=interpolate(rumah2_jendela_3[i],rumah2_jendela_3[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela2
shape7[i]=interpolate(rumah2_jendela_4[i],rumah2_jendela_4[i],rtick);
}
drawPolyline(shape1,81); //rumah1_bangunan
drawPolyline(shape2,41); //rumah1_pintu1
drawPolyline(shape3,61); //rumah1_atap
drawPolyline(shape4,11); //rumah1_jendela1
drawPolyline(shape5,11); //rumah1_jendela2
drawPolyline(shape6,11); //rumah1_jendela3
drawPolyline(shape7,11); //rumah1_jendela4
break;
case 3:
for(i=0;i<81;i++) { //rumah1_bangunan
shape1[i]=interpolate(rumah2_bangunan[i],rumah1_bangunan[i],rtick);
}
for(i=0;i<41;i++) { //rumah1_pintu1
shape2[i]=interpolate(rumah2_pintu_1[i],rumah1_pintu_1[i],rtick);
}
for(i=0;i<61;i++) { //rumah1_atap
shape3[i]=interpolate(rumah2_atap[i],rumah1_atap[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela
shape4[i]=interpolate(rumah2_jendela_1[i],rumah1_jendela_1[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela1
shape5[i]=interpolate(rumah2_jendela_2[i],rumah1_jendela_2[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela2
shape6[i]=interpolate(rumah2_jendela_3[i],rumah1_jendela_3[i],rtick);
}
for(i=0;i<11;i++) { //rumah1_jendela2
shape7[i]=interpolate(rumah2_jendela_4[i],rumah1_jendela_4[i],rtick);
}
drawPolyline(shape1,81); //rumah1_bangunan
drawPolyline(shape2,41); //rumah1_pintu1
drawPolyline(shape3,61); //rumah1_atap
drawPolyline(shape4,11); //rumah1_jendela1
drawPolyline(shape5,11); //rumah1_jendela2
drawPolyline(shape6,11); //rumah1_jendela3
drawPolyline(shape7,11); //rumah1_jendela4
break;
default:
break;
}
tick++;
}//userdraw
int main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode ( GLUT_DOUBLE | GLUT_RGB );
glutInitWindowPosition(0,0);
glutInitWindowSize(500,500);
glutCreateWindow ("Rumah to Kastil");
glClearColor(0.0, 0.0, 0.0, 0.0);
gluOrtho2D(-300., 300., -300.0, 300.0);
// Define the dimensions of the Orthographic Viewing Volume
glutIdleFunc(display); // idle event call back
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
Dari listing program diatas saya membuat tiap-tiap objek dari rumah 1 dan rumah 2 dengan mencatat titik-titik dari objek tersebut. Objek dari rumah 1 dan rumah 2 harus lah sama karena agar terlihat seperti adanya perubahan bukan seperti muncul-muncul tiba. Setelah itu baru di proses di bagian fungsi userdraw(). Bagian-bagian dari userdraw mungkin sudah jelas karena telah aku komentar. Semoga bisa menjadi inspirasi ? .
 
Penulis
Ilham Akbar A.H