컴퓨터 그래픽스 레포트
총 5가지 도형의 구현코드입니다.
-Bezier Spline
-Hermite Spline
-Koch Curve
-Sierpimsk Gasket
-Mamdel Brot
최근에 다큐멘터리에서 Mamdel Brot에 대한 내용을 보았는데 새삼 10여년 전에 저런 코드를 한번 구현해 봤다는게 신기하네요^^
지금보니 소스코드가 뭔 소린지 모르겠네요 ㅎㅎㅎ
어쩌자고 저렇게 구현했는지 ㅋㅋ
혹시 필요하신 분들께서는 그냥 참고 정도만 하세요~
위 5가지 예제의 결과물은 아래와 같아요
-Bezier Spline
-Hermite Spline
-Koch Curve
-Sierpimsk Gasket
-Mamdel Brot
소스코드입니다.
#include <gl\glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#define CNT 100 // u size
#define SIZE 500 // image size
#define TRUE 1
#define FALSE 0
#define BUFFER 100 // file name size
#define MASK_BIT 12 // Masking
#define NPOINT 4 // no. of point
#define EXIT 6 // Program Exit
#define STEP 7 // Koch Curve step
#define M_P 100000
#define ROUND(a) (int)(a+0.5)
#define MAX_COLOR 256
#define H1(u) (2*(u*u*u)-3*(u*u)+1) // 배합함수
#define H2(u) (-2*(u*u*u)+3*(u*u))
#define H3(u) ((u*u*u)-2*(u*u)+u)
#define H4(u) ((u*u*u)-(u*u))
typedef struct _wcPt3 {
double x, y, z;
}wcPt3;
typedef struct _Complex
{
float x;
float y;
}Complex;
typedef struct _RGB{
unsigned char R[MAX_COLOR],G[MAX_COLOR],B[MAX_COLOR];
}RGB;
////////////////////////////////////////////////////////
/* Global Variable List */
//Image Canvas Size
unsigned char Image[SIZE][SIZE][3];
/* Bezier Function */
wcPt3 initPt[NPOINT] = {{100.0, 150.0, 0.0}, {250.0, 120.0, 0.0},
{80.0, 90.0, 0.0}, {60.0, 120.0, 0.0}};
wcPt3 Curve[CNT];
/* Hermite Function */
void hermit();
/* Koch Curve */
wcPt3 temp[M_P];
wcPt3 koch_point[M_P] = {{0.3, 0.1, 0.0}, {0.3, 0.9, 0.0},
{0.9, 0.5, 0.0}, {0.3, 0.1, 0.0}};
/* Sierpimsk Gasket */
int Triangle[3][2] = {499, 0, 499, 499, 0, 250};
/* Mamdelbrot */
RGB color;
unsigned char R;
unsigned char G;
unsigned char B;
////////////////////////////////////////////////////////
/* Function List */
int Select_menu(); // select menu
int WriteToImagePixel(); // Write Image to File
int lineDDA(int xa, int ya, int xb, int yb, char flagMask); // Draw Line
void DrawLineMask(); // Draw Masked Line
void initImage(); // Image BgColor set
/* Bezier Function */
void Processing_Bezier(void); // Bezier Spline
void computeCoefficients(int n, int *c); // Factorial Calc
void computePoint(float u, wcPt3 *pt, int nControls, wcPt3 *controls, int *c);
void bezier(wcPt3 *controls, int nControls, int m, wcPt3 *curve);
/* Herimte Function */
void Processing_Hermite();
/* Koch Curve */
void Processing_Koch_Curve();
long koch_curve();
/* Sierpimsk Gasket */
void Processing_Sierpimsk_Gasket();
void sierpimsk_gasket();
/* Mamdelbrot */
void Processing_Mamdelbrot();
void mamdelbrot();
Complex complexSquare( Complex c);
int iterate(Complex z, int Iter);
void setColor(int color);
void setPixel(int x, int y);
///////////////////////////////////////////////////////
/* Start Main Proc */
int main(int argc, char **argv)
{
int select;
select = Select_menu();
while(select!=EXIT) {
switch(select) {
case 1:
Processing_Bezier();
break;
case 2:
Processing_Hermite();
break;
case 3:
Processing_Koch_Curve();
break;
case 4:
Processing_Sierpimsk_Gasket();
break;
case 5:
Processing_Mamdelbrot();
break;
case 6:
break;
default :
exit(1);
}
getch();
system("cls");
select = Select_menu();
}
return 0;
}
int Select_menu()
{
int select;
printf("1. Bezier Spline \n");
printf("2. Hermite Spline \n");
printf("3. Koch Curve \n");
printf("4. Sierpimsk Gasket \n");
printf("5. Mamdel Brot \n");
printf("6. EXIT\n");
scanf("%d",&select);
return select;
}
/* Write image to file */
int WriteToImagePixel()
{
FILE *fp; // file pointer
char name[BUFFER]; // buffer
int j,k; // loop index
printf("Insert File Name : ");
scanf("%s",name);
fp = fopen(name,"wb");
printf("Name : %s\n",name);
if(fp==NULL) { printf("File open failed!!!\n"); return FALSE; }
fprintf(fp,"P6\n");
fprintf(fp,"%d %d\n",SIZE,SIZE);
fprintf(fp,"%d\n",255);
for(j=0; j<SIZE; j++) {
for(k=0; k<SIZE; k++) {
putc((unsigned char)Image[j][k][0],fp);
putc((unsigned char)Image[j][k][1],fp);
putc((unsigned char)Image[j][k][2],fp);
}
}
fclose(fp);
return TRUE;
}
/* Line to init Points */
void DrawLineMask()
{
int i;
for(i=0; i<NPOINT-1; i++)
lineDDA(initPt[i].x,initPt[i].y,initPt[i+1].x,initPt[i+1].y,TRUE);
}
/* Init Image Background color to white */
void initImage()
{
int i,j;
for (i=0; i<SIZE; i++) {
for(j=0; j<SIZE; j++) {
Image[i][j][0] = 255;
Image[i][j][1] = 255;
Image[i][j][2] = 255;
}
}
}
/* Draw Line */
int lineDDA(int xa, int ya, int xb, int yb, char flagMask)
{
int dx = xb - xa;
int dy = yb - ya;
int step, k, cnt;
float xIncrement, yIncrement, x = (float)xa, y = (float)ya;
int mask[MASK_BIT] = {0,0,0,1,1,1,0,0,0,1,1,1};
if( abs(dx) > abs(dy) )
step = abs(dx);
else
step = abs(dy);
xIncrement = dx / (float) step;
yIncrement = dy / (float) step;
for(k=0; k<step; k++) {
cnt = k % MASK_BIT;
x += xIncrement;
y += yIncrement;
int width_pos = abs((int)x);
int height_pos = abs((int)y);
if(flagMask==TRUE) {
if(mask[cnt]==1)
Image[height_pos][width_pos][0] = 0;
Image[height_pos][width_pos][1] = 0;
Image[height_pos][width_pos][2] = 0;
}
else if (flagMask==FALSE)
Image[height_pos][width_pos][0] = 0;
Image[height_pos][width_pos][1] = 0;
Image[height_pos][width_pos][2] = 0;
}
return TRUE;
}
void computeCoefficients(int n, int *c) {
int k, i;
for(k = 0 ; k <= n ; k++ ) {
c[k] = 1;
for(i = n ; i >=k+1; i--)
c[k] *= i;
for(i = n-k ; i >= 2; i--)
c[k] /= i;
}
}
void computePoint(float u, wcPt3 *pt, int nControls, wcPt3 *controls, int *c) {
int k, n = nControls -1;
float blend;
pt->x = 0.0 ; pt->y = 0.0; pt->z = 0.0;
for(k = 0 ; k <nControls ; k++) {
blend = c[k] * powf(u, k) * powf(1-u, n-k);
pt->x += controls[k].x * blend;
pt->y += controls[k].y * blend;
pt->z += controls[k].z * blend;
}
}
/* Bezier Function */
void bezier(wcPt3 *controls, int nControls, int m, wcPt3 *curve) {
int *c = (int *)malloc(nControls * sizeof(int));
int i;
computeCoefficients(nControls -1, c);
for( i = 0 ; i <= m ; i++ )
computePoint(i / (float)m, &curve[i], nControls, controls, c);
free(c);
}
void Processing_Bezier(void)
{
/* init image background color */
initImage();
/* Draw Mask Line */
DrawLineMask();
/* make points no. of CNT */
bezier(initPt, NPOINT, CNT, Curve);
/* Draw Line to Points */
for(int i=0; i<CNT-1; i++)
lineDDA((int)Curve[i].x,(int)Curve[i].y,(int)Curve[i+1].x,(int)Curve[i+1].y,FALSE);
/* image write to file */
WriteToImagePixel();
printf("Processing Bezier Success \n");
}
void Processing_Hermite()
{
/* init image background color */
initImage();
/* Draw Mask Line */
DrawLineMask();
/* make points no. of CNT */
hermit();
/* image write to file */
WriteToImagePixel();
printf("Processing Hermite Success \n");
}
void hermit()
{
int xa=220,ya=40,xb=80,yb=150,xv=20,yv=-33,xv1=-4,yv1=50;
float f;
int i = 0;
int x, y, x_1, y_1;
int n = 200;
x_1 = x = xa;
y_1 = y = ya;
while(i <= n){
f = (float)(i / n);
x = (int)(H1(f) * xa + H2(f) * xb + H3(f) * xv1 + H4(f) * xv1);
y = (int)(H1(f) * ya + H2(f) * yb + H3(f) * yv1 + H4(f) * yv1);
lineDDA(x_1, y_1, x, y,FALSE);
x_1 = x;
y_1 = y;
i++;
}
}
long koch_curve()
{
int i,step;
long tp = NPOINT;
for(step = 0; step < STEP; step++)
{
tp += (tp-1) * 3;
if (tp > M_P) break;
for(i =0; i < tp; i+=4)
{
temp[i].x = koch_point[i/4].x;
temp[i].y = koch_point[i/4].y;
}
for(i = 0; i < tp; i++)
{
if( (i%4) == 1)
{
temp[i].x = temp[i-1].x + (temp[i+3].x - temp[i-1].x) / 3;
temp[i].y = temp[i-1].y + (temp[i+3].y - temp[i-1].y) / 3;
temp[i+2].x = temp[i+3].x - (temp[i+3].x - temp[i-1].x) / 3;
temp[i+2].y = temp[i+3].y - (temp[i+3].y - temp[i-1].y) / 3;
}
else if( (i%4) == 2)
{
temp[i].x = temp[i-1].x/2 + temp[i+1].x/2 + sqrt(3)/2*temp[i-1].y - sqrt(3)/2*temp[i+1].y;
temp[i].y = temp[i-1].y/2 + temp[i+1].y/2 - sqrt(3)/2*temp[i-1].x + sqrt(3)/2*temp[i+1].x;
}
}
for(i = 0 ; i < tp; i++)
{
koch_point[i].x = temp[i].x;
koch_point[i].y = temp[i].y;
}
}
return tp;
}
void Processing_Koch_Curve()
{
/* init image background color */
initImage();
/* make points no. of CNT */
long cnt = koch_curve();
/* Draw Koch Curve */
for(int i = 0; i < cnt - 1 ; i++)
lineDDA((int)(koch_point[i].x*(SIZE-1)+.5),(int)(koch_point[i].y*(SIZE-1)+0.5),
(int)(koch_point[i+1].x*(SIZE-1)+0.5),(int)(koch_point[i+1].y*(SIZE-1)+0.5), FALSE);
/* image write to file */
WriteToImagePixel();
printf("Processing Koch Curve Success \n");
}
void sierpimsk_gasket()
{
int i,j;
int cx, cy, px, py;
for(i = 0 ; i < 3; i++)
Image[Triangle[i][0]][Triangle[i][1]][0] = 0;
Image[Triangle[i][0]][Triangle[i][1]][1] = 0;
Image[Triangle[i][0]][Triangle[i][1]][2] = 0;
px = Triangle[0][0];
py = Triangle[0][1];
for(i = 0; i < M_P ; i++)
{
j = rand() % 3;
cx = (int)((double)(px+Triangle[j][0])/2.0 + 0.5);
cy = (int)((double)(py+Triangle[j][1])/2.0 + 0.5);
Image[cx][cy][0] = 0;
Image[cx][cy][1] = 0;
Image[cx][cy][2] = 0;
px = cx;
py = cy;
}
}
void Processing_Sierpimsk_Gasket()
{
/* init image background color */
initImage();
/* make points no. of CNT */
sierpimsk_gasket();
/* image write to file */
WriteToImagePixel();
printf("Processing Sierpimsk Gasket Success \n");
}
Complex complexSquare( Complex c)
{
Complex newz;
newz.x = c.x * c.x - c.y * c.y;
newz.y = 2 * c.x * c.y;
return (newz);
}
int iterate(Complex z, int Iter)
{
int cnt = 0;
Complex c = z;
while(( c.x * c.x + c.y * c.y <= 4. ) && (cnt < Iter))
{
c = complexSquare(c);
c.x += z.x;
c.y += z.y;
cnt++;
}
return (cnt);
}
void GetRandomColor()
{
for(int i = 0; i < 256; i++)
{
color.R[i] = rand() % 256;
color.G[i] = i;
color.B[i] = rand() % 256;
}
}
void mamdelbrot()
{
int x,y,cnt;
Complex z;
float realMax = 0.25, realMin = -0.75, imagMax = 2.1, imagMin = -1.0;
float realInc=(realMax-realMin) / (SIZE*4.5);
float imagInc=(imagMax-imagMin) / (SIZE*4.5);
for( x = 0, z.x = realMin; x < SIZE; x++, z.x += realInc)
{
for(y=0, z.y = imagMin; y < SIZE; y++, z.y+=imagInc)
{
cnt = iterate(z,100);
if ( cnt == 100)
setColor(255);
else
{
for (int i = 0 ; i < cnt ; i++ )
setColor(i);
}
setPixel(x, y);
}
}
}
void setColor(int index)
{
R = color.R[index];
G = color.G[index];
B = color.B[index];
}
void setPixel(int x, int y)
{
Image[x][y][0] = R;
Image[x][y][1] = G;
Image[x][y][2] = B;
}
void Processing_Mamdelbrot()
{
/* init image background color */
initImage();
/* Get Color */
GetRandomColor();
/* Processing mamdelbrot */
mamdelbrot();
/* image write to file */
WriteToImagePixel();
printf("Processing MamdelBrot Success \n");
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
'개발 > 앱' 카테고리의 다른 글
Chartboost 광고 구현해보기 (안드로이드 스튜디오) (0) | 2016.11.29 |
---|---|
직접만든 안드로이드 비행기게임 앱 날아라 비행기 (Tappy Plane) (0) | 2016.11.17 |
안드로이드 앱 다국어 사용하기 (android studio 다국어 설정방법 values-kr translatable) (0) | 2016.11.15 |
cocos2dx 컴파일 방법 (libcocos2dcpp.so 에러 발생시 해결방법) (0) | 2016.11.15 |
컴퓨터 그래픽스 레포트 - 원/선/타원/점선 그리기 코드 (0) | 2016.11.11 |
Cocos Creator 강좌 - Button 클릭 이벤트 구현해 보기 (Cocos2d-js button event) (0) | 2016.11.10 |
Cocos creator 설치 및 적응기 1탄 (0) | 2016.11.09 |
Coco2dx 개발 코코스2d 배경화면 자동 스크롤하기 (슈팅게임 배경화면 스크롤) (0) | 2016.11.07 |
최근댓글