2023年3月15日 星期三

辰_電腦圖學Week05

 真的太倒楣了!上週因為專研的問題整夜失眠,第四週早上就是沒精神去上電腦圖學課。那堂課我可是非常期待的(想要盡心上完),可是由於身體太疲憊,加上腦袋裡一團糟,我只好缺席整堂課程。真的好糟糕,因為我非常希望能夠好好學這堂課。希望老師能夠體諒我的困境,也會在日後找時間把這堂課補上,謝謝!

  1. T-R-T 轉動特定軸:本課程將教授如何使用 T-R-T 的方式進行物體的特定軸轉動。

  2. 複習移動-旋轉 vs 旋轉-移動:本課程將複習移動-旋轉和旋轉-移動的區別,以及縮放的基本概念。

  3. 矩陣在圖形學中的應用:本課程將深入學習矩陣的概念和基本運算,以及在圖形學中的應用,例如矩陣轉置、求逆等操作。

  4. 機器手臂轉動實作:本課程將以機器手臂轉動為例進行實際操作,更加深入地了解所學知識的應用和實踐操作。


這是這週我們所使用的code的程式碼

繪製形狀;改變旋轉錨點



class Board {
  String code;
  int x=0, y=0;
  int w=100;
  int h=40;
  boolean bMoving=false;
  boolean bChoosing=false;
  int ancherX, ancherY;
  float tx=0,ty=0,tz=0;
  int id=0;//myDrawObject(id)
  boolean bLower=false;
  int glType=0;//0:glPushMatrix(), 1:glPopMatrix(), 2:glTranslatef(), 3:glScalef(), 4:myDrawObject(), 5:glPopMatrix()
  Board(String _code, int _glType, int _x, int _y){
    glType = _glType;
    code=new String(_code);
    x=_x; 
    y=_y;
    w=int(textWidth(code));
  }
  Board(String _code, int _x, int _y) {
    code=new String(_code);
    x=_x; 
    y=_y;
    w=int(textWidth(code));
  }
  Board() {
    code=new String();
  }
  Board(Board sample) {
    code=new String(sample.code);
    x=sample.x;
    y=sample.y;
    w=sample.w;
    h=sample.h;
    bMoving=sample.bMoving;
    ancherX=sample.ancherX;
    ancherY=sample.ancherY;
  }
  boolean insideBoard(int px, int py) {//test if (px,py) inside the board
    if ( x<=px && px<=x+w && y<=py && py<y+h ) return true;
    return false;
  }
  boolean insideRange(int px, int py){
    if( x<=px && px<=x+300 && y<=py && py<y+h ) return true;
    return false;
  }
  void draw() {
    if (bChoosing) {
      pushMatrix();
      translate(x+w/2, y+h/2);
      if(bMoving) rotateZ(radians(-5));
      fill(255, 0, 0, 128); 
      stroke(0); 
      rect(-w/2, -h/2, w, h);
      fill(0); 
      text(code, -w/2, -h/2);
      popMatrix();
    } else {
      int dy=0;
      if(bLower) dy=h;
      noFill();
      stroke(0); 
      rect(x, y+dy, textWidth(code), 40);
      fill(0); 
      text(code, x, y+dy);
    }
  }
  void updateCode(){
    if(glType==1){
      code = "glTranslate("+nf(tx,1,2)+","+nf(-ty,1,2)+");";
    }
  }
}
String []code={"glPushMatrix", "glTranslate", "glRotatef", "glScalef;", "myDrawObj();", "glPopMatrix"};
ArrayList<Board> currentCode;
Board movingBoard=null;
ArrayList<PVector> curve=null;
ArrayList<ArrayList<PVector>> all;
color [] objC={#FF3700, #FFAF00, #FFF700, #2DFF00, #009FFF, #FF00EF};
int [] bornAngle=new int[6];
int topC=0;
int rotAngle=0;
boolean bKeepRotating=false;
void setup() {
  size(900, 400, P3D);hint(DISABLE_DEPTH_TEST);
  textSize(32);
  textAlign(LEFT, TOP);
  all = new ArrayList<ArrayList<PVector>>();
  currentCode = new ArrayList<Board>();
  int i=0;
  currentCode.add( new Board("glPushMatrix();", 0, 420, 50+40*i++) );
  currentCode.add( new Board("glTranslatef(0,0,0);", 1, 440, 50+40*i++) );
  currentCode.add( new Board("glRotatef(angle,0,0,1);", 2, 440, 50+40*i++) );
  currentCode.add( new Board("glTranslatef(0,0,0);", 1, 440, 50+40*i++) );
  currentCode.add( new Board("glPopMatrix();", 5, 420, 50+40*i++) );
}
void draw() {
  background(255);
  drawAxis(400, 400);
  myDrawNew();//drawObjects();
  drawCode();
  if (bKeepRotating) rotAngle++;
  fill(0); 
  if(rotAngle<10) text("angle=  "+(rotAngle)%360, 730,0);
  else if(rotAngle<100) text("angle= "+(rotAngle)%360, 730,0);
  else text("angle="+(rotAngle)%360, 730,0);
  noFill(); rect(750,350,textWidth("ToDraw"),50);
  fill(255,0,0); text("ToDraw",750,350);
}
void drawCode() {
  for (Board b : currentCode) {
    b.draw();
  }
  if (movingBoard!=null) {
    movingBoard.draw();
  }
}
void drawAxis(int w, int h) {
  fill(0);
  rect(0, 0, w, h);
  stroke(255);
  fill(255);
  line(0, h/2, w, h/2);
  line(w, h/2, w-20, h/2-10);
  line(w, h/2, w-20, h/2+10);
  text("x", w-textWidth("x"), h/2);

  line(w/2, 0, w/2, h);
  line(w/2, 0, w/2+10, 20);
  line(w/2, 0, w/2-10, 20);
  text("y", w/2-textWidth("y"), 0);
  text("0", w/2-textWidth("0"), h/2);
}
void myDrawNew(){
  pushMatrix();
  translate(200,200);  
  for(Board b : currentCode){
    //0:glPushMatrix(), 1:glPopMatrix(), 2:glTranslatef(), 3:glScalef(), 4:myDrawObject(), 5:glPopMatrix()
    if(b.glType==0) pushMatrix();
    if(b.glType==1){ellipse(0,0,3,3); translate(b.tx*200, b.ty*200, b.tz*200);}
    if(b.glType==2) rotateZ(radians(rotAngle));
    //if(b.glType==3) scale(b.tx,b.ty,b.tz);
    if(b.glType==4) myDrawObject(b.id);
    if(b.glType==5) popMatrix();
  }
  if(movingBoard!=null){
    myDrawObject(movingBoard.id);
  }
  popMatrix();
  fill(255, 128);
  strokeWeight(1);
  if (curve!=null) {
    beginShape();
    for (PVector pt : curve) {
      vertex(pt.x, pt.y);
    }
    endShape();
  }
}
void myDrawObject(int obj){
  if(obj >= all.size() ) return ;
  ArrayList<PVector> one = all.get(obj);

  fill(#ff0000); ellipse(0,0, 10,10);
  fill(objC[obj], 200);
  pushMatrix();
    translate(-200,-200);
    beginShape();
    for(PVector pt : one){
      vertex(pt.x, pt.y);
    }
    endShape(CLOSE);
  popMatrix();
}
void drawObjects() {
  strokeWeight(2);
  for (int c=0; c<all.size(); c++) {//all.size() is always less than 6
    ArrayList<PVector> one = all.get(c);
    pushMatrix();
    translate(200, 200);
    rotateZ(radians(rotAngle-bornAngle[c]));
    translate(-200, -200);
    fill(objC[c], 200);
    beginShape();
    for (PVector pt : one) {
      vertex(pt.x, pt.y);
    }
    endShape(CLOSE);
    popMatrix();
  }
  fill(255, 128);
  strokeWeight(1);
  if (curve!=null) {
    beginShape();
    for (PVector pt : curve) {
      vertex(pt.x, pt.y);
    }
    endShape();
  }
}
int nowState=0;//1: draw curve, 2: select code, 3: translate
Board candidate=null;
void mousePressed() {
  candidate=null;
  for(Board b : currentCode){
    if(b.bChoosing==true){
      candidate=b;
      if(b.glType==1) nowState=3;//for translate
    }
  }
  
  for (int i=0; i<currentCode.size(); i++) {
    Board now = currentCode.get(i);
    now.bChoosing=false;
    if ( now.insideBoard(mouseX, mouseY) && now.glType!=0 && now.glType!=5 ) {
      nowState=2;
      movingBoard = currentCode.get(i);
      movingBoard.bMoving=true;
      now.bChoosing=true;
      movingBoard.ancherX=mouseX-movingBoard.x;
      movingBoard.ancherY=mouseY-movingBoard.y;
      for(int k=i+1; k<currentCode.size(); k++){
        Board next = currentCode.get(k);
        next.y -= next.h;
        next.bLower=true;
      }
      currentCode.remove(i);
      //break;
    }
  }
  if (mouseX<400 & nowState==3){  }
  else if (mouseX<400 & topC<6) nowState=1;//in the drawing area
  
  if (nowState==1) {
    curve = new ArrayList<PVector>();
  }
}
void mouseDragged() {
  if (nowState==3) {
    candidate.tx += (mouseX-pmouseX)/200.0;
    candidate.ty += (mouseY-pmouseY)/200.0;
    candidate.updateCode();
  }
  if (nowState==1) {
    curve.add(new PVector(mouseX, mouseY));
  } else if (nowState==2) {
    movingBoard.y += (mouseY-movingBoard.y-movingBoard.ancherY);
    for(int i=0; i<currentCode.size(); i++){
      Board b = currentCode.get(i);
      b.bLower=false;
      if(b.insideRange(mouseX,mouseY)){
        for(int k=i; k<currentCode.size();k++){
          currentCode.get(k).bLower=true;
        }
        break;
      }
    }
  }
}
void mouseReleased() {
  if (nowState==3) nowState=0;
  if (nowState==1) {
    all.add(curve);
    curve=null;
    nowState=0;
    bornAngle[topC]=rotAngle;
    Board obj = new Board("myDrawObject("+topC+");", 4, 440, 50);
    obj.id=topC;
    currentCode.add(0, obj); 
    for(int i=1; i<currentCode.size();i++){
      Board b = currentCode.get(i);
      b.y += b.h;
    }
    topC++;
  } else if (nowState==2) {
    for(int i=0;i<currentCode.size();i++){
      Board b = currentCode.get(i);
      if(b.insideRange(mouseX,mouseY)){
        for(int k=i;k<currentCode.size();k++){
          Board b2=currentCode.get(k);
          b2.bLower=false;
          b2.bChoosing=false;
          b2.bMoving=false;
          b2.y+=b2.h;
        }
        movingBoard.y=b.y-b.h;
        movingBoard.bMoving=false;
        currentCode.add(i, movingBoard);
        movingBoard=null;
        nowState=0;
        break;
      }
    }
    if(nowState==2){
      Board last = currentCode.get(currentCode.size()-1);
      movingBoard.y = last.y + last.h;
      movingBoard.bMoving=false;
      currentCode.add(movingBoard);
      movingBoard=null;
      nowState=0;
    }
  }
}
void keyPressed() {
  if (key==' ') bKeepRotating = !bKeepRotating;
  if (key=='1' && movingBoard==null) {
    movingBoard=new Board("glPushMatrix();", mouseX, mouseY);
  }
}

沒有留言:

張貼留言