2016年4月7日 星期四

week07_期中進度_呂登祐 & 鄧安倫

首先要完成天空跟紙飛機的物件
1.天空:
   使用天空包(skybox)的概念,然後再把貼圖(texture)貼上,使環境看起來有自然的感覺。
我們一開始構想是用方形的立方體作為天空包的空間,他的寫法如下:

PImage []img = new PImage[6];
void setup(){
  size(1080,640,P3D);
  for(int i=0;i<6;i++){
    img[i]=loadImage("sky" + i + ".jpg");
  }
  imageMode(CENTER);
}
float rotX=0, rotY=0;
void draw(){
  background(255);
  translate(width/2, height/2, 250);
  rotateX(radians(rotY));
  rotateY(radians(rotX));
 pushMatrix();
    translate(0,0, -2000);
    image(img[0], 0, 0, 4000,4000);
  popMatrix();
 pushMatrix();
    rotateY(radians(90));
    translate(0,0, -2000);
    image(img[1], 0, 0, 4000,4000);
  popMatrix();
  pushMatrix();
    rotateY(radians(-90));
    translate(0,0, -2000);
    image(img[2], 0, 0, 4000, 4000);
  popMatrix();
  pushMatrix();
    rotateY(radians(180));
    translate(0,0, -2000);
    image(img[3], 0, 0, 4000,4000);
  popMatrix();
  pushMatrix();  //down
    rotateX(radians(90));
    translate(0,0, -2000);
    image(img[4], 0,0, 4000,4000);
  popMatrix();
  pushMatrix(); //up
    rotateX(radians(-90));
    translate(0,0, -2000);
    image(img[5], 0,0, 4000,4000);
  popMatrix();
}
void mouseDragged(){
  rotX += mouseX-pmouseX;
  rotY -= mouseY-pmouseY;
}
 他們分別對應圖片img[num]的編號,我已經事先切割好圖片



然後會分別把對應的編號貼到到立方體的空間成為貼圖,效果如下:


但是,貼圖與貼圖的接縫區還是會有一點明顯的線條,我們覺得效果不太好,於是改別的寫法,於是決定把空間改成圓形立體空間,然後再貼上貼圖:

int ptsW, ptsH;
PImage img, img2;

int numPointsW;
int numPointsH_2pi; 
int numPointsH;

float[] coorX;
float[] coorY;
float[] coorZ;
float[] multXZ;

void setup() {
  size(1280, 720, P3D);
  background(0);
  noStroke();
  img=loadImage("a3.jpg");
  //img2=loadImage("a2.jpg");
  ptsW=30;
  ptsH=30;
  // Parameters below are the number of vertices around the width and height
  initializeSphere(ptsW, ptsH);
}

// Use arrow keys to change detail settings
void keyPressed() {
  if (keyCode == ENTER) saveFrame();
  if (keyCode == UP) ptsH++;
  if (keyCode == DOWN) ptsH--;
  if (keyCode == LEFT) ptsW--;
  if (keyCode == RIGHT) ptsW++;
  if (ptsW == 0) ptsW = 1;
  if (ptsH == 0) ptsH = 2;
  // Parameters below are the number of vertices around the width and height
  initializeSphere(ptsW, ptsH);
}
float rotX=0, rotY=0;
void draw() {
  background(0);
  /*camera(width/2+map(mouseX, 0, width, -2*width, 2*width), 
         height/2+map(mouseY, 0, height, -height, height),
         height/2/tan(PI*30.0 / 180.0), 
         width, height/2.0, 0, 0, 1, 0);*/
  camera(mouseX, height/2, (height/2) / tan(PI/6), width/2, height/2, 0, 0, 1, 0);
  rotateX(radians(rotY));
  rotateY(radians(rotX));
  //rotateY(radians(frameCount*0.1));
  pushMatrix();
  translate(width/2, height/2, 0);  
  textureSphere(2000, 2000, 2000, img);
  popMatrix();
}

void initializeSphere(int numPtsW, int numPtsH_2pi) {

  // The number of points around the width and height
  numPointsW=numPtsW+1;
  numPointsH_2pi=numPtsH_2pi;  // How many actual pts around the sphere (not just from top to bottom)
  numPointsH=ceil((float)numPointsH_2pi/2)+1;  // How many pts from top to bottom (abs(....) b/c of the possibility of an odd numPointsH_2pi)

  coorX=new float[numPointsW];   // All the x-coor in a horizontal circle radius 1
  coorY=new float[numPointsH];   // All the y-coor in a vertical circle radius 1
  coorZ=new float[numPointsW];   // All the z-coor in a horizontal circle radius 1
  multXZ=new float[numPointsH];  // The radius of each horizontal circle (that you will multiply with coorX and coorZ)

  for (int i=0; i<numPointsW ;i++) {  // For all the points around the width
    float thetaW=i*2*PI/(numPointsW-1);
    coorX[i]=sin(thetaW);
    coorZ[i]=cos(thetaW);
  }
  
  for (int i=0; i<numPointsH; i++) {  // For all points from top to bottom
    if (int(numPointsH_2pi/2) != (float)numPointsH_2pi/2 && i==numPointsH-1) {  // If the numPointsH_2pi is odd and it is at the last pt
      float thetaH=(i-1)*2*PI/(numPointsH_2pi);
      coorY[i]=cos(PI+thetaH); 
      multXZ[i]=0;
    } 
    else {
      //The numPointsH_2pi and 2 below allows there to be a flat bottom if the numPointsH is odd
      float thetaH=i*2*PI/(numPointsH_2pi);

      //PI+ below makes the top always the point instead of the bottom.
      coorY[i]=cos(PI+thetaH); 
      multXZ[i]=sin(thetaH);
    }
  }
}

void textureSphere(float rx, float ry, float rz, PImage t) { 
  // These are so we can map certain parts of the image on to the shape 
  float changeU=t.width/(float)(numPointsW-1); 
  float changeV=t.height/(float)(numPointsH-1); 
  float u=0;  // Width variable for the texture
  float v=0;  // Height variable for the texture

  beginShape(TRIANGLE_STRIP);
  texture(t);
  for (int i=0; i<(numPointsH-1); i++) {  // For all the rings but top and bottom
    // Goes into the array here instead of loop to save time
    float coory=coorY[i];
    float cooryPlus=coorY[i+1];

    float multxz=multXZ[i];
    float multxzPlus=multXZ[i+1];

    for (int j=0; j<numPointsW; j++) { // For all the pts in the ring
      normal(-coorX[j]*multxz, -coory, -coorZ[j]*multxz);
      vertex(coorX[j]*multxz*rx, coory*ry, coorZ[j]*multxz*rz, u, v);
      normal(-coorX[j]*multxzPlus, -cooryPlus, -coorZ[j]*multxzPlus);
      vertex(coorX[j]*multxzPlus*rx, cooryPlus*ry, coorZ[j]*multxzPlus*rz, u, v+changeV);
      u+=changeU;
    }
    v+=changeV;
    u=0;
  }
  endShape();
}
void mouseDragged(){
  rotX += mouseX-pmouseX;
  rotY -= mouseY-pmouseY;
}

圖片部分為了讓頭尾連接看起來自然,所以我在圖片做了一點修改,使貼上圓形體時變得比較自然



最後,執行完程式,效果如下:
變的自然多了 =w=

天空包的部分大概就先到這了!再來是紙飛機的部分。



2.紙飛機:
  我們打算描點畫出3D的紙飛機,於是現在小畫家描點做測試:

紙飛機點座標
然後再放到Processing的座標系統內:
就會180度變正的紙飛機,如下圖:



但是,後來發現尷尬的一點就是,那是線條(line();)的寫法! 而不是形狀的寫法,所以執行出來的飛機就會變成只有骨架的紙飛機,最後我們又發現了別種寫法!

import de.voidplus.leapmotion.*;
LeapMotion leap;
void setup(){
  size(1080, 640, P3D);
  noStroke();
  leap = new LeapMotion(this);
  pos = new PVector(300,200,0);
}
PVector pos=null, dir=null;
void draw(){
 float handAngle=0;
   background(0);
 for(Hand hand : leap.getHands()){
    pos = hand.getPosition();
    PVector p0=hand.getThumb().getPosition();
    PVector p1=hand.getPinkyFinger().getPosition();
    PVector dir = PVector.sub(p1,p0);
    handAngle = atan2(dir.y, dir.x);
  }
   translate(pos.x, pos.y, pos.z);
   rotateZ(handAngle);
   airplane_v1();
}
void airplane_v1(){
    pushMatrix();
         stroke(0);
         scale(5);
         color c = color(255, 255, 0);
         fill(c);  
        beginShape(TRIANGLES); //paper airplane
           vertex(0, -40, 0);//01
           vertex(-20, -10, 0);
           vertex(-5, -10, 0);
           vertex(-5, -10, 0);//02
           vertex(0, 0, -10);
           vertex(0, -40, 0);
           vertex(0, 0, -10);//03
           vertex(5, -10, 0);
           vertex(0, -40, 0);    
           vertex(5, -10, 0);//04
           vertex(20, -10, 0);
           vertex(0, -40, 0);
        endShape();
     popMatrix();
}

利用beginShape(TRANGLES);endShape(); 函式可以畫出3D的三角形 ! :D

紙飛機就大致完成了!

當那2大部分完成時,我們之後會再把它給結合起來,並寫上用手操控的體感程式。

沒有留言:

張貼留言