top drop menu

Recent Post

수요일, 11월 16

Blender(1) - 강력한 오픈소스 무료 3D 툴 Blender 2.78를 다시 설치하고 기초부더 배워 보자.

한참 전에 Blender를 처음 접하게 되어 미친듯이 배운적이 있다. 100개를 목표로 열심히 달려서 미션을 완성한 적이 있는데 한동안 등한시 하다가 최근 다시 흥미가 생기기 시작했다. 그래서 다시 100개를 목표로 작업을 시작해 보기로 했다. 시즌2!!!
아마도 주로 유튜브의 튜토리얼을 강좌를 따라해 보고 연습한 최종 결과물을 올려 보는 것이 될듯 하다.

* 지난 작업
http://blender.dothome.co.kr/

새로 시작할려면 먼저 Blender를 설치해야지. 아래 사이트에서 가서 최신 버전으로 설치를 하자.

https://www.blender.org/


2016년 11월 17일 현재 버전은 2.78이다. 그새 꾸준히 버전업이 되고 있었나 보다. 거창하게 시즌2라고 제목을 달았지만 결국 기초 부터 다시 배워야 할듯 하다. 다 까먹었다. 맨날 기초만 반복하다가 끝이 나는것 같기도 하고 ... 
어쨌든 흥미가 발동 했으니 죽이 되던 밥이 되던 시작해 보기로 하자. 이런건 하다 보면 조금씩 늘기 마련이다. 

출발~!



화요일, 11월 15

프로세싱(11) : Processing에서 비디오를 재생하고 필터효과 주기

이번에는 로컬 하드에 있는 비디오를 재생하고 효과를 주는 방법에 대해 알아 보자. 재생할 비디오 파일을 data 폴더를 만들어 넣어 놓으면 된다. 아니면 절대 경로를 적어 주어야 한다. 상대경로는 테스트 안해 봤다. 

import processing.video.*; import com.hamoid.*; //프로세싱을 비디오로 저장하기 위해 VideoExport videoExport; //로컬동영상을 재생시 Movie를 라이브 카메라 영상을 사용시는 Capture를 사용 Movie myMovie; void setup(){ size(740, 580); frameRate(25); //동영상 파일 경로에 신경을 써야 한다. //파일명만 적어 주는 경우 스케치파일이 있는 디렉토리에 data디렉토리를 만들어서 //그곳에 동영상을 넣어야 한다. 아니면 절대 경로를 적어 주면 된다. myMovie = new Movie(this, "C:\\Users\\userid\\Videos\\20160921_112012.avi"); myMovie.frameRate(2); myMovie.play(); myMovie.loop(); //font PFont font = createFont("NanumGothic", 32); textFont(font); //video export videoExport = new VideoExport(this, "exportSample.mp4"); } void draw(){ background(180); //effect filter //tint(221,160,221); //수정 영상1 image(myMovie, width/2, 0, width/2, height/2); filter(THRESHOLD, 0.5); //수정 영상2 image(myMovie, 0, myMovie.height/2+50,width/2, height/2); //(video,x,y,w,h) filter(INVERT); //원본 영상 noTint(); image(myMovie, 0,0,width/2, height/2); //(video,x,y,w,h) //other filter //filter(THRESHOLD, 0.5); //filter(GRAY); //filter(BLUR, 1); //숫자가 높으면 적용치가 높아짐 //filter(POSTERIZE, 4); //filter(ERODE); //??? light area를 감소? //filter(DILATE); //light area를 증가? //text text("Video Filter", width * 3/5, height * 3/4); //video export videoExport.saveFrame(); } //call every time a new frame is available to read. void movieEvent (Movie m) { m.read(); } //큰 해상도 비디오 재생이 엄청 느려짐.




프로세싱(10) - 배열로 만드는 다량의 바운싱 볼 만들기

볼 클래스를 만들고 바닥에서 튕겨 올라 무한 반복 되게 한다. 이제 배열을 이용해서 다량의 볼을 복제해서 움직이도록 만들어 보자.


int num = 100;
//선언
Ball[] balls = new Ball[num];

void setup() {
  size(740, 400);
  background(0);
  //총갯수만큼 반복해서 객체생성후 배열에 담는다.
  for (int i = 0; i < balls.length; i++) {
    balls[i] = new Ball();
  }
}


void draw() {
  background(0);
  //객체 - 액션
  for (int  i = 0; i < balls.length; i++) {
    balls[i].update();
    balls[i].display();
  }
}

//클래스 정의
class Ball {
  //변수
  float x, y;
  float r;
  float g;
  float speedx, speedy;
  color c;
  
  //생성자
  Ball() {
    x = random(width);
    y = random(height/2);
    r = 10; //볼의 반지름
    g = random(0.01, 0.04);
    speedx = random(-1, 1);
    speedy = 0;
    c = color(random(255), random(255), random(255));
  }
  
  //액션
  void update() {
    x = x + speedx;
    y = y + speedy;
    
    speedy = speedy + g; //중력을 추가해 준다.
    
    
    //경계에 부딪히면 반전되게 ...
    if (x > width - r ) { 
      x = width -r;
      speedx *= -1;
    } else if( x < r) {
      x = r;
      speedx *= -1;
    }
    
    if (y > height - r) {
      y = height - r;
      speedy *= -1;
    } else if ( y < r) {
      y = r;
      speedy *= -1;
    }
    

  }
  
  //화면에 그린다.  
  void display() {

    noStroke();
    fill(c);
    ellipse(x, y, r * 2, r * 2);
  }
}


----------

주석을 참고 하면 쉽게 이해 할 수 있다. 램덤함수를 이용해서 각각의 움직임에 차이를 주었다. 실행해 보자.


프로세싱(9) - 안드로이드 앱 만들기 : 안드로이드모드 사용

프로세싱에서 안드로이드를 지원한다. 쉽게 말해서 프로세싱을 가지고 안드로이드용 앱을 만들 수 있다는 것이다. 그만큼 쉽게 비쥬얼한 앱을 만들 수 있다는 것이다. 그런데 초보자에겐 쉽지 않은듯 ...  프로세싱만 가지고 만드는게 아니라 다른 툴들과 마찬가지로 자바도 필요하고 SDK도 필요하고 ... 프로세싱에서 작업한 코드를 결국에는 SDK을 이용해서 앱으로 만드는것 같다. 간단한 예제를 적용해 보는것으로 어떤 식으로 만들 수 있는지 알아 보자.

PED에는 몇가지 개발모드를 사용할 수 있도록 되어 있다. 기본모드인 자바, 이 예제에서 추가할 Android 그리고 파이썬모드도 추가 가능하다.

오른쪽 상단 귀퉁이의 버튼을 클릭해서 보면 [모드 추가]라는 메뉴가 있다. 선택한다. 예제 전에 이미 추가해 놓았기 때문에 Android 메뉴가 떠 있지만 설치 전이라면 보이지 않는다.



[Mode]탭에서 Android Mode를 선택하고 인스톨한다. 안정버전은 3.0.1이다. 베타 버전을 설치해 본것이다. 뭐가 다른지는 모른다. ㅎ설치하는 중에 나오는지 실행하면 나오는지 기억이 가물가물한데 분명한것은 SDK가 어디에 설치 되어 있는지 설치 되어 있지 않다면 같이 이 모드를 설치하면서 반드시 설치해야 한다. 이미 설치 되어 있어서 위치만 지정해 주었다. 이제 Android Mode를 사용할 수 있게 되었다.

예제는 프로세싱 사이트에 있는 튜토리얼을 그대로 적용해 보았다. 아래 링크에서 확인 할 수 있다.

http://android.processing.org/tutorials/index.html

첫번재 예제는 화면의 좌/우를 터치하면 흰색/검정으로 반전되는 간단한 앱이다. 두번째 좀 더 심화된 예제를 해 보자. 마찬가지로 튜토리얼 두번째 Using Sensors 에 코드가 있다. 스마트폰의 가속도 정보를 추출해서 화면에 보여 주는 코드이다. 이것만 하면 심심하니 앞에서 해본 SuperFormula 소스를 같이 적용해 보았다. 폰의 accelerometer값중에 az를 기존 숫자 대신에 대입해 주었다. 폰의 움직임에 따라 그 값이 변화니 그래프도 마찬가지로 변하게 된다. 

//안되나? import peasy.*; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorManager; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; Context context; SensorManager manager; Sensor sensor; AccelerometerListener listener; float ax, ay, az; float t; void setup() { fullScreen(); context = surface.getActivity(); //안드로이드모드4.0이상에서는 manager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); sensor = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); listener = new AccelerometerListener(); manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_GAME); noFill(); stroke(255); strokeWeight(2); textFont(createFont("Arial", 60)); } void draw() { background(0); text("X: " + ax, 10, 60); text("Y: " + ay, 10, 120); text("Z: " + az, 10, 180); translate(width/2, height/2); //그리기 beginShape(); for (float theta = 0; theta <= 2 * PI; theta += 0.01) { float rad = r(theta, 3, 2, int(az), //6, 1, sin(t) * 1.2 + 1.2, cos(t) * 1.2 + 1.2 ); float x = rad * cos(theta) * 50; float y = rad * sin(theta) * 50; vertex(x,y); } endShape(); t += 0.1; } float r(float theta, float a, float b, float m, float n1, float n2, float n3) { return pow(pow(abs(cos(m * theta / 4.0) / a), n2) + pow(abs(sin(m * theta / 4.0) / b), n3), -1.0 / n1); } //리스너에서 가속도정보를 받아 온다. class AccelerometerListener implements SensorEventListener { public void onSensorChanged(SensorEvent event) { ax = event.values[0]; ay = event.values[1]; az = event.values[2]; } public void onAccuracyChanged(Sensor sensor, int accuracy) { } } //배터리 절약을 위해 사용하지 않을땐 리스너를 등록해지 하는게 좋다. public void onResume() { super.onResume(); if (manager != null) { manager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_GAME); } } public void onPause() { super.onPause(); if (manager != null) { manager.unregisterListener(listener); } }

Blogger Widget