[아두이노] 조이스틱+processing 3D 도형 회전(2)

IOT/아두이노|2019. 4. 28. 09:00

[아두이노] 조이스틱+processing 3D 도형 회전(2)



지난 시간에는 아두이노는 아두이노 제어 코딩을 하고 processing은 아두이노에서 전송된 방향키 data를 시리얼통신 받아와서 3D 도형 회전을 하였다면 오늘은 prcoessing에서 3D 도형 뿐 아니라 아두이노 코딩까지 전부 담당하는 코딩을 살펴보도록 하겠습니다.


1. 아두이노 소스



지난 시간에 아두이노 방향키를 만든 소스입니다. 시리얼모니터로 해당 방향 알파벳을 출력한 소스인데 processing 코딩에 그대로 복사해서 이식할 예정입니다.

const int AXIS_X = A0;
const int AXIS_Y = A1;
const int SW_P = 3; 
 
void setup() {
  Serial.begin(9600);
  pinMode(SW_P,INPUT_PULLUP);
}
 void loop() {
  //X축 방향값
  if(analogRead(AXIS_X)<=300){
    Serial.println('a');
  }
  else if(analogRead(AXIS_X)>=700){
    Serial.println('d');   
  }
  //Y축 방향값
  if(analogRead(AXIS_Y)<=300){
    Serial.println('w');      
  }
  else if(analogRead(AXIS_Y)>=700){
    Serial.println('s');
  }
  delay(20);
}

2. processing으로 옮기기



위 아두이노 기본 방향키 값을 구하는 로직을 processing으로 전부 가져 오겠습니다.
지난 시간의 processing 코딩한 소스에다가 옮겨야 하니깐 우선 원래 소스는 다음과 같습니다.

[processing 소스]

import processing.serial.*;

Serial myPort;

int x=0;
int y=0;

void setup() {

    println(Serial.list());
    myPort = new Serial(this, Serial.list()[0], 9600);
    myPort.bufferUntil('\n');
    noStroke();
    size(600,600,P3D);
    
} 

void draw() {  
    background(0); //배경색
    lights();  //조명

    pushMatrix();  //Start
    fill(0,255,0); //채우기
    translate(width/2,height/2,-100); //이동
    rotateX(radians(y)); //x축 회전
    rotateY(radians(x)); //y축 회전
    
    box(200,100,200); //상자
    popMatrix(); //End
}
 
void serialEvent(Serial p) { 
  String inString = myPort.readStringUntil('\n');
  char ch=inString.charAt(0);
    
  println(ch);
  
  if (ch == 'w') {
      y+=1;
  } 
  else if (ch == 's') {
     y-=1;
  } 
  else if (ch == 'a') {
     x-=1;
  } 
  else if (ch == 'd') {
     x+=1;
  }
}

아두이노 함수들을 사용하기 위해서는 다음과 같은 과정이 필요합니다.

아두이노 라이브러리를 import 해서 객체 변수로 하나 만들어야 합니다.

[ processing에서 아두이노 코딩 ]

import cc.arduino.*;
Arduino arduino;

Arduino arduino;

arduino = new Arduino(this, Arduino.list()[0], 57600); //인스턴스화
    

아두이노 소스코딩 부분에 앞에 arduino 객체변수를 접근자로 연결해서 바꿔주시면 됩니다.

[아두이노 소스랑 processing 소스를 결합]을 하면 다음과 같습니다. const 상수형 표현은 processing에서 에러가 발생하더군요. 그래서 int형으로 만들었습니다.스위치 SW_P 변수로 사용준비만 해놓기만 했고 실제로 사용하지 않습니다. 나중에 이 키값은 3D box 의 색상을 변경하는 코딩을 여러분들이 한번 IF문을 써서 해보세요.

import processing.serial.*;
import cc.arduino.*;


Arduino arduino;

int AXIS_X = 0;
int AXIS_Y = 1;
int SW_P = 3; 

int x=0;
int y=0;

void setup() {  // this is run once.   

    println(Serial.list());
    arduino = new Arduino(this, Arduino.list()[0], 57600);
    arduino.pinMode(SW_P,Arduino.INPUT_PULLUP);

    size(600,600,P3D);
    noStroke();    
} 

void draw() {  
    
    move();
    
    background(0); //배경색
    lights();  //조명

    pushMatrix();  //Start
    fill(0,255,0); //채우기
    translate(width/2,height/2,-100); //이동
    rotateX(radians(y)); //x축 회전
    rotateY(radians(x)); //y축 회전
    
    box(200,100,200); //상자
    popMatrix(); //End
}
 
void move() { 
  int axisX = arduino.analogRead(AXIS_X);
  int axisY = arduino.analogRead(AXIS_Y);  
  
  //X축 방향값  
  if(axisX <= 300){
    x-=1;
  }
  else if(axisX >= 700){
    x+=1;
  }
  //Y축 방향값
  if(axisY <= 300){
    y-=1;
  }
  else if(axisY >= 700){
    y+=1;
  }
  delay(20);
}

따로 방향키 알파벳을 만들 필요 없고 시리얼 호출 함수명을 move()함수명으로 사용자 정의 함수로 변경 했습니다. 아날로그 핀이니깐 0,1번 핀으로 아날로그로 읽으면 A0, A1핀의 값을 읽습니다. 방향키 알파벳 자리에 x, y 변수값을 해당 조이스틱의 방향으로 증감시키면 됩니다.

아마 이 코딩이 지난 시간에 비해 훨씬 편한 코딩인 것 처럼 보일 꺼에요. 아두이노에서 명령을 내린 코딩을 processing으로 전부 가져와야 하니깐 좀 번거롭고 코딩이 될 수 있스니다. 나중에 processing이나 아두이노 코딩이 복잡해지고 길어지면 코딩이 산만해 질 가능성이 있기 때문에 아두이노는 아두이노 코딩을 하고 processing은 processing 코딩을 하는게 좋습니다.

3. 실행 과정


[회로도]


회로도는 동일합니다.

[1단계] : 아두이노는 processing이 사용할 수 있는 조건으로 펌웨어 해야합니다. "Firmata->StandardFirmata" 업로드 시키면 됩니다. 그러면 processing에서 아두이노를 제어할 수 있습니다.




[2단계] : processing에 아두이노+processing 가 합쳐진 소스를 복사해서 붙여 넣으시면 됩니다. 아래 이미지는 기존 소스에서 지워야 했던 시리얼객체변수가 이미지에 남아 있네요. 지웠어야 했는데 오의티네요.


[3단계] : processing 실행하시면 윈도우창이 뜨면서 3D box가 나타납니다. console창에는 com넘버 출력되고 3D box가 정상적으로 출력되면 제대로 실행 된거라 생각히시면 됩니다.


4. 결과


폰으로 촬영하려다 화질이 구려서 포기 했네요. 아래 움직이는 이미지는 어제 사용한 아미지가 아니고 다시 pc 녹화한 영상입니다. 옆에 코딩 소스를 보시면 Arduino 객체가 선언되어 있는 걸 보실 꺼에요. pc 실행 영상만 녹화했습니다. 정상적으로 조이스틱에 따라 3D box가 회전하네요.


마무리


원래는 다른 포스트를 할 예정이였는데 processing은 두가지 방식으로 아두이노를 접근하기 때문에 어쩔 수 없이 두개의 포스트로 나눠서 오늘까지 쓰게 되었네요. 추가적으로, 한번 Bluetooth를 스마트폰에 연결해서 스마트폰으로 조정한 값을 토대로 processing 3D box를 회전를 해보셨으면 합니다. 이건 포스팅 하지 않겠습니다. 금요일 소스에서 스마트폰에서 방향키 값을 Bluetooth로 통해서 아두이노에 시리얼통신 한 값을 다시 pc에 시리얼모니터로 출력하는 문장으로 보내면 그 값을 processing이 읽어서 회전 시키면 되기 때문입니다. 금요일 소스에서 조이스틱 부분 빼고 Bluetooth통신으로 값을 읽고 Serial 통신으로 값을 보내면 끝납니다.

어렵지 않으니깐 한번 해보셨으면 하네요.

댓글()

[아두이노] 조이스틱+processing 3D 도형 회전(1)

IOT/아두이노|2019. 4. 27. 09:00

[아두이노] 조이스틱+processing 3D 도형 회전(1)



오늘은 조이스틱의 키 값을 가지고 지난 시간에 포스트한 3D 도형을 회전시키는 실험을 해보겠습니다. 참고로 오늘 접근 방식은 아두이노는 기존 조이스틱 제어 코딩을 그대로 동작하고 processing에서 조이스틱을 제어한 값을 시리얼통신을 통해서 값을 받아 3D 도형을 회전 시킵니다. 즉, 아두이노는 아두이노 역할에 충실하고 processing은 processing의 역할을 충실한 코딩으로 생각하시면 됩니다.


1. 아두이노 소스


지난 시간에 아두이노 방향키를 만든 소스입니다. 시리얼모니터로 해당 방향 알파벳을 출력한 소스인데 그대로 적용할 예정입니다.

const int AXIS_X = A0;
const int AXIS_Y = A1;
const int SW_P = 3; 
 
void setup() {
  Serial.begin(9600);
  pinMode(SW_P,INPUT_PULLUP);
}
 void loop() {
  //X축 방향값
  if(analogRead(AXIS_X)<=300){
    Serial.println('a');
  }
  else if(analogRead(AXIS_X)>=700){
    Serial.println('d');   
  }
  //Y축 방향값
  if(analogRead(AXIS_Y)<=300){
    Serial.println('w');      
  }
  else if(analogRead(AXIS_Y)>=700){
    Serial.println('s');
  }
  delay(20);
}

2. processing 소스


지난 시간에 3D box를 제어한 포스트에서 다룬 소스를 기반으로 아두이노의 시리얼 통신 값을 가지고 3D box를 제어 해보기 위해서 몇가지 지난 소스에서 수정을 해야 합니다.

복습 : 시리얼 통신



시리얼통신을 사용하기 위해서는 Serial를 프로세싱에 import해야 합니다. 그리고 사용 할 객체 변수를 하나 선언해야겠죠.

import processing.serial.*;

Serial myPort;  

다음으로 myPort를 인스턴스화 해야 합니다.

 println(Serial.list()); //연결된 포트정보
 myPort = new Serial(this, Serial.list()[0], 9600); //시리얼통신 세팅

연결된 포트정보를 list()함수로 찾을 수 있고 그 정보를 시리얼모니터로 출력합니다. 그리고 myPort는 객체변수를 선언했다고 해서 바로 사용되는게 아닙니다. 객체변수 선언은 비유로 들자면 껍때기만 만들어 놓은 거고 인스턴스를 해야 합니다. 할당한다는 의미로 생각하면 될 듯 싶네요. 비유로 알맹이를 채운다고 생각하면 좋을 듯 싶네요.

이렇게 해서 시리얼통신의 준비 작업은 끝났습니다.

다음으로 시리얼통신에서 들어온 데이터를 읽는 방법은 두가지 방법이 있습니다. 아두이노에서 시리얼통신으로 읽는 방식과 동일하게 코딩하는 방법과 processing 자체에서 시리얼통신에서 데이터가 들어오면 자동으로 호출되는 함수가 있습니다. 두번째 호출함수로 코딩을 해보겠습니다.

void serialEvent(Serial p) { 
    명령;
}

SerialEvent()함수가 바로 시리얼통신으로 데이터가 들어오면 바로 호출되는 함수입니다.

void serialEvent(Serial p) { 
  String inString = myPort.readStringUntil('\n');
  char ch=inString.charAt(0);
}

시리얼 통신에서 일부러 문자열로 받았습니다. myPort.readString()함수는 문자열로 읽는 함수입니다. 여기서 myPort.readStringUntile('\n') 함수는 찾고자 하는 인자가 없을 때 null을 반환합니다. 문자열 라인 단위로 읽는다고 생각하면 될 듯 싶네요.

참고로, 아두이노에서는 시리얼통신으로 println('a') 함수로 보내면 "a\n"이렇게 전송되게 됩니다. 받는 쪽에서 만약 문자니깐 함수를 myPort.readChar() 함수를 쓰게 되면 한 글짜씩 개별로 읽게 됩니다. 'a'라는 문자를 보냈지만 추가로 옆에 기호까지 같이 보내지기 때문에 Char으로 읽으면 안됩니다. 나중에 여러개 값을 한번에 보낼 때를 사용하시라고 String 문자열로 읽겠습니다.
'a'라는 한글자지만 문자열이기 때문에 해당 글자를 한글자 문자로 읽어서 변수에 저장하겠습니다. charAt(0)으로 0번째 위치의 문자를 읽는 함수인데 'a'라는 문자를 읽게 됩니다. 그걸 char 문자 변수에 저장하면 되겠죠.

진짜 번거로운 과정을 거쳐서 코딩을 했네요. 그 이유는 나중에 여러분들이 자이로센서같은 것을 다루게 되면 한번에 x,y,z 값을 받아서 읽게 되는데 이때 문자열로 읽고 해당 위치의 값만 빼내서 제어하는데 활용하시라고 미리 이렇게 번거로운 코딩을 하게 되었네요.

시리얼 통신에서 데이터를 읽는 함수의 종류는 다양합니다. 그 다양한 함수들은 위에 링크한 라퍼런스을 보고 한번 여러분들이 따로 코딩해 보셨으면 합니다.

추가로,

inString = trim(inString);

문자열의 시작과 끝에서 공백 문자를 제거하는 함수입니다.("nbsp" 제거) 이 명령라인을 추가해 주시면 더 안정적으로 데이터를 읽겠지만 실험에서는 그냥 사용하지 않았네요. 이런 함수가 있다는 정도만 이해하시고 나중에 활용해 보세요.

ch변수에 겨우 방향키 값을 저장할 수 있게 되었습니다. 지난 3D box 제어에서 키보드로 제어했던 것을 기억하실 지 모르겠네요.

[ 키보드 제어 원 소스]

void keyPressed() {
  if (key == CODED) {
    if (keyCode == UP) {
      y+=1;
    } 
    else if (keyCode == DOWN) {
      y-=1;
    } 
    else if (keyCode == LEFT) {
      x-=1;
    } 
    else if (keyCode == RIGHT) {
      x+=1;
    }
  }
  else if (key == 'z' || key == 'Z') {
      z+=10;
  } 
  else if (key == 'x' || key == 'X') {
      z-=10;
  } 
}

여기서, 수정을 하면은 다음과 같습니다.

void serialEvent(Serial p) { 
    String inString = myPort.readStringUntil('\n');
    char ch=inString.charAt(0);
    println(ch); //시리얼모니터로 방향키 값 출력
    
    if (ch == 'w') {
        y+=1;
    } 
    else if (ch == 's') {
        y-=1;
     } 
     else if (ch == 'a') {
        x-=1;
     } 
     else if (ch == 'd') {
        x+=1;
     }  
}

여기서는 X, Y축을 한꺼번에 if~ else if문으로 표현했습니다. 지난 시간에 방향키 값을 만들 때는 X축과 Y축을 따로 if문을 했는데 여기서 묶여서 처리한 이유가 뭘까요. 방향키 ch변수에는 하나의 값만 존재합니다. 하나의 값만 순서대로 읽어오기 때문에 X,Y축을 구별 안하고 읽어온 하나에 값에 대한 하나의 동작만이 필요하기 때문에 선택문으로 전부 연결한 것이죠.

if문은 상황에 따라 맞게 의미를 이해하시고 사용하셔야 합니다.

전체적으로, 코딩을 하면 아래와 같습니다.

import processing.serial.*;

Serial myPort;

int x=0;
int y=0;

void setup() {

    println(Serial.list());
    myPort = new Serial(this, Serial.list()[0], 9600);
    myPort.bufferUntil('\n');
    noStroke();
    size(600,600,P3D);
    
} 

void draw() {  
    background(0); //배경색
    lights();  //조명

    pushMatrix();  //Start
    fill(0,255,0); //채우기
    translate(width/2,height/2,-100); //이동
    rotateX(radians(y)); //x축 회전
    rotateY(radians(x)); //y축 회전
    
    box(200,100,200); //상자
    popMatrix(); //End
}
 
void serialEvent(Serial p) { 
  String inString = myPort.readStringUntil('\n');
  char ch=inString.charAt(0);
    
  println(ch);
  
  if (ch == 'w') {
      y+=1;
  } 
  else if (ch == 's') {
     y-=1;
  } 
  else if (ch == 'a') {
     x-=1;
  } 
  else if (ch == 'd') {
     x+=1;
  }
}

3. 실행 과정


[회로도]


[1단계] : 아두이노 IDE에 방향키 소스를 복사해서 붙여 넣으시고 화살표에 업로드 버턴을 누르면 아래 정상적으로 처리되면 업로드 완료라고 뜹니다.


[2단계] : 시리얼모니터로 결과 검사



정상적으로 방향키값이 시리얼모니터로 출력되는 것을 확인 하실 수 있습니다.

[3단계] : processing에 오늘 수정한 코드를 복사해서 붙여 넣으시고 화살표 실행 버턴을 누르시면 아래 그림처럼 console창에 방향키값이 정상적으로 출력되는 것을 확인 하실 수 있을 겁니다.



[4단계] : processing에서 만든 윈도우창이 뜨면서 3D box가 보여지는데 조이스틱으로 조정을 하면 이 3D box가 움직이는 걸 확인 하실 수 있을 꺼에요.


4. 결과


processing에서 실제로 조이스틱을 조정하면 움직이는 이미지 입니다.


실제 폰으로 촬영한 영상으로 살펴 봅시다.


만약, 여러분들이 processing를 좀 더 깊게 공부하시면 아두이노와 processing를 연동한 재밌는 작품들을 만드실 수 있을 거라 생각됩니다.

마무리


이렇게 시리얼통신을 통해서 읽은 데이터 값으로 processing 제어하는 실험을 하였습니다. 예전에는 processing에서 아두이노를 제어 했다면 반대로 아두이노에서 processing를 제어한 실험인데 그렇게 어렵지 않죠. 여기서 부터 출발하여 좀 더 다양한 시각화 표현을 processing 에서 코딩하면 좀 더 멋진 작품으로 만들어 질 수 있습니다.

여러분들도 한번 다른 모형을 만들어서 제어를 꼭 해보셨으면 합니다. 최대한 의미 전달을 목적으로 코딩을 최소화 하기 위해서 box()함수로 상자도형을 간단히 제어를 했짐나 좀 더 멋진 모형을 만들어서 멋진 작품을 만드셨으면 하네요.

댓글()

[아두이노] processing 3D 도형 제어

IOT/아두이노|2019. 4. 25. 09:00

[아두이노] processing 3D 도형 제어 


예전에 잠깐 아두이노와 연동하는 processing을 소개 한 적이 있습니다. 오늘은 아두이노 부분을 제외하고 간단히 processing에서 키보드와 마우스로 도형을 제어하는 원리를 소개하려고 합니다. 이부분을 어느정도 이해하시면 나중에 아두이노에서 제어값을 입력된 값으로 해서 processing 이미지를 제어 할 수 있기 때문입니다. 오늘 다루게 될 키보드와 마우스가 나중에 아두이노로 대체하면 재밌는 표현들을 할 수 있기 때문에 관심을 가져줬으면 하는 마음으로 포스팅을 합니다.

1. processing 3D box() 도형 그리기


[복습]

void setup() {  
  한번만 수행;
}
void draw() { 
  무한 반복 수행;
}

아두이노랑 구조가 비슷하다고 했죠. setup()은 한번만 수행되는 초기화 작업을 코딩하고, draw()은 계속 그리는 무한 작업 코딩을 담당합니다.

void setup() {  
    
    size(600,600,P3D); //창사이즈
    noStroke();  //테두리없음

//  frameRate(30); //초당 프레임
} 
void draw() {  
     background(0); //배경색
}

추가적으로 초기 설정하는 함수들이 있는데 다 생략하고 딱 두개만 사용합니다. 윈도우 창이 하나 생성되는데 size() 함수로 윈도우 창 만듭니다. 여기서, "P3D" 3D Rendering 모드입니다. "OPENGL"로 선언해도 됩니다. 참고로 opengl은 import 선언이 필요하지만요. 그리고 테두리를 그리지 않는 noStroke()함수를 사용합니다. box 그렸는데 테두리가 보기 흉해서 테두리를 지웠네요.

배경색은 background(0)로 검정색으로 했네요. 아래 그림은 위 코딩의 결과입니다.


다음으로,

void draw() {  
    background(0); //배경색
    lights();  //조명

    pushMatrix();  //Start
    fill(0,255,0); //채우기
    translate(width/2,height/2,-100); //이동
    box(200,100,200); //상자
    popMatrix(); //End
}

옆에 주석을 다 달아 놓았습니다. 배경색은 검정색으로 하고 lights() 조명효과를 나타냅니다. 이미지 도형을 만들면 그 이미지에 light를 비추는 효과라고 생각하시면 됩니다.

fill()은 그리는 도형에 어떤 색을 채울것인지 지정하는 함수입니다. 즉, fill() 함수에 의해서 다음에 그려진 도형의 표면의 색이 결정됩니다. 사각형을 그리면 사각형 면의 색이 fill()함수의 색으로 채워진다고 생각하시면 됩니다.

pushMatrix(), popMatrix()함수가 있는데 스텍, 행렬의 의미를 이해하고 있어야 하지만 설명을 해도 쉽게 의미를 전달하기 어렵습니다. 다음으로 약식 꼼수 의미로 이해해 주셨으면 합니다. 저 함수가 나오면 push랑 pop은 한쌍이라고 생각하세요. 그리고 그리는 영역으로 push 시작위치에서 pop은 그리기 끝나는 위치라고 생각하세요. push~pop사이의 그리기 명령함수는 그 영역안에서만 독립적으로 적용된다고 생각하시면 될 듯요.


위 그림으로 다시 설명하면은 draw()에서 한장에 종이에 다가 그림을 그린다고 생각하시면 push~pop함수가 있으면 그 부분은 새로운 종이로 독립적인 영역의 그림을 그린다고 생각하시면 됩니다. 여기서, draw라는 메인 종이 위헤 새로 그린 종이를 붙이는 느낌으로 이해하시면 될 듯요. push~pop 안에 또다른 push~pop이 나오면 밖에 push~pop은 부모라고 생각하시고 부모 종이 위에 자식 종이가 두장 있다고 생각하시면 됩니다. 이때 자식 종이들은 각각 독립된 영역으로 A종이에 그리는 명령은 B종이에 영향을 줄 수 없고, B종이에 그리는 명령은 A종이에 영향을 줄 수 없는 독립된 영역으로 보시면 됩니다. 하지만 부모 종이에서는 자식 A, B가 둘 다 포함되어 있기 때문에 부모 종이에서 그리는 명령은 A, B 종이에 영향을 주게 됩니다.

왜! 이렇게 번거롭게 push~pop를 사용하느냐면 한두개의 도형을 그릴 때는 상관 없지만 다수의 도형을 그리고 배치하고 개별적인 도형들이 움직이거나 변화가 일어나게 코딩할려면 push~pop이 없이 그냥 한다면 어렵습니다. 그리는 명령을 매번 일일히 변화를 줘야 하기 때문이지요. 한장의 종이에 자동차 그림을 그린다면 한번에 전체를 다 그려야 합니다. 엔진, 바퀴, 핸들 등등의 각각의 부품들을 한번에 한장에 다 그려야 하기 때문에 그리고 나면 다시 엔진이 맘에 안든다고 엔진을 바꿀려고 하면 수정하기도 힘들고 하나를 변경하면 그 영향이 전체에 가기 때문에 무척 힘든 작업이 됩니다.

하지만 push~pop은 각각의 엔진이면 엔진 바퀴면 바퀴를 독립적으로 그리고 한장에 종이에 독립적으로 그림 그림을 가져와서 해당 위치에 붙이기만 하면 조립을 쉽게 완성할 수 있습니다. 나중에 엔진을 바꾸고 싶다면 엔진만 다시 그려서 해당 위치에 붙이면 쉽게 변경할 수 있게 됩니다.

한마디로 말하면 각 그림을 캡슐화 한다고 생각하시면 됩니다.

다시 설명드리면,


위 그림을 그리기 위해서 push~pop이 없다면 한개의 좌표계에서 몸체와 2개의 바퀴를 3D공간 좌표계에서 위치 좌표를 일일히 이동시켜서 그 위치에서 그림을 그려야 합니다. 한개라도 변경되는 일이 발생하면 전체에 영향을 주게 됩니다. 그리고 바퀴만 회전시키고 싶을때 제어하기가 무자 까다롭습니다.

하지만 push~pop을 사용하면 독립된 3D좌표계에서 독립적으로 그리게 됩니다.


위 그림처럼 계별적 3D 좌표계에서 도형을 그린 다음에 메인 draw() 이 그림을 push~pop으로 배치만 하면 됩니다. 나중에 원의 색을 바꾸고 싶으면 push~pop안에 fill()값만 바꾸면 색을 쉽게 변경이 됩니다. 바퀴가 두개인데 복제도 가능해지죠. 바퀴를 회전 시키고 싶으면 push~pop에 rotate()함수만 삽입하면 됩니다. draw()함수 내에서 하나의 좌표에게서 push~pop의 개별좌표계로 독립된 표현이 된다고 생각하시면 되겠습니다.

3D 포스트가 아닌데 삼천포로 빠지고 말았네요. 나중에 아두이노와 연동해서 뭔가 화려한 3D 관련 표현을 하실 수 있으니깐 가장 중요한 push~pop을 이야기 하다보니 좀 설명이 길어 졌네요.

    pushMatrix();  //Start
    fill(0,255,0); //채우기
    translate(width/2,height/2,-100); //이동
    box(200,100,200); //상자
    popMatrix(); //End

fill(0,255,0)함수로 다음에 그리게 될 도형의 표면 색을 녹색으로 정했습니다. translate(x,y,z)로 그리게 될 도형이 윈도우창에서 어디쯤 위치할 것인지 이동 시킵니다. 즉, 도형의 색은 녹색이고 특정위치로 이동시킨 곳에 상자가 그려진다고 생각하시면 될 듯 싶네요.

[결과]


위 그림에서는 상자가 녹색인 것은 알 수 있지만 3D 상자인지는 알 수 없네요. 이제 회전을 시켜 볼까요.

2. Mouse 회전


마우스 회전은 간단합니다. 상자가 그려진 윈도우창에 마우스의 좌표를 가져 올 수 있다면 쉽게 해결 됩니다. processing에서는 마우스 좌표를 변수로 실시간 좌표를 가져올 수 있습니다. mouseX, mouseY가 그 변수명입니다. 이 변수를 사용하면 현재 마우스가 가리키는 좌표값을 얻을 수 있습니다. 회전을 시켜볼까요.

회전 rotate()함수는 그냥 회전인데 마우스 좌표로 X, Y 축으로 회전를 해봅시다. processing 에서는 각 축을 기준으로 회전 시키는 함수를 제공합니다.

해당 함수를 살펴보면, ratateX()은 X축 기준으로 회전함수이고, ratateY()은 Y축 기준으로 회전하는 함수입니다. mouseX, mouseY 변수는 size()함수로 만든 윈도우 창의 영역 안에 마우스의 좌표(x,y)값을 실시간으로 가져 올 수 있어 이 값을 회전각으로 하면 쉽게 회전 할 수 있습니다.

처음, 회전각은 mouseX로 했더니 너무 고속으로 회전해서 약간 회전을 느리게 하기 위해서 0.1을 곱해도 너무 빠르고 0.01정도 하니깐 제 컴퓨터에서 이상적으로 회전 하네요.

회전각(mouseX * 0.01)로 회전시켜 보았습니다.

void setup() {  
    
    size(600,600,P3D); //창사이즈
    noStroke();  //테두리없음
//  frameRate(30); //초당 프레임
} 

void draw() {  
    background(0); //배경색
    lights();  //조명

    pushMatrix();  //Start
    fill(0,255,0); //채우기
    translate(width/2,height/2,-100); //이동
    rotateX(mouseY*0.01); //x축 회전
    rotateY(mouseX*0.01); //y축 회전
    box(200,100,200); //상자
    popMatrix(); //End
}

[결과]


나중에 조이스틱 같은걸로 조정한 값을 이 부분을 대신하면 회전이 되겠죠.

2. 키보드 회전



이제는 키보드로 회전 시키는 방식을 살펴보도록 하겠습니다.

위 링크 소스에서 키보드 관련 부분 살펴보면,

void keyPressed() {
    if (key == CODED) {
            if (keyCode == UP) {
                 회전각;
            }   
    }
    else if (key == 'z'){
       명령문;
    }   
}

대충 구조는 이렇습니다. keyPressed()함수는 키보드의 키를 누르면 호출 되는 함수입니다. key는 눌렀을때의 키 값을 가지고 있으면 그 키 값이 CODED인지 채크하게 됩니다. CODED면 keyCode 변수의 키 값이 들어 있고 그 키가 UP, DOWN, LEFT, RIGHT 인지를 체크하게 됩니다. 참고로 화살표 키 값이라고 생각하시면 될 듯요.
일반 키값은 key에 들어 있으면 'a'~'z', 'A'~'Z' 등 등으로 키값을 가질 수 있고 key에 저장 되어 있어서 key로 비교하면 됩니다.

키보드로 회전한다면 방향키로 X, Y축 회전을 시키고 키값 Z, X키로 Z축으로 이동 제어 키로 쭘인/줌아웃을 시킬 예정입니다.

int x=0;
int y=0;
int z=0;

void setup() {  
    
    size(600,600,P3D); //창사이즈
    noStroke();  //테두리없음
        
//  frameRate(30); //초당 프레임
} 

void draw() {  
    background(0); //배경색
    lights();  //조명

    pushMatrix();  //Start
    fill(0,255,0); //채우기
    translate(width/2,height/2,-100+z); //이동
    rotateX(radians(y)); //x축 회전
    rotateY(radians(x)); //y축 회전
    
    box(200,100,200); //상자
    popMatrix(); //End
}

void keyPressed() {
  if (key == CODED) {
    if (keyCode == UP) {
      y+=1;
    } 
    else if (keyCode == DOWN) {
      y-=1;
    } 
    else if (keyCode == LEFT) {
      x-=1;
    } 
    else if (keyCode == RIGHT) {
      x+=1;
    }
  }
  else if (key == 'z' || key == 'Z') {
      z+=10;
  } 
  else if (key == 'x' || key == 'X') {
      z-=10;
  } 
}

위에서 if문이 조건식이 두개인데 '||'은 둘중 하나만 참이면 참으로 인정하는 기호입니다. 둘개 다 참이여야 참으로 인정하는 기호는 '&&'인데 참고로 알아 두세요. '||'로 'z' or 'Z' 중 Z키가 대소문자 중 아무거나 입력해도 Z로 인정한다는 의미입니다. 나머지는 구지 성명 드릴 필요는 없겠죠.

    rotateX(radians(y)); //x축 회전
    rotateY(radians(x)); //y축 회전

여기서 radians(y)은 라디안 단위로 각도로 변환시키는 함수입니다. 그냥 각도 구하기라고 생각하시면 될 듯 싶네요.

[결과]



화살표 방향키하고 춤인/줌아웃 키인 Z, X 키가 잘 작동하네요.

마무리


processing에 대해서 한번 관심을 가져보시라고 간단히 3D Rendering를 해보았습니다. 참고로 이미 만들어진 box()함수의 도형이지만 좌표계 기준으로 각 좌표로 모형을 그리고 싶다면 공식홈페이지에 도형 그리는 함수들을 찾아보시고 따라서 그려보세요, 충분히 그릴 수 있을 거라 생각됩니다.

참고로 processing 함수들이 다양한 기능들을 제공해주기 기 때문에 위 포스트한 코딩에서 추가 할 코딩 부분이 있지만 다 생략하고 기본만 되는 부분만 코딩한거라 좀 단순한 표현이 되었네요. 그래도 핵심적인 표현은 다 했습니다. 이제는 여러분들이 도형을 그리고 그 도형에 대해서 움직임을 push~pop를 이용해서 제어하시면 됩니다.

갑자기 processing를 포스팅을 한 이유는 최근에 스위치 버턴과 조이스틱으로 조정하는 것을 배웠습니다. 한번 여러분들이 이 코딩을 기반으로 아두이노와 접목하면 좋을 것 같아서 소개하게 되었습니다.

한번 스위치 버턴 or 조이스틱으로 오늘 배운 도형을 컨트롤 해보고 싶지 않으신지요. 제가 답을 바로 드리는 것보다 여러분들이 한번 지난 시간에 processing에서 아두이노와 어떻게 연동을 했는지 상단에 참고 링크 포스트를 읽어보시고 연구를 해보셨으면 합니다.

댓글()

구글 스케치업으로 온라인 3D 도면 디자인 하기

유용한팁|2019. 2. 1. 14:10

구글 스케치업으로 온라인 3D 도면 디자인 하기






이번에 소개할 프로그램은 온라인 상에서 3D 도면 디자인하는 프로그램을 소개 합니다. 초보자도 쉽게 3D 도면 디자인할 수 있는 입문자용으로 딱 좋은 프로그램입니다. 구글 스케치업 프로은 30일 평가판이 있으며 온라인상에서 실시간으로 가볍게 사용할 수 있는 구글 스케치업 프리가 있습니다. 예전에 구글 스케치업 프로로 잠깐 강좌를 따라 다뤄본게 전부라 실력은 없습니다. 온라인상에서 3D 도면 디자인을 즐길 수 있어서 한번 도면그리기와 벽체 세우는 강좌 동영상을 보면서 따라서 해봤는데 스케이업 프리도 괜찮은 프로그램이여서 아는분들도 많겠지만 한번 암것도 모른사람도 유튜브 동영상 강좌보고 따라하면 이정도 할 수 있다는 걸 보여주기 위해서 소개를 합니다.

1. 구글 스케치업프리 사이트



구글 계정이 있으면 작업할 것을 저장할 수 있습니다. 로그인 필요 없이 한번 따라서 작업해 보시는 것도 좋아요. 단 저장을 할 수 없다는 게 단점이고요. 저장을 할려면 로그인 해야하고 스케치업 계정을 만들던지 구글 계정으로 로그인하든지 둘 중 하나입니다.

제품소개에 스케치업 프로는 pc에 설치하는 프로그램이고요 좀 더 전문적인 다양한 기능을 제공합니다. 그 아래 스케치업 프리가 있는데 이건 온라인상에서 간편하게 3D 도면을 작업할 수 있습니다. 모델링 시작하면 온라인상에서 디자인할 수 있는 창으로 넘어갑니다.

왼쪽 작은 아이콘들을 디자인할 도구 목록이고요 오른쪽 아이콘들은 선택한 객체의 재질, 스타일 등 속성들을 설정해주는 것들입니다. 설치용 스케치업 프리에서 사용되는 기능들이 최소한으로 구성되어 있지만 간편하게 3D 도면 작업을 수행할 수 있게 한 최적의 프로그램이라고 생각 되네요. 프로 평가판을 사용하다가 사용할려고 하니깐 일부 기능이 좀 불편하게 첨에 느꼈지만 오랫만에 스케치업 동영상 강좌를 따라해보니 그리 어렵지 않더군요.

2. 구글 스케치업프리 편집해보기







첨에 새로만들기에서 저는 밀리미터 형태로 연습해 봤어요. 동영상에서 수치를 밀리미터로 하기 때문에 햇갈리 수 있어서 세번째 밀리미터 형태로 새 모델 만들기를 하였습니다.

선을 그을때는 시작점에서 선을 그릴때 시작점과 끝점으로 구성됩니다. 시작점을 누른 상태에서 그릴 방향으로 약간 움직였다가 수치를 입력하면 수치만큼 선을 만들어 줍니다. 그래야 정교하게 길이 계산을 할 수 있습니다. 마우스로 드래그하면 그려지지만 정확한 수치으로 옮기기 힘드니깐 대충 시작점 클릭하고 선을 그릴 방향으로 대충 이동시켜놓고 창 오른쪽 하단에 숫자를 입력하는 텍스트박스가 있는데 거기다 수치를 입력하시면 되니깐 어려워 하지 마세요. 그리고 자동으로 보조해주는 기능들이 많으니깐 유튜브에서 아무 스케치업 강좌를 검색하셔서 따라서 흉내를 내면 됩니다.

  • 선을 만들때에 진행 방향으로 대충 클릭한 상태에서 오른쪽 하단 텍스트 박스에 2000입력한다. 텍스트 박스에 커서를 옮길 필요는 없다 그냥 숫자를 치면 텍스트 박스에 입력된다.

  • 2000을 입력하고 엔터를 치면 아래와 같이 진행방향으로 정확히 2000 만큼 선이 그어진다.

  • 선을 그을때 보조 자동 기능이 있는데 바로 빨간(x)축에서 선을 초록(y)축으로 정사각형을 만들고자 그을때 마우스로 움직이면 선이 초록으로 바뀌는 때가 있습니다. 그때가 y축과 평행을 이룰때를 나타냅니다. 초록선이 나오면 대충 그 방향을 이동했다가 원하는 사각형의 길이 세로 값을 입력하시면 됩니다.

  • 선을 다 연결하면은 면이 나옵니다.

  • 밀기/끌기를 해당 면에 근처에 마우스를 가져가면 영역이 선택된 모습을 보실 꺼에요 그 상태에서 클릭하고 드래그 하면 3D 모형으로 만들어 지게 됩니다.

  • 여기에 색을 입히면 좀 더 그럴싸하게 바뀌게 됩니다.

참 쉽죠. 대충 만져보시면 어렵지 않을꺼에요. 곡선이나 기하학적 모형을 만들때만 그리기 좀 복잡하고 힘들지만 나머지는 3D 디자인 하기 참 쉽고 재미 있습니다.

집 만드는 과정



(1) 평면도면 그리기

강좌 출처에 나온 평면도 그리기 내용에서 한번 간단히 따라서 해봤어요. 사용법은 유튜브 강좌를 보시면 쉽게 다룰 수 있을거에요. 따라 해보는데 어렵지 않더군요. 대충 도면을 그려봤네요.

(2) 색상 입히기

좀 더 그럴싸하게 보이죠. 왼쪽 아이콘 목록들은 3D 도면 디자인 도구라고 했죠. 오른쪽 아이콘들은 선택한 객체에 속성들을 디자인하는 도구로 선택한 방바닥이면 외벽들 화장실 타일등으로 입혀서 좀 더 그럴싸하게 표현 된 모습입니다.

(3) 벽체 올리기

오른쪽 아이콘 중에 밀기/끌기라는 아이콘이 있는데 선택한 면에 클릭한 상태에서 마우스로 이동하면 벽체를 올릴 수 있습니다. 이렇게 올림으로 3D 형태로 디자인 할 수 있게 됩니다. 여기서 선을 그리는 것과 마찬가지로 벽체를 대충 진행방향으로 올리고 오른쪽 하단 텍스트 박스에 수치를 입력하면 정확하게 원하는 높이까지 벽체가 올라갑니다.

(4) 지붕 만들기

우선 지붕을 만들 범위를 지정했고요

한쪽 지붕을 만들 삼각형 면을 만들때 마우스를 사이드 면선에 대면서 그 선을 따라서 움직이면 중심점에 도달하면 중심점이라고 프로그램이 알려줍니다. 그 지점을 시작점으로 해서 파란(z) 축으로 선을 진행방향을 맞추고 대충 지붕높이값을 하단 텍스트박스에 수치로 입력해서 선을 그렸고 다시 양쪽 사이드 끝점에 선을 이여주니깐 면이 완성되었습니다 그 상태에서 밀기/끌기 땡기니깐 지붕이 만들어졌네요.

아래 바닥 모습입니다. 참고로 벽체를 밀기/끌기로 올렸기 때문에 구멍이 뚤려 있습니다. 하지만 대충 선을 이으면 면이 생기고 그걸 바닥으로 두면 됩니다.

(5) 완성

딱 완성 해놓고 오른쪽 아이콘에 있는 재질을 이용해서 지붕과 벽면에 색을 입히니깐 그럴싸하게 집이 완성 되었네요. 안타깝게 지붕을 올리기 전에 안에 벽지를 좀 바르고 나올 껄 아깝게 됐네요. 수정하면 되는데 이상태로 마무리 합니다.

(6) 외부 이미지 입히기

외부 pixabay 무료이미지에서 대충 다운받아서 입힌거라서 별로 보기에는 좋지 않습니다. 편집창 왼쪽 상단의 폴더이미지 모양있는데 거기 클릭하면 새로만들기 열기... 등이 있는데 Insert를 누르면 외부 이미지를 불러 올 수 있습니다. 이미지와 재질로 선택해서 불러옵니다. 여기서 불러오실때 이미지로 선택하면 이미지를 평면을 배치할 위치에 클릭하면 시작점이 되고 드래그 해서 마지막 지점을 클릭하면 이미지 크기가 결정되는 데 결과물에서 땅 이미지가 그 이미지 불러오기로 불러와서 배치한것입니다. 그리고 재질로 이미지를 선택 재질쪽 이미지가 넘어가고 재질에서 선택해서 선택한 면에 페인트를 할 수 있게 됩니다. 아래 그림에서 벽과 지붕을 외부 이미지로 불러와서 입혀 봤네요.

마무리




전문적으로 다루지는 못합니다. 건축의 건자도 모르니깐요. 대충 동영상 강좌에 나온 대로 사용하다 보니깐 프로그램 다루는데 별로 어렵지 않더군요. 이걸 통해서 3D 모형을 만드는데도 사용하기 편할 듯 싶네요. 잠깐이지만 어렵지 않고 쉽게 다룰 수 있으니깐 한번 도전 해보세요.

참고로 제가 이 스케치업 프로그램이 가장 매리트가 있었던 것은 이렇게 건물을 만들어 놓은걸 유니티로 옮겨 올 수 있다는 것입니다. 게임에 사용 할 건물을 여기서 만들어서 옮겨오면 재미 있겠죠.

암튼 사용법은 저도 전문적인거 모릅니다. 그냥 간단한 기능만 사용만 해도 이정도는 쉽게 만들어 낼 수 있으니깐 재미삼아 즐겨보세요. 설치할 필요도 없고 온라인 상태에서 그냥 다룰 수 있기 때문에 부담이 전혀 없으니깐 한번 해보시면 재미있을꺼에요.

'유용한팁' 카테고리의 다른 글

Fritzing 회로도 디자인  (0) 2019.02.03
논문 검색  (0) 2019.02.02
Ideone.com을 이용한 웹컴파일러  (0) 2019.01.31
Tinkercad로 온라인 3D 디자인 하기  (0) 2019.01.30
OpenToonz로 작화 애니메이션 편집  (0) 2019.01.29

댓글()

Tinkercad로 온라인 3D 디자인 하기

유용한팁|2019. 1. 30. 11:26

Tinkercad로 온라인 3D 디자인 하기






오늘은 즐거운 토요일입니다. 매주 토요일이면 하나씩 무료로 사용할 수 있는 프로그램을 소개하는데 이번주 소개할 무료 툴은 팅커캐드입니다. 초보자도 쉽게 3D 디자인할 수 있는 입문자용으로 딱 좋은 프로그램입니다. 물론 윈도우 10이 설치된 분이라면 앱으로 3D 디자인 할 수 있는 무료 프로그램이 몇개 있지만 오늘 소개하는 프로그램은 설치 없이 온라인상에서 3D 디자인 편집이 가능하고 아이들도 쉽게 조작할 수 있는 프로그램일 것 같아서 소개합니다.

1. 팅커캐드 사이트




간단히 이메일 계정으로 회원가입하시면 됩니다.

갤러리 누르시면 작품들이 화려하죠. 이걸 다운로드 받을 수 있고 복사해서 내 계정으로 옮겨올 수 있습니다. 작품들을 보면 감히 범접 할 수 없는 화려한 작품들을 소개하고 있네요. 내계정으로 복사해와서 어떻게 만들어졌는데 분해 해보시고 따라하시면 대충 감이 잡히실 꺼에요.

그리고 알아보기에서 샘플 튜토리얼 교육이 있습니다. 그런데 영어로 되어 있어 다소 불편하실 수 있지만 그냥 그림만 보고 대충 따라하실 수 있습니다.

알아보기 페이지 하단에 참고로 단축키 목록이 나와 있으니깐 살펴보시고 이용하시면 편하게 3D 디자인을 할 수 있습니다. 마우스로만 해도 되는데 단축키에서 Ctrl+화살표와 Shift+화살표, Shift 누른상태에서 물체들을 클릭이나 Shift+마우스왼쪽키, Ctrl+마우스왼쪽키 등 몇개가 더 있는데 연습하시다 보면 단축키를 사용으로 편하게 편집을 할 수 있다는 것을 느끼실 꺼에요. 마우스 하나로 해도 되기는 하는데 나중에 좀 불편해지니깐 꼭 단축키를 숙지하세요.

2. 팅커링 편집해보기





딱 계정을 만들면 디자인(팅커링), Circuits(아두이노편집기), 교육(알아두기튜토리얼을 클릭하면 자동으로 여기 저장) 이렇게 구성되어 있습니다. 디자인을 누르면 편집창을 새로 만들 수 있습니다. 2달전 만져보고 포스팅 할려고 잠깐 만져 봤네요.

편집창

기본창에서 보면 기본 쉐이프가 몇개 없고 덩그러니 창 하나만 있습니다. 갤러리에서 본 작품들은 화려한데 도대체 이걸로 어떻게 만들었지 하고 의문이 들꺼에요. 저도 처음에 기본 쉐이프을 가지고 어떻게 모먕을 만들지 갑갑 했었습니다. 모양을 만드는 것이 참 도특한 방식이더군요. 모양을 만들때 이게 모양을 만드는 것이 아니라 모양을 깍는다는 원리로 모양을 만들더군요. 아래 모양을 만드는 과정을 자세히 보시면 왜 모양을 깍는다란 표현인지 아실거에요.

어떻게 모양을 만드는지 과정을 설명하겠습니다.

(1) 사각형과 원형의 모형이 있습니다.

(2) 원형안에 사각형을 배치하고 속성창에서 솔리드와 구멍이 있는데 구멍을 클릭하여 변경합니다.

여기서 물체가 정상적으로 보이는 상태는 솔리드이고 물체를 투명하게 보이게 하는게 구멍입니다. 구멍이라는 표현이 번역이 좀 이상하게 된건지 좀 우낀 표현이지요.

(3) Shift 누른상태에서 두 물체를 클릭해줍니다. 범위가 지정되면 위쪽 상단에 그룹만들기가 활성화 되어 있고 그걸 눌러주면 묶여집니다.

(4) 완성


이렇게 모양이 하나 완성됩니다. 이게 팅커벨의 핵심입니다. 이런식으로 해서 독특한 모양을 만들어 냅니다. 여러개의 쉐이프 들을 붙이기 해서 하나로 그룹화하고 거기서 구멍을 파거나 깍을때 그 위치에 도형들을 배치하고 솔리드 대신 구멍 속성을 변경하고 파거나 깍는 부분에 덮어 씌우면 덮어진 범위은 사라지게 됩니다.

참 쉽죠. 이런식으로 작품을 만들어 내면 됩니다. 쉽기는 한데 이게 웹상에서 하기 때문에 컴 사양을 좀 타는 것 같아요. 웹브라우저 인터넷 성능이 느릴때는 좀 버벅거릴 꺼에요. 다 좋은데 이게 단점이네요. 온라인상에서 설치 없이 하는거라 그정도 단점은 감수할 만 할거에요. 아이들 작품도 꽤 잘 만든것 봐서는 쉽게 아이들도 3D 디자인을 할 수 있는 편집기인것 같아요.

3. 짧게 연습해서 만들어 봤어요.




초보수준으로 연습없이 사용법도 간단하고 무대포로 대충 만들어 봤네요. 포스팅 할려고 잠깐 짬내서 짧게 대충 만들었습니다. 공부안하고 이정도로 만들어지는 걸 봐서는 아마 아이들도 사용법만 알면 무자 쉽게 3D 디자인을 할 수 있을 거라 생각되네요.

마무리




전문적으로 하시고 싶다면 3D 게임엔진인 블렌드와 유니티 프로그램을 다운 받아서 설치하시면 되고요. 건축캐드용인데 아주 쉬운 툴로는 스케치업이 있는데 한달 무료 사용이라서 이걸 작년에 한달 놀았는데 아쉽더군요. 더 사용은 되는데 한달 후에는 다른 일부는 사용 못하게 되더군요. 이것도 전문 3D 캐드가 어려운분들이 스케치업으로 공부하면 꽤 쉽게 3D 디자인을 할 수 있어 편집기로 매리트가 있는 프로그램 입니다. 여기서 만든 건물들을 유니티 게임엔진으로 옮겨와서 게임에 사용되는 건물로 쓸 수 있어서 만들기도 쉽고 게임개발 공부할 때 사용하면 괜찮은 프로그램 같아요.

댓글()