본문 바로가기
매트랩(Matlab)/매트랩 강의

[Matlab / 매트랩] 6. 3차원 도형그리기

by freezkim 2010. 2. 3.

[Matlab / 매트랩] 매트랩 강의 6번째  

6. 3차원 도형 그리기 

매우 아주 정말 오랜만입니다 

원래는 저번주에 올라왔어야 했는데...... 

저번 한 주는 정말 눈코뜰새없이 바빴네요 흐흑 

지금 쓰고있는 특허가 하나 있는데, 오늘까지가 완료여서 거기에 완전 매달려 있었어요ㅠㅠ흑흑 

뭐 결국 미루기는 했지만....=_= 

어찌됐건 비겁한 변명일 뿐입니다  

약간의 죄책감을 가지고 오늘은 조금 색다른 걸(?) 해볼까 해요. 

이번꺼는 뭐랄까 사람들이 잘 안쓰는 거랄까?? 일반적으로는 잘 사용하지 않는 내용을 다뤄볼 건데요. 

그냥 그래프 하는김에 요거까지 확 다 해버리고 이제 그래프와는 영영 빠이빠이 해버리자는....(될까?) 의미에서  

몰아치듯이 하는거에요 후후, 쇠뿔도 단김에, 떡본김에 제사, 도랑치고 가재잡고(...?) 
 

서론이 긴데요... 뭘 할꺼냐면!!! 

바로 저번에 보셨던 주전자 기억나시나요?? 

 

요런거 그리는 걸 한번 해볼까 해요. 

뭐 사실 쓰잘데기 없다고 느낄수도 있지만.... 네 별로 쓰잘데기 없습니다. 

하지만 재밌어 보이잖아요?? 

ㅋㅋ

아닌가
 

사실 쓰잘데기 없는건 아니에요. 시뮬레이션 같은데 써먹을 수도 있는거죠. 예를 들면 이런거? 

 
이건 광원 시뮬레이션이에요. 뭐 이런것도 가능하고, 

로봇 시뮬레이션이나 기구 시뮬레이션 같은 거 할려면 body를 그려줘야 되는데 그럴 때 요런 도형 그리기가 쓰이겠죠.....?? 아마. 

헤에 구경은 이쯤하고 이젠 진짜 도형을 한번 그려보자구요. 

제가 쓰는 도형 그리는 방법은 딱 하나밖에 없습니다. 

'patch' 라는 명령어를 쓰는건데요. 뭔가 감이 오시지 않나요? 뭔가 막 덕지덕지 붙은 느낌????? 흐흐 

요거 원리는 간단해요. 

1) 먼저 도형의 꼭지점 (x,y,z)를 행렬로 지정해주고요.

2) 꼭지점 세 점으로 이루어진(꼭 세점일 필요는 없습니다.) 면을 지정해줍니다. 

3) 그 다음은 매우 적절하게 patch 명령어를 살포시 적어주면 끝이 나버리는거지요. 어때요, 참 쉽죠? 

후후, 말은 쉬운데 실제 코드는 이전에 비해서는 조금 복잡합니다. 

일단 예를 한번 들어볼게요. 

>> vertex=[0 0 0; 0 1 0; 1 1 1];
>> face=[1 2 3];
>> patch('Faces',face,'Vertices',vertex,'Facecolor',[0.8 0.8 1]);
>> view(3);
>> grid on
 


자, 요러한 삼각형이 그려졌습니다.

 위의 코드를 하나하나 분석해 보면서 설명을 해보도록 할게요. 

1) 먼저 도형의 꼭지점을 지정을 합니다. 
    >> vertex=[0 0 0; 0 1 0; 1 1 1];
   : (0,0,0), (0,1,0), (1,1,1) 이라는 점 세개를 지정했습니다. 

2) 그다음 꼭지점 세개로 이루어진 면을 지정 합니다. 
    >> face=[1 2 3];
    : 1, 2 3은 각각 vertex의 첫번째 점, 두번째 점, 세번째 점을 선택해서 평면을 지정하겠다는 의미입니다.
     즉, 위에서 (0,0,0)  ,  (0, 1 0)   , (1, 1, 1) 점 세개를 연결해서 평면을 그리겠다. 이 말입니다

3) patch 명령어를 적절하게 써줍니다.  
    >> patch('Faces',face,'Vertices',vertex,'Facecolor',[0.8 0.8 1]);
   :patch는 그냥 쓰면 "꼭지점-면 지정"의 형식으로 인식을 하지 않습니다. '꼭지점-면 지정'의 형식으로 인식을 하게 하려면
    요 위에 작은 따옴표(' ') 안에 있는 주문(?)을 적어주셔야 해요.

    'Faces' 는 면의 정보를 가진 행렬을 입력할 때, 
    'Vertices'는 꼭지점 정보를 가진 행렬을 입력할 때,
    'Facecolor'은 면의 색깔을 지정해 줄때 쓰는 특성(?) 입니다. 

    일전에 plot에서 plot(x,y,'r') 등으로 색깔 지정해준 것과 같은 맥락으로 받아 들이시면 될것 같아요. 

    어찌되었건, 요 작은 따옴표에 들어있는건 토씨 하나도 틀려선 안됩니다!!!  

    patch 명령어가 작은 따옴표 안에 있는걸 입력 받아야만,
    그 작은 따옴표 옆에 데이터가 나타내는게 이거구나! 요러면서 받아들이기 때문이에요.
 

    앞에서 'Facecolor'는 설명하지 않았는데, 요건 일단 스크롤 압박이 좀더 느껴질때쯤 다뤄 보도록 합시다.
    일단은 쉽게쉽게 기초만!!
 

4) 적절하게 3D로 나타냅니다. 
  >> view(3); 
 그냥 patch를 치게되면 2차원으로 출력이 되게 됩니다. 요걸 3차원으로 보기 위해서는 view(3) 이라는 명령어를 입력해줍니다.
 요건 이해가 잘 가실거에요. 보다(view) 3차원으로 -> view(3)   

 만약에 view(2)를 치면? 2차원으로 보여지게 되겠죠ㅎ 

 view(4)는 4차원으로 보여주면 참 좋겠지만 못봅니다 에라떠요 
 grid on은 설명안할게요. 

흠 대략 이해가 가시나요?? 

여기서 중요한 것은, 점의 지정과, 면의 지정의 방법입니다. 특히, 면의 지정은. 몇번째 점을 연결한다. 는 형식이기 때문에 잘 이해가 안가실 수가 있어요. 

위에서는 면 하나만 있는 경우를 다뤘는데, 직사각형을 한번 다뤄보면서 설명을 해보도록 할게요. 

 
자, 요런 직사각형이 하나 있습니다.

 먼저 꼭지점 8개를 지정해야 되겠죠? 

1번 점부터 차례대로 8개를 지정해볼게요.. 알아보시겠죠 그림? ㅠ 

 1번은 (0,0,0) 2번은 (2,0,0), 3번은 (2,2,0), 4번은 (0,2,0) ..... 순서대로 입니다. 

vertex=[0 0 0 ; 2 0 0; 2 2 0; 0 2 0; 0 0 1; 2 0 1; 2 2 1; 0 2 1]; 

자 그림 이제 면을 한번 지정해볼게요. 

점을 선택하는 순서대로 직선이 그어진다고 생각하면 됩니다. 

즉, 1 2 6 5 번 점을 선택하면 1,2,6,5 점으로 이루어진 면을 그리겠다. 요말이죠. 

주의하실점은!! 1,2,5,6을 선택한다고 하시면 직선으로 그려지게 되서 요런 모양이 나오게 됩니다.
                

네, 까다롭죠?? 저도 무지 애 많이 먹었습니다 ㅠㅠㅠㅠ 면은 요렇게 지정했어요.

face=[1 2 3 4; 1 2 6 5; 2 3 7 6; 3 4 8 7; 1 4 8 5; 5 6 7 8];

그리고 patch 명령어 쓰기! + 3d로 보기

>> patch('Vertices',vertex,'faces',face)
>> view(3) 

지금은 색깔을 지정 안해줬는데요. 지정 안해주면 기본적으로 검은색이 나옵니다.

색깔까지 함께 해줄려면  

>> patch('Vertices',vertex,'faces',face,'Facecolor',[0.8 1 0.8]) 

'Facecolor'라고 입력해서 색깔을 한번 줘볼까? 라고 넌지시 말을 건넨 다음에 

[0.8 1 0.8] 의 색깔을 칠하자!! 요렇게 입력을 해준거죠. 

여기서 [0.8 1 0.8]의 의미는 각각 -> [ R(빨간색 농도) G(녹색 농도) B(파란색 농도)] 를 의미합니다. 

저는 녹색 농도를 짙게 줬으니 녹색 직사각형이 나오게 된거죠. 

위의 삼각형 예제에서는 [0.8 0.8 1] 이었으니 파란색 삼각형이 나오게 된 거구요.

 

--------------------------------------------------------------------------------

***조금 더 해보기*** 

네 위의 것을 무리없이 하셨다면 조금 더 만용을 부려봅시다. 요번엔 좀더 어려울 테니 각오하시는게 좋으실듯? 흑 ㅠ 

크게 두가지를 더 다뤄볼까 하는데요.

!!면마다 색깔을 다르게 넣어주기

!!다른 그림 파일로 그려서 데이터만 넘겨주기 

요렇게 두가지를 더 해볼까 합니다. 

1) 첫째는 면마다 색깔을 다르게 넣어주는 겁니다 !! 이런식으로 말이죠. 

 

요건 일일이 면마다 색깔을 지정해 준 다음에 색깔을 입힌거에요. 여기선 위의 patch에 한가지 특성을 더 추가하게 됩니다.
제가 입력한 명령어를 보면서 설명을 해 드릴게요. 

>> vertex=[0 0 0 ; 2 0 0; 2 2 0; 0 2 0; 0 0 1; 2 0 1; 2 2 1; 0 2 1];
>> face=[1 2 3 4; 1 2 6 5; 2 3 7 6; 3 4 8 7; 1 4 8 5; 5 6 7 8];

>> Ic=[1 0.8 0.8; 0.9 0.8 0.8 ; 1 1 0.8; 0.8 1 0.8; 0.8 0.8 1; 0.7 0.7 1];

>> patch('Vertices',vertex,'faces',face,'FaceVertexCData',Ic,'Facecolor','flat')

>> grid on
>> axis([-1 3 -1 3 0 2])
 

여기 Ic 라는 매트릭스가 생기고, 'FaceVertexCData'라는 특성이 하나 더 지정되었죠? 'Facecolor' 다음에도 'flat'이란게 붙었고 말이죠.

복잡합니다 흑 ㅠ
먼저 Ic 라는 명령어는  [R G B] 색깔 데이터를 face에서 지정한 면마다 따로따로 넣어주는 데이터 행렬입니다.
즉, face에서 [1 2 3 4] 로 이루어진 면은 [1 0.8 0.8] 의 색깔 정보를
                  [1 2 6 5] 로 이루어진 면은 [0.9 0.8 0.8]의 색깔 정보를  .....
와 같은 식이죠.

요런 색깔을 일일이 면으로 받아주겠다는 걸 알게하기 위해, patch에서 'FaceVertexCData' 를 쓰고, 옆에 Ic 라는 색깔 데이터를 넣어주게 됩니다.

데이터 입력만 해주는 걸로 끝나면 좋겠지만, 이게 좀 거시기해요. 요 데이터를 면에 칠해주기 위해서는.... 칠하는 명령어가 필요한데그게 뒤에 있는 'Facecolor' 입니다. 'flat' 이란 것의 의미는 앞의 색깔 데이터를 이용해라. 뭐 요런 의미로 받아들이시면 될것 같에요. 

그러니깐 명령어 구조가  

색깔 데이터 입력해라('FaceVertexCDtata') -> 그래 넣어주마 (Ic)

-> 면을 색칠해볼까? ('Facecolor') -> 그래 앞에 데이터 있으니깐 그거 써먹어!! ('flat') 

요런 식인 겁니다. 흐흐ㅠ 이해 가시나요ㅠㅠ 

저도 요건 쓰다보면 까먹고 까먹고 해서 항상 help보면서 한답니다ㅠ 

 

2) 둘째는 일일이 도형을 데이터 정보로 넣어주기 힘드니ㅠㅠㅠㅠ 다른 그림 파일로 그려서 넣어주는 방법입니다.
(위의 주전자나 광원 시뮬레이션 같은 경우는 다른걸로 그려서 넣어준거에요.) 

저의 경우는 3ds max라는 프로그램을 이용해서 그림을 그렸는데요. 다른 거도 아마 연동이 될 수 있을지도?? 

어찌됐건 주전자 예를 한번 볼게요. 

3ds max라는 프로그램으로 주전자를 그리면 요런 모양이 됩니다. 기본적으로 있는 도형이에요 하핫-_-;; 

 

그다음은 file->export->*.ASE 형태로 저장해 주시구요. 

 세번째로는 ASE 파일의 데이터를 적절히 잘라주어서 메모장 파일로 만드는 겁니다.

 

 

 

그다음으론 매트랩에서 메모장 파일을 불러 들여서, Vertex, Face, 정보로 입력한 후  

>> s=fopen('vertex.txt','r');
>> data=fscanf(s,'   *MESH_VERTEX    %g %g %g %g ' ,[4 inf]);
>> vertex=data';
>> vertex=vertex(:,2:4);
>> s2=fopen('face.txt','r');
>>data2=fscanf(s2,'   *MESH_FACE    %g:    A:    %g B:    %g C:    %g AB:    %g BC:    %g CA:    %g  *MESH_SMOOTHING %g  *MESH_MTLID %g',[9 inf]);
>> data2=data2';
>> face=data2(:,2:4);
>> faces=face+1;
 

(여기서 파일 입출력이 들어가기 때문에 이부분은 생략할게요. 나중 강의에서 다루도록 하겠습니다ㅠ) 

 

위의 patch 명령어를 쓰는거죠. 

>> p=patch('faces',faces,'vertices',vertex,'Facecolor',[1 1 0.8]); 

요건 걍 이런것도 있다. 정도로만 알아두시면 될 것 같아요. 사실 저도 지금은 별로 쓰지 않는 거기도 하고.. 나중에 로봇 시뮬레이션 하면 좀 쓸려나 모르겠어요. 여튼 일일이 입력하기 짜증나고 힘들고 하니깐 다른걸로 그려서 매트랩으로 그리는 거죠. 

그럼 매트랩으로 그린 정보를 가지고 Rotation, Traslation등과 같은 변환 메트릭스를 통해 시뮬레이션을 하면 되겠죠?ㅠ 

흐흐 일단 이정도로 일단락 하기로 합시다. 어정쩡한 급마물...  

큭, 추석 잘보내세요 후후 







 

Tip!!

patch와 관련된 특성들은 help->matlabhelp -> search 탭 -> patch입력 하여 검색후 
-> Patch Properties를 보시면 설명이 나와 있습니다.