2009년 1월 7일 수요일

[스크랩]GRAPHIC.H 사용법

스크랩자주:Visual Studio .NET에는 GRAPHIC.H가 들어있지 않습니다.
출처 카페 > Mobile모바일,위피,WI.. / 맛동산
원본 http://cafe.naver.com/webzero0/1086

컴퓨터 그래픽이라는 단어는 모든 사람에게 그리 잘 알려진 것은 아니다. 비디오 아케이트 게임을 즐겼던 사람들이나 전기회로, 교량해석 및 자동차설계, 건축설계 등에 종사하였던 공학도에게나 알려져 있다. 그러나 현재는CAD/CAM, FA, CIM 등에 이용되고 사무자동화, 화장기법, 옷감의 재단 등에 쓰이지 않는 곳이 없다. 따라서 이 장에서는 마이크로 컴퓨터를 이용하여 그래픽 이미지를 나타내기 위하여 필요한 가장 기초적인 수학공식과 이에 따른 프로그래밍 기술을 취급한다.

마이크로 컴퓨터는 그래픽을 위하여 일반적으로 래스터 디스플레이(raster display) 장치를 사용하고 있다.

이것은 디스플레이 장치가 수평선의 라인(raster line)으로 구성되는 것을 나타내며 각 라인은 픽셀(또는 picture element : PEL)이라 부르는 도트(dot)로 구성된다.

스크린의 해상도는 중해상도, 고해상도로 나누며 고해상도는 200 래스터 라인에 640 픽셀, 중해상도는 200 래스터 라인에 320 픽셀로 나타낸다.그래픽 이미지는 픽셀의 ON, OFF에 의해 이루어진다.

C 언어에서는 그래픽을 위해서 #include 화일 내에 그래픽의 무늬, 색상, 모양등을 지원하는 <graphics.h> 함수와 좌표와 수치를 지원하는 <math.h> 함수가 선언되어 있다.


top01.gif12.1 컴퓨터 그래픽 함수

top01.gif기본 그래픽함수

 


initgraph, cleardevice, setbkcolor

setcolor, putpixel, getpixel,

moveto, moverel, setlinestyle,

line, lineto, linerel,

rectangle, closegraph 함수

 

top01.gif■ 그래픽함수의 초기화 - initgraph()

initgraph() 함수는 그래픽스 시스템을 초기화 시키는 명령으로, 그래픽 드라이브와 그래픽 모드를 설정하는 명령이다.

이 함수의 일반형식은

 


initgraph(graph_drive, graph_mode, drive_path)


이다. 여기서 graph_drive는 그래픽 보드를 선택하는 것이며, graph_drive가 0(DETECT)이면 그래픽 보드를 체크하여 그래픽 드라이브를 자동으로 얻는다.

그래픽 보드 대응 상수는 다음과 같다.

 

표 12.1 그래픽보드 대응상수

그래픽 드라이브 상수

정 수 값

DETECT

CGA

MCGA

EGA

EGA64

EGAMONO

HERC

ATT400

VGA

PC3270

IBM8514

0

1

2

3

4

5

7

8

9

10

6

 

그래픽 모드는 다음과 같다.

 

표 12.2 그래픽 모드

그래픽 드라이브

그래픽 모드

CGA

MCGA

EGA

EGA64

EGA-MONO

HERC

ATT400

VGA

PC3270

IBM8514

CGAC0 (320 x 200)

CGAC1 (320 x 200)

CGAC2 (320 x 200)

CGAC3 (320 x 200)

CGAHI (640 x 200)

MCGAC0 (320 x 200)

MCGAC1 (320 x 200)

MCGAC2 (320 x 200)

MCGAC3 (320 x 200)

MCGAMED (640 x 200)

MCGAHI (640 x 480)

EGALO (640 x 200)

EGAHI (640 x 350)

EGA64LO (640 x 200)

EGA64HI (640 x 350)

EGAMONOLO (640 x 350)

EGAMONOHI (640 x 350)

HERCMONOH (720 x 348)

ATT400C0 (320 x 200)

ATT400C1 (320 x 200)

ATT400C2 (320 x 200)

ATT400C3 (320 x 200)

ATT400C1 (320 x 200)

ATT400MEM (640 x 200)

ATT400HI (640 x 400)

VGALO (640 x 200)

VGAMEM (640 x 350)

VGAHI (640 x 480)

PC3270HI (720 x 350)

IBM8514HI (640 x 480)

IBM8514LO (1024 x 768)

 

drive_path는 .BGI파일이 있는 path를 정의해주는 것으로, 특정 값이 주어지지 않으면 현재 디렉토리로 한다.

top01.gif■ 화면지우기 - cleardevice()

cleardevice() 함수는 그래픽 화면 전체를 지우고 새롭게 시작하게 해준다.

이 함수의 일반형식은

 


cleardevice()

 

이다.

top01.gif■ 백그라운드 색지정 - setbkcolor()

setbkcolor() 함수는 팔레트를 사용하여 현재의 백그라운드 컬러를 지정한다.

이 함수의 일반형식은

 


setbkcolor(color)

 

이다. 여기서 color는 배경색을 말하며, color표는 다음과 같다(표13-1 참조)

 

표 12.3 칼라표

칼라상수

칼라상수

0

1

2

3

4

5

6

7

BLACK

BLUE

GREEN

CYAN

RED

MAGENTA

BROWN

LIGHTGRAY

8

9

10

11

12

13

14

15

DARKGRAY

LIGHTBLUE

LIGHTGREEN

LIGHTCYAN

LIGHTRED

LIGHTMAGENTA

YELLOW

WHITE


top01.gif■ 색지정 - setcolor()

setcolor() 함수는 팔레트를 사용하여 현재 드로잉 칼라를 지정한다.

이 함수의 일반형식은

 


setcolor(color)

 

이다. 여기서 color는 포그라운드색을 말하며, color표는 (표 12.3)과 같다.

 

[예제 12-1]


#include <graphics.h>

#include <math.h>

void main()

    {

        int GraphDriver=DETECT, GraphMode;

        int x1=100, y1=100, x2=200, y2=100;

        initgraph(&GraphDriver, &GraphMode, "");

        setcolor(RED);

        line(x1,y1,x2,y2);

        getch();

        closegraph();

    }

 

 

 

top01.gif■ 점그리기 - putpixel(), getpixel()

putpixel() 함수는 그래픽 함수에서 가장 기본이 되는 명령으로 픽셀(pixel)의 ON, OFF를 나타낸다. 즉 지정된 좌표에 점을 나타내는 명령이다. getpixel() 함수는 화면상의 점에 색상을 지정한다.

이 함수의 일반형식은

 


putpixel(x, y, color), getpixel(x,y,color)


이다. 여기서 x, y는 ON, OFF해야 할 점의 좌표를 말하며 컬러는 setcolor()함수로 선택 한다.

top01.gif■ 커서이동 - moveto(), moverel()

moveto() 함수는 현재 커서 위치를 이동시키는 명령으로 lineto() 함수를 사용할때 유익하게 사용될 수 있다. moverel() 함수는 상대 좌표를 이용한 방법이다. 이 함수의 일반형식은

 


moveto(x, y), moverel(dx,dy)


이다. 여기서 x, y는 커서를 이동시킬 좌표를 말한다.

 

[예제 12-2]

#include <graphics.h>

#include <math.h>

void main()

    {

        int GraphDriver=DETECT, GraphMode;

        initgraph(&GraphDriver, &GraphMode, "");

        setcolor(RED);

        line(100,200,200,200);

        moveto(200,200);

        lineto(200,100);

        getch();

        closegraph();

    }

 

 

 

top01.gif■ 라인의 형태 설정 - setlinestyle()

setlinestyle() 함수line(), lineto(), rectangle()등에 그려지는 모든 라인의 굵기와 형태를 설정하는 명령이다.

이 함수의 일반형식은

 


setlinestyle(line_style, user_pattern, line_width)


이다. 여기서 line_style은 선의 형태를 지정하는 것으로 그 값은 다음과 같다 (표 12.4 참조)

 

표 12.4 라인 스타일표

스타일 상수

설명

0

1

2

3

4

SOLID_LINE

DOTTED_LINE

CENTER_LINE

DASHED_LINE

USERBIT_LINE

실선

점선

일점쇄선

파선

사용자 정의선

 

그리고 user_pattern은 line_style의 값이 4, 즉 USERBIT_LINE일 경우에만 적용되는 16bit 패턴이다, line_width는 라인의 굵기를 지정하는 것으로 그 값은 1, 2, 즉 NORM_WIDTH, THICK_WIDTH로 1도트, 3도트 굵기이다.

 

[예제 12-3] Line style를 변화시키면서 리인을 긋는 프로그램


#include <graphics.h>

#include <math.h>

void main()

    {

        int GraphDriver=DETECT, GraphMode;

        char *line_style[]={ "SOLID_LINE",

                                        "DOTTED_LINE",

                                        "CENTER_LINE",

                                        "DASHED_LINE"


                                    };

        int i;

        initgraph(&GraphDriver, &GraphMode, "");

        settextstyle(TRIPLEX_FONT,HORIZ_DIR,1);

        for(i=0; i<80; i+=20)

            {

                setlinestyle(i/20,1,2);

                line(100,100+i, 200,100+i);

                outtextxy(250, 100+i, line_style[i/20]);

            }

        getch();

        closegraph();

    }

 

------------------- SOLID_LINE

------------------- DOTTED_LINE

-- · -- · -- · -- CENTER_LINE

--- - --- - --- - ---DASHED_LINE

 

 

top01.gif■ 선그리기 - line(), lineto(), linerel()

line() 함수는 지정된 두 점 사이에 직선을 긋는 명령이다. linerel() 함수는 상대 좌표 함수이다.

이 함수의 일반형식은

 


line(start_x, start_y, end_x, end_y)


이다. 여기서 start_x, start_y는 시작점, end_x, end_y는 끝점 이다.

lineto() 함수는 현재 커서 위치에서 지정된 점 사이에 직선을 긋는 명령이며 linerel() 함수는 상대 좌표 함수이다.

이 함수의 일반형식은

 


lineto(end_x, end_y), linerel(dx,dy)


이다. 여기서 end_x, end_y는 끝점 이다.

 

[예제 12-4]

#include <conio.h>

#include <graphics.h>

#include <math.h>

void main()

    {

        int GraphDriver=DETECT, GraphMode;

        initgraph(&GraphDriver, &GraphMode, "");

        line(100,100,150,200);

        moveto(150,200);

        linerel(110,-80);

        lineto(100,100);

        getch();

        closegraph();

    }

 

 

 

top01.gif■ 사각형 그리기 - rectangle()

rectangle() 함수는 사각형을 그리는 명령이다.

이 함수의 일반형식은

 


rectangle(left, top, right, bottom)


이다. 여기서 left는 사각형의 좌단의 좌표이고, top은 사각형의 상단의 좌표이고, right는 사각형의 우단의 좌표이고, bottom은 사각형의 하다의 좌표이다. 이 값들의 관계를 그림과 함께 나타내면 다음과 같다.

[ rectangle(x1, y1, x2, y2) ]

 


+-----------------------------------------------------------------------------+

| (x1, y1) (left, top)|

|+-----------++-----------+|

||||||

||| <==========>|||

||||||

|+-----------++-----------+|

| (x2, y2) (right, bottom)|

||

+-----------------------------------------------------------------------------+

 

[예제 12-5] 사각형 형태를 고려한 프로그램을 나타내면 아래와 같다.


#include <graphics.h>

void main()

    {

        int graph_drive, graph_mode;

        graph_drive = DETECT;

        initgraph(&graph_drive, &graph_mode, "");

        setlinestyle(SOLID_LINE,0,THICK_WIDTH);

        rectangle(40, 40, 210, 110);

        setlinestyle(DOTTED_LINE,0,NORM_WIDTH);

        rectangle(50, 50, 100, 100);

        setlinestyle(DASHED_LINE,0,NORM_WIDTH);

        rectangle(150, 50, 200, 100);

        getch();

        closegraph();

    }

 

 

top01.gif■ 그래픽종결 - closegraph()

closegraph() 함수는 그래픽 시스템을 종료시키는 명령이다.

이 함수의 일반형식은

 


closegraph()


이다.

원, 타원 , 호 함수


setfillstyle, circle, ellipse, arc, pieslice 함수


top01.gif■ 필패턴 및 필칼라지정 - setfillstyle()

setfillstyle() 함수는 필 패턴과 필 칼라를 지정하는 명령이다.

이 함수의 일반형식은


setfillstyle(fill_pattern, fill_color)


이다. 여기서 fill_pattern의 값은 다음과 같다 (표12.5참조).

 

표 12.5 필 패턴표

필 패턴 상수

설 명

0

1

2

3

4

5

6

7

8

9

10

11

EMPTY_FILL

SOLID_FILL

LINE_FILL

LTSLASH_FILL

SLASH_FILL

BKSLASH_FILL

LTBKSLASH_FILL

HATCH_FILL

XHATCH_FILL

INTERLEAVE_FILL

WIDE_DOT_FILL

CLOSE_DOT_FILL

백그라운드 칼라로 칠한다.

SOLID로 칠한다.

---로 칠한다.

///로 칠한다.

두꺼운 ///로 칠한다.

두꺼운 \\\로 칠한다.

\\\로 칠한다.

HATCH로 칠한다.

???로 칠한다.

INTERLEAVE로 칠한다.

굵은 점으로 칠한다.

점으로 칠한다.


top01.gif■ 원그리기 - circle()

circle() 함수는 원을 그리는 명령이다.

이 함수의 일반형식은

 


circle(center_x, center_y, radius)


이다. 여기서 center_x, center_y는 원의 중심 좌표이며, radius는 반지름을 말한다.

top01.gif■ 타원그리기 - ellipse()

ellipse() 함수는 타원의 원호를 그리는 명령이다.

이 함수의 일반형식은

 


ellipse(center_x, center_y, start_angle,

end_angle, x_radius, y_radius)

 

이다. 여기서 center_x, center_y는 타원의 중심 좌표이며, start_angle과 end_angle은 시작 각도와 끝 각도를 나타내는데 각도 0도가 시계 3시 방향으고, 반시계 방향으로 각도가 증가한다. x_radius와 y_radius는 x축과 y축의 반지름을 말한다.

top01.gif■ 호 그리기 - arc()

arc() 함수는 원호를 그리는 명령이다.

이 함수의 일반형식은

 


arc(center_x, center_y,

start_angle, end_angle, radius)


이다. 여기서 center_x, center_y는 원호의 중심의 좌표이며, start_angle과 end_angle은 시작 각도와 끝 각도를 나타내는데 각도 0도가 시계 3시 방향으고, 반시계 방향으로 각도가 증가한다. radius는 반지름을 말한다.

 

[예제 12-6]



#include <graphics.h>

void main()

    {

        int graph_drive, graph_mode;

        graph_drive = DETECT;

        initgraph(&graph_drive, &graph_mode, "");

        circle(100, 100, 30);

        ellipse(190, 100, 0, 360, 60, 15);

        arc(330,100, 210, 330, 30);

        setfillstyle(EMPTY_FILL, WHITE);

        pieslice(390, 100, 230, 310, 30);

        getch();

        closegraph();

    }



 

top01.giffloodfill 함수


floodfill() 함수는 선택된 색깔을 가지고 영역을 색칠하는 것이다.

이 명령의 일반형식은

 


floodfill(x, y, border_color)

 

이다. 여기서 x, y는 빈틈없이 색칠할 개시점의 x, y좌표이다. 그리고 board_color는 색칠할 경계의 칼라의 색이다. 색할 패턴과 칼라는 setfillstyle() 함수를 사용하여 장한다.

[예제 12-7] 라인문을 이용하여 커브를 여러 개 그리는 모양을 프로그램하시오

① 알고리즘

라인문을 짧게 작성하여 여러 번 반복시켜 커브 비슷한 모양을 얻는다.

 

② 프로그램 및 결과



#include <graphics.h>

#define X getmaxx()

#define Y getmaxy()

#define XY_Rate X / Y * 2

void main()

    {

        int x=0, y;

        int graph_drive, graph_mode;

        graph_drive = DETECT;

        initgraph(&graph_drive, &graph_mode, "");

        for(y=0; y < Y; y+=2)

        line(0, y, x+=XY_Rate, Y);

        getch();

        closegraph();

    }

 

 

top01.gifsetviewport() 함수

setviewport() 함수는 화면의 좌표계를 재정의해 줄 수가 있다. 다른 말로 표현하면 setviewport() 함수는 새로운 좌표공간을 설정하여 목적물을 그릴 수 있다. 즉 viewport내에서는 상대좌표 값을 사용한다.

이 함수의 일반형식은

 


setviewport(left, top, right, bottom, clip)

 

이다. 여기서 left, top은 좌측 상단의 좌표값이고, right, bottom응 우측 하단의 좌표이다. 그리고 clip은 클리핑 플랙을 말하는 것이다.

예를 들어 setviewport(0, 0, 190, 90, 0)은 좌측 제일상단이 (0,0)이며 우측 제일하단이 (190,90)을 나타낸다.

 

[예제 12-8] 이웃하는 집을 setviewport() 함수를 이용하여 그리는 프로그램


#include <graphics.h>

void Draw();


void main()

    {

        int graph_drive, graph_mode;

        graph_drive = DETECT;

        initgraph(&graph_drive, &graph_mode, "");

        setviewport(160, 100, 319, 199, 1);

        rectangle(0,0, 159, 99);

        Draw();

        setviewport(0, 100, 160, 199, 1);

        Draw();

        getch();

        closegraph();

    }

void Draw()

    {

        line(20, 45, 40, 15);

        moveto(40, 15);

        lineto(140, 15);

        lineto(150, 40);

        lineto(150, 85);

        lineto(120, 90);

        line(120, 45, 140, 15);

        rectangle(20, 45, 120, 90);

    }


 

top01.gif 12.2 컴퓨터 그래픽에 대한 수학적 방법

일반적으로 컴퓨터 그래픽은 스크린에 어떤 영상을 표현할 때 그 영상을 필요에 따라 축소, 확대 또는 이동, 회전 시키고자 하는 경우가 있다, 이러한 경우, 이용하는 방법에 기하학적인 변환기법이 필요하며, 이에 따른 수학적인 표현방법이 있다.

여기에서는 이해를 4돕기 위해 2차원 평면상에서 점, 선, 목적물들의 변환과 표현방법을 기술하는 수학의 기본적인 방법에 대해 나타내고, 그다음 3차원에 대해 취급한다.

top01.gif변 형

2차원 평면상, 또는 2축 좌표계에서의 점의 표현은 X나 Y좌표로 주어진다. 이러한 좌표계는 1*2매트릭스로 취급된다.

예를 들어 매트릭스(2,5)는 원점에서 X축으로 2, Y축으로 5라는 점으로 이해할 수 있다. 이 표현방법은 두 점을 가진 직선으로 확장시켜 X, Y좌표계로 나타내면 계산하기에 편리하다.

 


rm L = bmatrix {x _1 ~y _1 ~#~x _2 ~y _2 ~~}


매트릭스 계산규칙을 이용하면 점이나 직선 매트릭스에(또는 다른 매트릭스로 표현되는 기하학적인 요소) 변형 매트릭스를 추가하여 새로운 변형(transformation)을 요소로 나타낼 수 있다. 여기에서 3개의 변형(이동, 확대 및 축소, 회전)에 대해 기술한다.

top01.gif■ 이 동

이동(translation)은 한 장소에서 다른 장소로 움직이는 것을 말한다. 점의 경우 좌표계 변환은

X'= X + m, Y'= Y + n

여기서 X', Y'= 이동된 점의 좌표

X , Y = 이동하기 전의 원래 좌표

m , n = X, Y 방향으로 이동을 나타낸다.

매트릭스 형태로 나타내면

(X',Y')=(X,Y)+T

여기서 T는 (m,n)이며 이동 매트릭스라고 한다.

일반적으로 T매트릭스는 확장하여 2*2로 표시하며

 


rm T = bmatrix { A ~~B~ #~C ~~D~~}

 

로 나타낸다. 이 A, B, C, D의 적당한 선택에 의해 점의 변형을 간단하게 나타낼 수 있다.

이동의 한 예로서 직선인 경우를 고려한다. 직선의 경우는 두 점으로 이어진 선분임으로 각각 점의 이동도 알 수가 있다. (X1,Y1)의 좌표(1,1)과 (X2,Y2)의 좌표(2,4)로 이어진 직선을 X방향으로 2, Y방향으로 3만큼 이동시켰을 때의 매트릭스 변환은 이

 


rm L=bmatrix { 1 ~1~ #2 ~2~ } ~~~ T=bmatrix { 2 ~3~ #2 ~3~ }

 


rm P`=L+T=bmatrix { 1 ~1~ #2 ~2~} + ~bmatrix { 2 ~3~ #2 ~3~}=~bmatrix { 3 ~4~ #4 ~7~}

 

다. 여기서 새로운 직선의 좌표 P'은 (X1,Y1)의 좌표(3,4)와 (X2,Y2)의 좌표(4,7)를 잇는 직선이 된다.

그리고 목적물(object) 이동의 경우 확장하여 아래와 같이 나타낼 수 있다.

 


rm P`=bmatrix { P _1 '~ #P _n '~} = ~bmatrix { X _1 ~Y _1~ #X _n ~Y _n~} +~bmatrix { T _x ~T _y ~ #T _n ~ T _n~}

 

변형후의 좌표 원래 좌표 이동 크기

목적물의 이동 예로서 (X1,Y1)의 좌표 (0,0), (X2,Y2)의 좌표 (52,30), (X3,Y3)의 좌표 (-4,7)로 구성된 3각형을 X방향으로 100, Y 방향으로 50만큼 이동시킨다면

 


rm P`=bmatrix { P _1 '~ #P _2 '~ #P _3 '~} = ~bmatrix { ~0 ~~0~ #52 ~30~ #-4 ~67~} +~bmatrix { 100 ~50 ~ #100 ~ 50~ #100 ~ 50~} = ~bmatrix { 100 ~50 ~ #152 ~ 80~ #~96 ~ 117~}

로 된다.

top01.gif■ 스케일링

스케일링(scaling)은 크기를 확대하고 축소하는 데 이용된다. 스케일링은 X, Y방향으로 반드시 동일하게 할 필요는 없다. 예를 들어 원은 X와 Y의 스케일링 벡터값을 다르게 사용하여 타원으로 변형시킬 수 있다. 점의 변형을 스케일링 매트릭스로 표현하면

(X',Y')=(X,Y)*S

여기서


rm S = bmatrix { S _x ~~0~ #~0 ~~S _y~}

 

매트릭스이다. 이것은 X방향으로 Sx, Y방향으로 Sy만큼의 크기변형이다. 예를 들어 직선의 스케일링은 원래의 좌표를 참조하고

스케일링 매트릭스

 


rm S = bmatrix { 2 ~0~ #0 ~2~}

 

로 하면 새로운 변형형태는


rm P' = bmatrix { 1 ~1~ #2 ~4~}bmatrix { 2 ~0~ #0 ~2~} = ~bmatrix { 2 ~2~ #4 ~6~}

 

로 된다. 즉 2배로 확대되었다. 아래와 같은 목적물의 경우를 매트릭스 형태로 표현하면

 


rm P`=bmatrix { P _1 '~ #P _2 '~ #P _3 '~} = ~bmatrix { ~0 ~~0~ #30 ~~0~ #15 ~30~} bmatrix { 2 ~0 ~ # #0 ~ 2~} = ~bmatrix { ~0 ~~0 ~ #60 ~~0~ #~30 ~60~}

 

(변형된 후의 좌표) (원래좌표)<-(스케일링 벡터) 로 된다.

top01.gif■ 회 전

회전(rotation)은 한 점의 위치에서 다른 점으로 회전하는 형태를 말한다. 양의 각도로 회전시키면 반시계방향으로 회전하며 음의 각도로 회전시킨 시계방향으로 회전한다. 매트릭스 형태로 표시하면

(X',Y')=(X,Y)*R

R은 회전 매트릭스를 나타내며 다음과 같다.


rm R = bmatrix { ~cosθ ~sinθ~ #-sinθ ~cosθ~}

 

따라서 새로운 점의 좌표(X',Y')은


rm (X',Y') = (X,Y) bmatrix { ~cosθ ~sinθ~ #-sinθ ~cosθ~}

 


rm = (xcosθ- ysinθ , xsinθ + ycosθ)

 

가 된다. 그러나 원점을 중심으로 회전하였을 경우 본래의 좌표 P와 회전 후의 새로운 좌표 p'의 거리는 같다.

증명 : 거리를 r로 할 때

x = rcosθ, y = rsinθ

x'= rcos(θ+φ)=rcosφcosθ - rsinφsinθ

= xcosθ - ysinθ

y'= rsin(θ+φ)=rcosφsinθ + rsinφcosθ

= xsinθ + ycosθ

직선의 회전을 고려하면


rm R = bmatrix { ~cos30˚ ~sin30˚~ #-sin30˚ ~cos30˚~} = ~bmatrix { ~~0.866 ~0.500~ #-0.500 ~0.866~}

원래의 직선좌표가


rm L = bmatrix { 1 ~~1~ #1 ~~1~}

이면

변형 후의 직선좌표는


rm P' = bmatrix { 1 ~1~ #2 ~4~} = ~bmatrix { ~~0.866 ~0.500~ #-0.500 ~0.866~} = ~bmatrix { ~~0.366 ~1.366~ #-0.268 ~4.464~}

가 된다.

물체의 회전을 고려하여 매트릭스를 확장하면 다음 형태로 나타낼 수 있다.

 


rm P' = bmatrix { P' ~~ #P _n ' ~} = ~bmatrix { X _1 ~Y _1~ #X _n ~Y _n~} = ~bmatrix { ~cosθ ~sinθ~ #-sinθ ~cosθ~}

 

원래의 P1, P2, P3가 (0,0),(60,0),(30,60)으로 나타나는 3각형의 물체를 30˚만큼 회전시킨다면 새로운 좌표 P1', P2', P3'의 물체는

 


rm bmatrix { P _1 ' ~ #P _2 ' ~#P _3 ' ~} = ~bmatrix {~0 ~0~ #60 ~0~ #30 ~0~} = ~bmatrix { ~0.8660 ~0.5~~~~ #-0.5 ~~~0.8660~}= ~bmatrix {~~0 ~~0~ #~52 ~30~ #-4 ~67~}

으로 된다.

top01.gif찌그러짐, 반사의 변형

목적물의 반사는 각축의 반대쪽에 있는 거울형상을 발생시키는 과정을 말한다. 매트릭스 형태로 생각하면 Y축과 X축의 반사는 각각

 


rm bmatrix {-1 ~1~ #~~1 ~0~} , ~bmatrix {1 ~~~0~ #0 ~-1~}

 

로 나타내며 원점 (0,0)에 대한 반사는

 


rm bmatrix {-1 ~~~0~ #~~0 ~-1~}

로 나타난다.

원래의 좌표 (0,0),(60,0),(30,60)을 가지는 목적물을 X축 방향으로 반사시킨 모양은 다음과 같이 계산된 형태로 나타낸다.

 


rm P' = ~bmatrix { P _1 ' ~ #P _2 ' ~#P _3 ' ~} = ~bmatrix {~0 ~0~ #60 ~0~ #30 ~0~} = ~bmatrix { 1 ~~~0~ #0 ~-1~}= ~bmatrix {~0 ~~~~0~ #60 ~~~~0~ #30 ~-60~}

 

찌그러짐 변환은 전단변환이라고도 하며 대각선 이외의 성분만이 값을 가지는 변환을 찌그러짐 변환이라고 한다.

점의 찌그러짐 변환


rm (X', Y') = (X, Y) bmatrix { 1 ~B~ #0 ~1~} = ~(X, BX+Y)

또는


rm (X', Y') = (X, Y) bmatrix { 1 ~0~ #C ~1~} = ~(X + CY, Y)

와 같은 경우이다.

사각형 목적물의 찌그러짐 매트릭스가 다음과 같은 형태이면

 


rm (X', Y') = (X, Y) bmatrix { 1 ~1.5~ #0 ~~~1~} = ~(X , 1.5X+Y)

Y 찌그러짐으로 된다.


top01.gif 12.3 동차 좌표계

목적물을 변환시키는 데 있어서 일반적으로 2*2매트릭스를 사용하면 두 가지의 제한 조건이 생긴다.

첫째는 모든 변환이 원점(0,0)을 중심으로 이루어졌으므로 회전이나, 임의의 점이나 선을 기준으로 하는 변환은 불가능하다.

둘째는 이동의 계산과 스케일링과 회전의 계산은 서로 다르게 나타난다. 즉 이동은 덧셈, 스케일링, 회전 또는 찌그러짐, 반사는 곱셈 계산이다.

컴퓨터 그래픽에서는 많은 변환들이 하나의 매트릭스로 표현되는 것이 아니고 여러개가 복합적으로 이루어진다. 일련의 매트릭스 계산이 손쉽게 수행되기 위해서는 다른 매트릭스 형태로 되면 어렵다. 따라서 수학적 계산을 편리하게 하기 위해서 동차방법(homogeneous way)를 사용한다. 이 방법을 사용하면 모든 매트릭스 계산을 곱셈으로 나타낼 수 있다.

top01.gif동차 좌표계

동차 좌표계(homogenious coordination)에 있어서 점 (x,y)를 스케일 팩터(scale factor) H를 포함시켜 (x,y,H)로 표현한다. 정규화된 동차 좌표계에서 점 (x,y)는 (x/H,y/H,1)로 나타낸다.

동차 좌표계의 가장 중요한 효과는 2*2매트릭스가 3*3매트릭스로 표현되는 것이다. 매트릭스 형태로 표현하면,

 


rm bmatrix { A ~B~ #C ~D~} = ~bmatrix { A ~B ~0~ #C ~D ~0~ #0 ~0 ~0~}

 

로 된다. 이 동차변환의 특성을 고려하여 3*3매트릭스에 세변째 행의 요소(0,0,1)을 (L,M,1)로 바꾼다. 선형이동의 효과에서 L은 수평방향의 이동, M은 수직방향의 이동이다. 일반적으로 매트릭스 형태로 나타내면

 


rm T = bmatrix { A ~B ~0~ #C ~D ~0~ #L ~M ~1~}

 

로 된다. 이 동차변환 매트릭스는 이동, 스케일링, 회전변형 조작을 곱셈으로 나타낼 수가 있다. 점 (x,y)에 대한 변환은 다음과 같다.

 


rm (x', y', 1) = (x, y, 1)×T

또는

 


rm x' = Ax + cY + L, y' = Bx + Dy + M


top01.gif■ 이 동

이동(translation)을 고려하였을 때 매트릭스는 다음과 같은 형태로 된다.

 


rm T = bmatrix { 1 ~~0 ~0~ #C ~~1 ~0~ #L ~M ~1~}

 

이동 과정을 설명하기 위해 그림 13-6의 좌표를 이용하여 X방향으로 100, Y방향으로 50만큼 이동시킨다.

 


rm P = bmatrix { ~~0 ~~0~ #~52 ~32~ #-4 ~67~} ~~~T = bmatrix {100 ~50~ #100 ~50~ #100 ~50~}

을 동차 좌표계로 나타내면


rm P = bmatrix { ~~0 ~~0 ~1~ #~52 ~32 ~1~ #-4 ~67 ~1~} ~~~T = bmatrix {~~1 ~~0 ~1~ #~~0 ~~1 ~1~ #100 ~50 ~1~}

이다.

새로운 좌표 P'은


rm P' = ~bmatrix { P _1 ' ~ #P _2 ' ~#P _3 ' ~} = ~bmatrix {~~0 ~~0 ~1~ #~52 ~32 ~1~ #-4 ~67 ~1~} bmatrix {~~1 ~~0 ~1~ #~~0 ~~1 ~1~ #100 ~50 ~1~} = ~bmatrix {100 ~~50 ~1~ #152 ~~80 ~1~ #~96 ~117 ~1~}

 

가 된다. 세번째 행만 뺀다면 그림 13-6과 같다. 즉 덧셈의 계산이 곱셈으로 되었다. 만약 한 번 이동변환한 후 다시 이동한다면

그때의 변환은

 


rm bmatrix{1 ~~0 ~~~0~ #0 ~~1 ~~~0~ #L _1 ~M _1 ~1~} bmatrix{1 ~~0 ~~~0~ #0 ~~1 ~~~0~ #L _2 ~M _2 ~1~} = ~bmatrix{~~~1 ~~~~~~0 ~~~~~~0~ #~~~0 ~~~~~~1 ~~~~~~0~ #L _1 + L _2 ~M _1 + M _2 ~1~}

이다. 즉 L1+L2, M1+M2로 된다.

top01.gif■ 스케일링

스케일링 매트릭스의 동차 좌표계는


rm S= ~bmatrix{S _1 ~0~ ~0~ #0~ ~S _2 ~0~ #0~ ~0~ ~1~}

이다. 계속되는 크기변환은 곱셈형태로 된다.


rm bmatrix{S _1 ~0~ ~0~ #0~ ~S _2 ~0~ #0~ ~0~ ~1~} bmatrix{S _3 ~0~ ~0~ #0~ ~S _4 ~0~ #0~ ~0~ ~1~} = ~bmatrix{S _1 S _3 ~0~~~ ~0~ #0~~~ ~S _2 S _4 ~0~ #0~~~ ~0~~~ ~1~}


top01.gif■ 회전

동차 좌표계에서 각 θ만큼의 회전 매트릭스(회전 행렬)는 다음과 같다.

 


rm R= ~bmatrix{~~cosθ ~sinθ ~0~ #-sinθ ~cosθ ~0~ #~~~0~~~ ~~~0~~ ~~1~}

 

일련의 연속되는 회전변환 매트릭스는

 


rm bmatrix{~~cosθ _1 ~sinθ _1 ~0~ #-sinθ _1 ~cosθ _1 ~0~ #~~~~0~~~ ~~~0~~ ~~1~} bmatrix{~~cosθ _2 ~sinθ _2 ~0~ #-sinθ _2 ~cosθ _2 ~0~ #~~~~0~~~ ~~~0~~ ~~1~} = ~bmatrix{~~cos(θ _1 +θ _2 ) ~sin(θ _1 +θ _2 ) ~0~ #-sin(θ _1 +θ _2 ) ~cos(θ _1 + θ _2 ) ~0~ #~~~~~~~0~~~~~~ ~~~~~~~~0~~~~~ ~~1~}

으로 된다.

top01.gif■ 역 변 환

2개의 이동 매트릭스에 대해 생각하면, T1,T2의 매트릭스가

 


rm T _1 = bmatrix { ~~1~ ~~~0~ ~0~ #~~0~ ~~~1~ ~0~ #-L ~-M ~1~} ~~~T _2 = bmatrix { 1~~ ~0~~ ~0~ #0~~ ~1~~ ~0~ #L ~~M ~~1~}

 

일 때 T1T2의 곱셈 행렬은


rm T _1 × T _2 = bmatrix { ~~1~ ~~~0~ ~0~ #~~0~ ~~~1~ ~0~ #-L ~-M ~1~} bmatrix { 1~~ ~0~~ ~0~ #0~~ ~1~~ ~0~ #L ~~M ~~1~} = ~bmatrix { 1 ~0 ~0~ #0 ~1 ~0~ #0 ~0 ~1~}

 

이 되어 단위 매트릭스가 된다. 여기서 두 매트릭스는 역의 관계에 있다고 하며 T매트릭스의 역매트릭스를 T-1라 표시한다.

또 회전변환의 경우는 회전하는 각도의 부호를 바꾸면 역행렬이 된다.

 


rm R(30˚) = bmatrix { ~~cos30˚ ~sin30˚ ~0~ #-sin30˚ ~cos30˚ ~0~ #~~~0~~~ ~~~~0~~~ ~~~~1~}

 


rm R(30˚) ^-1 = R(-30˚)=bmatrix { ~~cos(-30˚) ~sin(-30˚) ~0~ #-sin(-30˚) ~cos(-30˚) ~0~ #~~~~~0~~~~~ ~~~~~~0~~~~~ ~~~~1~} bmatrix { ~~cos30˚ ~sin30˚ ~0~ #-sin30˚ ~cos30˚ ~0~ #~~~0~~~ ~~~~0~~~ ~~~~1~}

이 되어


rm R(30˚) × R(-30˚)= bmatrix {1 ~0 ~0~ #0 ~1 ~0~ #0 ~0 ~1~}

이 된다.

[예제 12-9] 사용자 정의에 의한 무늬를 지정한 프로그램


#include <graphics.h>

void main()

    {

        int GraphDriver = DETECT,GraphMode;

        int left=50,top=50,right=100,bottom=100,i,count=3;

        static char userpattern [][8]=

            {

                { 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55 },

                { 0x33,0x33,0xcc,0xcc,0x33,0x33,0xcc,0xcc },

                { 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0 },

                { 0x00,0x10,0x28,0x44,0x28,0x10,0x00,0x00 },

                { 0x00,0x70,0x20,0x27,0x24,0x24,0x27,0x00 },

                { 0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00 },

                { 0x00,0x00,0x3c,0x3c,0x3c,0x3c,0x00,0x00 },

                { 0x00,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x00 },

                { 0x00,0x00,0x22,0x08,0x00,0x22,0x1e,0x00 },


                { 0xff,0x7e,0x3c,0x18,0x18,0x3c,0x7e,0xff },

                { 0x00,0x10,0x10,0x7e,0x10,0x10,0x00,0x00 },

                { 0x00,0x42,0x24,0x18,0x18,0x24,0x42,0x00} } ;

                initgraph(&GraphDriver,&GraphMode," ");

                outtextxy(125,0,"User define file pattern");

                for(i=0; i<=11;i++)

                    {

                        setfillpattern(&userpattern[i][0],getmaxcolor()-1);

                        bar(left,top,right,bottom);

                        left +=100,right +=100;

                        if(i==count)

                            {

                                left=50,top +=100;

                                right=100,bottom+=100;

                                count +=4;

                            }

                    }

        getch();

        closegraph();

    }

 

[예제 12-10] 원의 중심좌표가 (200,200) 반지름이 150인 원안에 이동함수를 사용하여 선을 그리는 프로그램.


#include <graphics.h>

#include <math.h>

void main()

    {

        int GraphDriver=DETECT,GraphMode;

        initgraph(&GraphDriver,&GraphMode," ");

        setcolor(7);

        circle(200,200,150);

        moveto(200,200);

        lineto(200,100);

        moverel(0,100);

        linerel(-50,90);

        getch();

        cleardevice();

        closegraph();

    }

 

 

[예제 12-11] 화면상에 사각형을 그리는 프로그램


#include <graphics.h>

#include <math.h>

void main()

    {

        int GraphDriver=DETECT,GraphMode;

        int x1=100,y1=100,x2=200,y2=200;


        initgraph(&GraphDriver,&GraphMode," ");

        setcolor(7);

        rectangle(x1,y1,x2,y2);

        getch();

        cleardevice();

        closegraph();

    }


+-------------+

| |

| |

+-------------+

 

[예제 12-12] 화면상에 원을 그리는 프로그램.


#include <graphics.h>

#include <math.h>

void main()

    {

        int GraphDriver=DETECT,GraphMode;

        int x=100,y=100,r=50;

        initgraph(&GraphDriver,&GraphMode," ");

        setcolor(7);

        circle(x,y,r);

        getch();

        cleardevice();

        closegraph();

    }

 

 

 

[예제 12-13] 화면상에 45 ~ 270도 범위의 호와 현을 그리는 프로그램.


#include <graphics.h>

#include <math.h>

void main()

    {

        int GraphDriver=DETECT,GraphMode;

        int x=100,y=100,r=50;

        initgraph(&GraphDriver,&GraphMode," ");

        setcolor(7);

        arc(x,y,45,270,r);

        getch();

        cleardevice();

        closegraph();

    }


 

[예제 12-14] 화면상에 여러개의 직사각형 내의 각각의 무늬를 그리는 프로그램.


#include <graphics.h>

#include <math.h>

void main()

    {

        int GraphDriver=DETECT,GraphMode;

        initgraph(&GraphDriver,&GraphMode," ");

        setcolor(7);


        setfillstyle(BKSLASH_FILL,WHITE) ;

        bar(0,0,100,100);

        setfillstyle(LTBKSLASH_FILL,WHITE) ;

        bar(150,0,250,100);

        setfillstyle(HATCH_FILL,WHITE) ;

        bar(300,0,400,100);

        setfillstyle(XHATCH_FILL,WHITE) ;

        bar(450,0,550,100);

        setfillstyle(INTERLEAVE_FILL,WHITE) ;

        bar(600,0,700,100);

        setfillstyle(CLOSE_DOT_FILL,WHITE) ;

        bar(150,150,250,250);

        getch();

        cleardevice();

        closegraph();

    }

 

 

top01.gif 12.4 그래픽 이미지의 저장 및 출력

그래픽 이미지의 저장 및 출력을 위해서 사용되는 함수는 다음과 같다.

 


setactivepage, setvisualpage, imagesize,

getimage, putimage , outtext,

outtextxy

top01.gifsetvisualpage()

setactivepage() 함수는 액티브 페이지의 텍스트 모드인 경우에 사용하며 폭이 40x80일 경우에 모드 제어 함수에 의해 지정되며 사용될 페이지를 생성하는 함수이다. setvisualpage() 함수는 텍스트 모드인 경우에 사용하여 액티브 페이지와 같은 값둁을 가지며 화면상에 출력되는 페이지를 선택하는 함수이다. 함수 선언 형식은 다음과 같다.

 


setactivepage(paeg) setvisualpage(page)

int page int page

 

여기서 page의 값은 0 또는 1이다.

top01.gifimagesize()

imagesize() 함수는 화면에 미미지의 크기를 비트로 저장하며 메모리 영역의 크기를 결정한다. 이 함수는 이미지의 크기가 64K로 제한되어 있다. 따라서 메모리를 관리하는 헤더화일 <alloc.h>를 이용한다. 선언 형식은 다음과 같다.

 


imagesize(left,top,right,bottom)

 

여기서 left,top,right,bottom은 화면의 왼쪽 모서리와 오른쪽 모서리의 좌표값을 말한다.

top01.gifgetimage(), putimage()

getimage() 함수는 화면으로 그린 도형의 데이타 값을 비트로 버퍼속에 저장시키는 함수이며 putimage() 함수는 버퍼 속에 저장된 비트값을 화면의 좌표로 출력하는 함수이다. 선언 형식은 다음과 같다.

 


getimage(x,y,buf)

putimage(x,y,top,op)

 

여기서 x,y는 저장되고 출력될 좌표값을 말하며 buf는 버퍼속의 메모리 값, op는 화면에 그리는 연산을 말한다. op의 내용은 각각 다음과 같다

 


변수

내 용

COPY_PUT

XOR_PUT

OR_PUT

AND_PUT

NOT_PUT

0

1

2

3

4

복사

배타 논리곱

논리합

논리곱

반전


top01.gif그래픽 모드에서 텍스트를 출력하는 함수

그래픽 화면에 텍스트를 출력하는 방법은 출력할 위치의 좌표를 지정하여 문자, 숫자를 출력한다. 텍스트 모드는 문자열 상수, 문자열 포인터 변수, 문자 배열을 지정할 수 있으며 지정된 화면상 내에 색채함수를 선택할 수 있으며 문자열을 이동, 확대, 축소할 수있다. 선언 형식은 다음과 같다.

 


outtext(str)

outtextxy(x,y,str)

 


settextstyle(font,direction,charsize)

 

여기서 x,y는 문자가 놓일 위치의 좌표값을 말하며 str은 문자열을 말한다. font, direction, charsize는 int형으로 font는 글자체형, direction은 문자의 위치 방법, charsize는 확대 축소값을 나타낸다.

 

[예제 12-15] 문자의 크기를 변화 시키는 함수를 이용한 프로그램


#include <conio.h>

#include <graphics.h>

#include <math.h>

void main()

    {

        int GraphDriver=DETE

        CT, GraphMode;

        char *str="Turbo-C";


        initgraph(&GraphDriver, &GraphMode, "");

        settextstyle(0,0,3);

        outtextxy(100,10,str);

        settextstyle(0,0,1);

        outtextxy(10,100,str);

        getch();

        closegraph();

    }

Turbo-C

Turbo-C

 




top01.gif 연 습 문 제

 

[문제 12-1] SPIRAL BAND를 그리는 프로그램


#include <graphics.h>

#include <math.h>

void main()

    {

        int i, j, color;

        int Center_X = 320, Center_Y = 100;

        int graph_drive, graph_mode;

        float distance = 0.1, sc = 5. / 12., x = 0., y = 90.;

        float co = 0., t = 0.;

        float c = (float) cos ((double) distance),

        s = (float) sin ((double) distance);

        graph_drive = DETECT;

        initgraph(&graph_drive, &graph_mode, "");

        moveto((int)(x + Center_X), (int)(sc * y + Center_Y));

        for(j = 1; j != 20; j++)

            {

                for(i = 1; i != 63; i++)

                    {

                        t = x * c - y * s;

                        y = y * c + x * s;

                        x = t;

                        co = co + 0.5;

                        color = (int)(fmod(co, 4.) * 10);

                        setcolor(color);

                        lineto((int)(x + Center_X), (int)(sc * y + Center_Y));

                    }

                y = y - 4.;

            }

        getch();

        closegraph();

    }

 

 

[문제 12-2] 데이타를 구조체로 정의하여 막대그래프를 생성하는 프로그램


#include <graphics.h>

#define X 100

#define Y getmaxy() - 100

#define MAX 80

struct data

    {

        char *month;

        int income;

    };

        struct data DATA[12]=

            {

                {"JAN", 77}, {"FEB", 80}, {"MAR", 82}, {"APR", 75},

                {"MAY", 72}, {"JUN", 65}, {"JUL", 60}, {"AUG", 64},

                {"SEP", 70}, {"OCT", 78}, {"NOV", 85}, {"DEC", 88}

            };

void main()

    {

        int i, x1, x2, Height;

        int graph_drive, graph_mode;

        graph_drive = DETECT;

        initgraph(&graph_drive, &graph_mode, "");

        for(i = 0; i < 12; i++)

            {


                Height = 120 * DATA[i].income / MAX;

                x1 = 40 * i - 16;

                x2 = 40 * i - 4;

                setcolor(i + 1);

                setfillstyle(SOLID_FILL, i + 1);

                bar3d(X + x1, Y - 60, X + x2, Y - (Height + 60),

                (x2 - x1) / 4, 1);

                outtextxy(X + x1 - 3, Y - 50, DATA[i].month);

            }

        getch();

        closegraph();

    }

 

 

[문제 12-3] 데이타를 구조체로 정의하여 파이차트(pie chart)를 그리는 프로그램


#include <graphics.h>

#define X 300

#define Y 150

struct data

    {

        char *name;

        int income;

    };

        struct data DATA[4]=

            {


                {"KIM", 27}, {"KWAK", 25}, {"CHOI", 17}, {"OOH", 31},

            };

void main()

    {

        int i, start, end, Height;

        int graph_drive, graph_mode;

        graph_drive = DETECT;

        initgraph(&graph_drive, &graph_mode, "");

        for(i = 0; i < 4; i++)

            {

                if (i == 0 ) start = 0;

                else start = end;

                end = start + (360 * DATA[i].income / 100);

                setcolor(i + 1);

                setfillstyle(i + 1, i + 1);

                pieslice(X, Y, start, end, 100);

                gotoxy(450, 60 * i);

                bar(450, 50 * i + 80, 500, 50 * i + 100);

                outtextxy( 505, 50 * i + 95, DATA[i].name);

            }

        getch();

        closegraph();

    }

 

 

[문제 12-4] 이웃하는 집을 그리고 색을 칠하는 프로그램


#include <graphics.h>

#include <math.h>

void Draw();

void main()

    {

        int graph_drive, graph_mode;

        graph_drive = DETECT;

        initgraph(&graph_drive, &graph_mode, "");

        setviewport(160,100,319,199,1);

        Draw();

        setviewport(0,100,160,199,1);

        Draw();

        getch();

        closegraph();

    }

void Draw()

    {

        rectangle(0, 0, 159, 99);

        line(20, 40, 40, 10);

        moveto(40, 10);

        lineto(140, 10);

        lineto(150, 35);

        lineto(150, 80);

        lineto(120, 85);

        line(120, 40, 140, 10);

        rectangle(20, 40, 120, 85);

        line(120, 40, 140, 10);

        rectangle(45, 65, 80, 85);

        line(0, 60, 20, 60);

        line(150, 60, 159, 60);

        setfillstyle(SOLID_FILL, RED);

        floodfill(130, 70, WHITE);


        setfillstyle(LINE_FILL, GREEN);

        floodfill(80, 30, WHITE);

        setfillstyle(BKSLASH_FILL, BROWN);

        floodfill(50, 70, WHITE);

        setfillstyle(LTSLASH_FILL, YELLOW);

        floodfill(30, 20, WHITE);

        setfillstyle(SOLID_FILL, CYAN);

        floodfill(130, 88, WHITE);

        rectangle(81, 65, 100, 75);

        setfillstyle(SLASH_FILL, MAGENTA);

        floodfill(88, 70, WHITE);

        setfillstyle(XHATCH_FILL, BLUE);

        floodfill(30, 50, WHITE);

    }

 

[문제 12-5] 각도를 변화시키면서 lineto() 함수를 이용하여 헥사곤(hexagon)을 변화시키는 프로그램


#include <graphics.h>

#include <math.h>

void main()

    {

        float XWMIN = -40, YWMIN = -10, XVMIN = 40, YVMIN = 40,

        s1 = 2, s2 = 2, l = 0, m = 160, xw = 49, yw = 0,

        xs, ys, xn, PI = 3.14159, SCF = 2.4, SF = 0.95,

        C = (float)cos((double)PI / 4),

        S = (float)sin((double)PI / 4),

        CN = (float)cos((double)PI / 36),


        SN = (float)sin((double)PI / 36);

        int i, j;

        int graph_drive, graph_mode;

        graph_drive = DETECT;

        initgraph(&graph_drive, &graph_mode, "");

        for(j = 1; j <= 50; j++)

            {

                if (j != 1) { xw = SF * xw * CN - SF * yw * SN;

                                yw = SF * xw * SN + SF * yw * CN;

                            }

                for(i = 0; i <= 8; i++)

                        {

                            xs = s1 * ( xw - XWMIN) + XVMIN + l;

                            xs = SCF * xs;

                            ys = s2 * (YWMIN - yw) - YVMIN + m;

                            if ( i == 0 ) moveto(xs, ys);

                            lineto(xs, ys);

                            xn = xw * C - yw * S;

                            yw = xw * S + yw * C;

                            xw = xn;

                        }

            }

        getch();

        closegraph();

    }

 

[문제 12-6] 자동차를 그린후 getimage() 함수와 putimage() 함수를 이용하여 자동차를 이동시키는 프로그램


#include <graphics.h>

void main()

    {

        int i;

        char image[8330];

        int graph_drive, graph_mode;

        graph_drive = DETECT;

        initgraph(&graph_drive, &graph_mode, "");

        setfillstyle(SOLID_FILL, RED);

        bar(25, 19, 80, 35);

        bar(25, 5, 50, 20);

        bar( 3, 33, 82, 35);

        setfillstyle(SOLID_FILL, BLUE);

        bar(32, 7, 48, 15);

        setcolor(GREEN);

        arc(25, 30, 90, 180, 20);

        circle(25, 35, 8);

        floodfill(25, 35, GREEN);

        circle(70, 35, 8);

        floodfill(70, 35, GREEN);

        getimage(1, 5, 85, 55, image);

        for (i = 1; i <= 600; i++) putimage(i, 5, image,

        COPY_PUT);

        getch();

        closegraph();

    }

 

[문제 12-7] 주어진 삼각형을 이동, 확대 및 회전시키는 프로그램


#include <graphics.h>

#include <math.h>

void Original_data();

void Draw();

void Move(int x, int y);

void Scale(float x_scale, float y_scale);

void Rotate(int angle);

struct data

    {

        float x;

        float y;

    };

struct data DATA[7];

void main()

    {

        int max_x, max_y;

        int graph_drive, graph_mode;

        graph_drive = DETECT;

        initgraph(&graph_drive, &graph_mode, "");

        max_x = getmaxx();

        max_y = getmaxy();

        setviewport(0, 0, max_x, max_y, 0);

        line(10, 10, 10, max_y);

        line(10, 10, max_x, 10);

        outtextxy(0, 0, "(0, 0)");

        outtextxy(max_x / 2, 0, "X ->");

        outtextxy(0, max_y / 2, "Y");

        outtextxy(0, max_y / 2 + 16, "|");

        outtextxy(0, max_y / 2 + 20, "v");


        Original_data();

        Draw();

        outtextxy(DATA[6].x, DATA[6].y, "Original");

        Original_data();

        Move(130, 150);

        Draw();

        outtextxy(DATA[6].x, DATA[6].y, "Move");

        Original_data();

        Scale(2, 1.3);

        Draw();

        outtextxy(DATA[6].x, DATA[6].y, "Scale");

        Original_data();

        Rotate(-25);

        Draw();

        outtextxy(DATA[6].x, DATA[6].y, "Roate");

        getch();

        closegraph();

    }

void Original_data()

    {

        DATA[0].x = DATA[5].x = 80;

        DATA[0].y = DATA[5].y = 150;

        DATA[1].x = DATA[2].x = DATA[0].x + 60;

        DATA[1].y = DATA[2].y = DATA[0].y;

        DATA[3].x = DATA[4].x = DATA[0].x + 30;

        DATA[3].y = DATA[4].y = DATA[0].y - 30;

        DATA[6].x = DATA[3].x + 30;

        DATA[6].y = DATA[3].y + 10;

    }

void Draw()

    {

        int i;


        for(i = 0; i <= 4; i+=2)

            {

                moveto(DATA[i].x, DATA[i].y);

                lineto(DATA[i + 1].x, DATA[i + 1].y);

            }

    }

void Move(int x, int y)

    {

        int i;

        for(i = 0; i <= 6; i++)

            {

                DATA[i].x = DATA[i].x + x;

                DATA[i].y = DATA[i].y + y;

            }

    }

void Scale(float x, float y)

    {

        int i;

        for(i = 0; i <= 6; i++)

            {

                DATA[i].x = DATA[i].x * x;

                DATA[i].y = DATA[i].y * y;

            }

    }

void Rotate(int angle)

    {

        int i;

        float radian = angle * 3.14159 / 180;

        for(i = 0; i <= 6; i++)

            {

                DATA[i].x = DATA[i].x * cos(radian) - DATA[i].y *

                sin(radian);

                DATA[i].y = DATA[i].x * sin(radian) + DATA[i].y *

                cos(radian);

            }

    }

 

댓글 2개:

  1. 우와, 그래픽 디바이스에 직접 접촉하는 물건인가요?

    답글삭제
  2. trackback from: won-으로 이어질 블로그링
    won-에 관한블로그를 요약한 것입니다.

    답글삭제