2025年5月1日 星期四

12750094_week11

 //week11_1_postman_saveString_loadString

//修改自week10_6_postman_many_angle_ID_saveString_loadString
PImage postman, head, body, uparm1, hand1, uparm2, hand2;
float [] angle = new float[20]; // 準備20個關節的變數
int ID = 0; // 現在要處理的關節 ID (第幾個關節)
void mouseDragged(){
  angle[ID] += mouseX - pmouseX;
} // 記得把圖檔拉進來哦!!!!
void keyPressed(){
  if(key=='1') ID = 1; // 左邊臂
  if(key=='2') ID = 2; // 左邊手
  if(key=='3') ID = 3; // 右邊臂
  if(key=='4') ID = 4; // 右邊手
  if(key=='5') ID = 5; // (待用)
  if(key=='6') ID = 6; // (待用)
  if(key=='0') ID = 0; // 頭
   
  if(key=='s'){ // 從這裡開始 每次按 's' 就存一組 angle
    String now = ""; // 要放現在全部的關節的值
    for(int i=0; i<20; i++){ // 利用 for 迴圈
      now += angle[i] + " "; // 全部塞到 now 裡, 記得有空
    }
    lines.add(now); // 把現在的這行, 加到 lines 裡
    String [] arr = new String[lines.size()];
    lines.toArray(arr);
    saveStrings("angles.txt", arr);
  }
  if(key=='r') //replay照之前按's'存檔的lines重播
  {
    if(R==0)
    {
      String [] file =loadStrings("angles.txt");
      if(file!=null)//有讀到檔案
      {
        for(int i=0;i<file.length;i++)
        {
          lines.add(file[i]);
        }
      }
    }
    if(R<lines.size())
    {
      float [] now = float(split(lines.get(R),' '));
      for(int i =0;i<20;i++)angle[i]=now[i];
      R=(R+1)%lines.size();
    }
  }
}
int R=0;//一開始沒有任何東西
ArrayList<String> lines = new ArrayList<String>(); // 放移動的結果 
// 到這裡結束
void setup(){
  size(560, 560);
  postman = loadImage("postman.png");
  head = loadImage("head.png");
  body = loadImage("body.png");
  uparm1 = loadImage("uparm1.png");
  hand1 = loadImage("hand1.png");
  uparm2 = loadImage("uparm2.png");
  hand2 = loadImage("hand2.png");
}
void draw(){
  background(#FFFFF2);
  image(postman, 0, 0); // 基礎的郵差先生(全身)
  fill(255, 0, 255, 128); // 半透明的紫色
  rect(0, 0, 560, 560); // 蓋上去
  pushMatrix(); // 要畫左邊的上手臂、手肘
    translate(+185, +261);
    rotate(radians(angle[1]));
    translate(-185, -261);
    image(uparm1, 0, 0); // 上手臂
    pushMatrix();
      translate(+116, +265);
      rotate(radians(angle[2]));
      translate(-116, -265);
      image(hand1, 0, 0);
    popMatrix();
  popMatrix();
  
  pushMatrix(); // 要畫右邊的上手臂、手肘
    translate(290, 262);
    rotate(radians(angle[3]));
    translate(-290, -262);
    image(uparm2, 0, 0);
    pushMatrix();
      translate(357, 259);
      rotate(radians(angle[4]));
      translate(-357, -259);
      image(hand2, 0, 0);
    popMatrix();
  popMatrix();
  
  pushMatrix();
    translate(+236, +231); // 再放回去正確的位置
    rotate(radians(angle[0]));
    translate(-236, -231); // 把頭的旋轉中心, 放到(0,0)
    image(head, 0, 0); // 再畫頭
  popMatrix();
  image(body, 0, 0); // 再畫身體
}
按S存取動作
按R讀取動作
  //week11_2_postman_saveString_loadString_alpha_interpolation
  //修改自week11_1_postman_saveString_loadString
  PImage postman, head, body, uparm1, hand1, uparm2, hand2;
  float [] angle = new float[20]; // 準備20個關節的變數
  int ID = 0; // 現在要處理的關節 ID (第幾個關節)
  void mouseDragged(){
    angle[ID] += mouseX - pmouseX;
  } // 記得把圖檔拉進來哦!!!!
  void keyPressed(){
    if(key=='1') ID = 1; // 左邊臂
    if(key=='2') ID = 2; // 左邊手
    if(key=='3') ID = 3; // 右邊臂
    if(key=='4') ID = 4; // 右邊手
    if(key=='5') ID = 5; // (待用)
    if(key=='6') ID = 6; // (待用)
    if(key=='0') ID = 0; // 頭
     
    if(key=='s'){ // 從這裡開始 每次按 's' 就存一組 angle
      String now = ""; // 要放現在全部的關節的值
      for(int i=0; i<20; i++){ // 利用 for 迴圈
        now += angle[i] + " "; // 全部塞到 now 裡, 記得有空
      }
      lines.add(now); // 把現在的這行, 加到 lines 裡
      String [] arr = new String[lines.size()];
      lines.toArray(arr);
      saveStrings("angles.txt", arr);
    }
    if(key=='p')//按了r,想要內插中間結果
    {
      int R2=(R+1)%lines.size();
      float [] oldAngle=float(split(lines.get(R),' '));
      float [] newAngle=float(split(lines.get(R2),' '));
      float alpha=(frameCount%30)/30.0;
      for(int i=0;i<20;i++)angle[i]=oldAngle[i]*(1-alpha)+newAngle[i]*alpha;
    }
    if(key=='r') //replay照之前按's'存檔的lines重播
    {
      if(R==0)
      {
        String [] file =loadStrings("angles.txt");
        if(file!=null)//有讀到檔案
        {
          for(int i=0;i<file.length;i++)
          {
            lines.add(file[i]);
          }
        }
      }
      if(R<lines.size())
      {
        float [] now = float(split(lines.get(R),' '));
        for(int i =0;i<20;i++)angle[i]=now[i];
        R=(R+1)%lines.size();
      }
    }
  }
  int R=0;//一開始沒有任何東西
  ArrayList<String> lines = new ArrayList<String>(); // 放移動的結果 
  // 到這裡結束
  void setup(){
    size(560, 560);
    postman = loadImage("postman.png");
    head = loadImage("head.png");
    body = loadImage("body.png");
    uparm1 = loadImage("uparm1.png");
    hand1 = loadImage("hand1.png");
    uparm2 = loadImage("uparm2.png");
    hand2 = loadImage("hand2.png");
  }
  void draw(){
    background(#FFFFF2);
    image(postman, 0, 0); // 基礎的郵差先生(全身)
    fill(255, 0, 255, 128); // 半透明的紫色
    rect(0, 0, 560, 560); // 蓋上去
    pushMatrix(); // 要畫左邊的上手臂、手肘
      translate(+185, +261);
      rotate(radians(angle[1]));
      translate(-185, -261);
      image(uparm1, 0, 0); // 上手臂
      pushMatrix();
        translate(+116, +265);
        rotate(radians(angle[2]));
        translate(-116, -265);
        image(hand1, 0, 0);
      popMatrix();
    popMatrix();
    
    pushMatrix(); // 要畫右邊的上手臂、手肘
      translate(290, 262);
      rotate(radians(angle[3]));
      translate(-290, -262);
      image(uparm2, 0, 0);
      pushMatrix();
        translate(357, 259);
        rotate(radians(angle[4]));
        translate(-357, -259);
        image(hand2, 0, 0);
      popMatrix();
    popMatrix();
    
    pushMatrix();
      translate(+236, +231); // 再放回去正確的位置
      rotate(radians(angle[0]));
      translate(-236, -231); // 把頭的旋轉中心, 放到(0,0)
      image(head, 0, 0); // 再畫頭
    popMatrix();
    image(body, 0, 0); // 再畫身體
  }

按住p會利用內插進行連續動作

  //week11_2_postman_alpha_interpolation_better
  //修改自week11_1_postman_saveString_loadString
  PImage postman, head, body, uparm1, hand1, uparm2, hand2;
  float [] angle = new float[20]; // 準備20個關節的變數
  int ID = 0; // 現在要處理的關節 ID (第幾個關節)
  void mouseDragged(){
    angle[ID] += mouseX - pmouseX;
  } // 記得把圖檔拉進來哦!!!!
  void keyPressed(){
    if(key=='1') ID = 1; // 左邊臂
    if(key=='2') ID = 2; // 左邊手
    if(key=='3') ID = 3; // 右邊臂
    if(key=='4') ID = 4; // 右邊手
    if(key=='5') ID = 5; // (待用)
    if(key=='6') ID = 6; // (待用)
    if(key=='0') ID = 0; // 頭
     
    if(key=='s'){ // 從這裡開始 每次按 's' 就存一組 angle
      String now = ""; // 要放現在全部的關節的值
      for(int i=0; i<20; i++){ // 利用 for 迴圈
        now += angle[i] + " "; // 全部塞到 now 裡, 記得有空
      }
      lines.add(now); // 把現在的這行, 加到 lines 裡
      String [] arr = new String[lines.size()];
      lines.toArray(arr);
      saveStrings("angles.txt", arr);
    }
   // if(key=='p')//按了r,想要內插中間結果
    //{
      //float alpha=(frameCount%30)/30.0;
      //if(alpha==0.0)R=(R+1)%lines.size();
      //int R2=(R+1)%lines.size();
      //float [] oldAngle=float(split(lines.get(R),' '));
      //float [] newAngle=float(split(lines.get(R2),' '));

      //for(int i=0;i<20;i++)angle[i]=oldAngle[i]*(1-alpha)+newAngle[i]*alpha;
    //}
    if(key=='r') //replay照之前按's'存檔的lines重播
    {
      if(R==0)
      {
        String [] file =loadStrings("angles.txt");
        if(file!=null)//有讀到檔案
        {
          for(int i=0;i<file.length;i++)
          {
            lines.add(file[i]);
          }
        }
      }
      if(R<lines.size())
      {
        float [] now = float(split(lines.get(R),' '));
        for(int i =0;i<20;i++)angle[i]=now[i];
        R=(R+1)%lines.size();
      }
    }
  }
  int R=0;//一開始沒有任何東西
  ArrayList<String> lines = new ArrayList<String>(); // 放移動的結果 
  // 到這裡結束
  void setup(){
    size(560, 560);
    postman = loadImage("postman.png");
    head = loadImage("head.png");
    body = loadImage("body.png");
    uparm1 = loadImage("uparm1.png");
    hand1 = loadImage("hand1.png");
    uparm2 = loadImage("uparm2.png");
    hand2 = loadImage("hand2.png");
  }
  void myinterpplate()
  {
    if(lines.size()>0)
    {
      float alpha=(frameCount%30)/30.0;
      if(alpha==0.0)R=(R+1)%lines.size();
      int R2=(R+1)%lines.size();
      float [] oldAngle=float(split(lines.get(R),' '));
      float [] newAngle=float(split(lines.get(R2),' '));
      for(int i=0;i<20;i++)angle[i]=oldAngle[i]*(1-alpha)+newAngle[i]*alpha;
    }
  }
  void draw(){
    myinterpplate();
    background(#FFFFF2);
    image(postman, 0, 0); // 基礎的郵差先生(全身)
    fill(255, 0, 255, 128); // 半透明的紫色
    rect(0, 0, 560, 560); // 蓋上去
    pushMatrix(); // 要畫左邊的上手臂、手肘
      translate(+185, +261);
      rotate(radians(angle[1]));
      translate(-185, -261);
      image(uparm1, 0, 0); // 上手臂
      pushMatrix();
        translate(+116, +265);
        rotate(radians(angle[2]));
        translate(-116, -265);
        image(hand1, 0, 0);
      popMatrix();
    popMatrix();
    
    pushMatrix(); // 要畫右邊的上手臂、手肘
      translate(290, 262);
      rotate(radians(angle[3]));
      translate(-290, -262);
      image(uparm2, 0, 0);
      pushMatrix();
        translate(357, 259);
        rotate(radians(angle[4]));
        translate(-357, -259);
        image(hand2, 0, 0);
      popMatrix();
    popMatrix();
    
    pushMatrix();
      translate(+236, +231); // 再放回去正確的位置
      rotate(radians(angle[0]));
      translate(-236, -231); // 把頭的旋轉中心, 放到(0,0)
      image(head, 0, 0); // 再畫頭
    popMatrix();
    image(body, 0, 0); // 再畫身體
  }
按下R自動循環動作

// week11-3_postman_again
// 重新來一次,讓程式的架構變更清楚
PImage postman, head, body, leftupuparm, leftuparm, rightupuparm, rightuparm, foot1, foot2;
void setup(){
  size(560,560);
  postman = loadImage("postman.png");
  head = loadImage("head.png");
  body = loadImage("body.png");
  leftupuparm = loadImage("leftupuparm.png");
  leftuparm = loadImage("leftuparm.png");
  rightupuparm = loadImage("rightupuparm.png");
  rightuparm = loadImage("rightuparm.png");
  foot1 = loadImage("foot1.png");
  foot2 = loadImage("foot2.png");
}
int R = 0;
void myInterpolate(){
  if(lines.size() >= 2){ // 要有 2 行以上,才能做內插
    float alpha = (frameCount%30)/30.0; // 介於 0.0~1.0 中間的值
    if(alpha == 0.0) R = (R+1)%lines.size(); // 如果變到0.0,就換下一組
    int R2 = (R+1)%lines.size();
    float [] oldAngle = float(split( lines.get( R ),' '));
    float [] newAngle = float(split( lines.get( R2 ),' '));
    for(int i=0;i<10;i++){
      angleX[i] = oldAngle[i*2+0]*(1-alpha) + newAngle[i*2+0]*alpha;
      angleY[i] = oldAngle[i*2+1]*(1-alpha) + newAngle[i*2+1]*alpha;
    }
  }  
}

float [] angleX = new float[10]; // 在 3D 的世界裡面,我們的旋轉
float [] angleY = new float[10];

int ID = 0; // 一開始是頭的關節
ArrayList<String> lines = new ArrayList<String>();
void keyPressed(){
  if(key == 's'){
    String now = ""; //空字串
    for(int i=0;i<10;i++){
      now += angleX[i] + " "; // 後面有空格
      now += angleY[i] + " "; // 後面有空格
    }
    lines.add(now); // 把現在的動作的這行,加到 lines 裡面
    String[] arr = new String[lines.size()];
    lines.toArray(arr);
    saveStrings("angles.txt",arr);
    println("現在存檔:"+ now);
  }
  if(key == 'r'){
    String [] file = loadStrings("angles.txt");
    if(file != null){
      for(int i=0; i<file.length; i++){
        lines.add(file[i]);
        println("現在讀檔:" + file[i]);
      }
    }
  }
  if(key == 'p') playing = !playing; // 播動畫 <=> 不播動畫
  if(key == '1') ID = 1; // 左上上臂
  if(key == '2') ID = 2; // 左上臂
  if(key == '3') ID = 3; // 右上上臂
  if(key == '4') ID = 4; // 右上臂
  if(key == '5') ID = 5; // (待用)
  if(key == '6') ID = 6; // (待用)
  if(key == '0') ID = 0; // 頭
}
boolean playing = false; // 一開始,不播動畫,按下 'p' 可切換

void mouseDragged(){
  angleX[ID] += mouseX - pmouseX;
  angleY[ID] += mouseY - pmouseY; // 多了這一行
}

void draw(){
  background(#FFFFF2);
  if(playing) myInterpolate();
  image(body, 0, 0); // 先畫身體
 
  pushMatrix();
    translate(+236, +231); // 再放回去正確的位置
    rotate(radians(angleX[0]));
    translate(-236,-231); // 把頭的旋轉中心,放到(0,0)
    image(head, 0, 0); // 再畫頭
  popMatrix();
 
  pushMatrix();
    translate(+185, +263); // 再放回去正確的位置
    rotate(radians(angleX[1]));
    translate(-185,-263);
    image(leftupuparm, 0, 0);  // 左上上手臂
    pushMatrix();
      translate(+118, +264); // 再放回去正確的位置
      rotate(radians(angleX[2]));
      translate(-118,-264);
      image(leftuparm, 0, 0);  // 左上手臂
    popMatrix();
   popMatrix();

 
  pushMatrix();
    translate(+290, +263); // 再放回去正確的位置
    rotate(radians(angleX[3]));
    translate(-290,-263);
    image(rightupuparm, 0, 0);  // 右上上手臂
    pushMatrix();
      translate(+356, +259); // 再放回去正確的位置
      rotate(radians(angleX[4]));
      translate(-356,-259);
      image(rightuparm, 0, 0);  // 右上手臂
    popMatrix();
  popMatrix();

  pushMatrix();
    translate(220,375);
    rotate(radians(angleX[5]));
    translate(-220,-375);
    image(foot1,0,0);
  popMatrix();
 
  pushMatrix();
    translate(261,372);
    rotate(radians(angleX[6]));
    translate(-261,-372);
    image(foot2,0,0);
  popMatrix();
 
}

















































沒有留言:

張貼留言