2021年3月24日 星期三

電腦圖學筆記-week05

1.Spirograph 萬花尺

畫出大圓


mouse畫出小園

atan2() 算小圓圓心

小圓會旋轉

畫出小圓孔動的軌跡

最終程式
ArrayList<PVector> points;
void setup(){
  size(500,500);
  stroke(255);
  noFill();
  points = new ArrayList<PVector>();
  angle = atan2(-cy, -cx);//一開始mouseX,mouseY為0,所以角度向左上角
}//之後可引導 mousePressed 在小齒輪後, 才能開始控制轉動
float r0=225, r1=50, r2=37;
float cx=250, cy=250;
float angle;
void draw(){
  background(0);
  ellipse(cx,cy, r0*2, r0*2);
  beginShape();
  for( PVector pt : points ){
    vertex(pt.x, pt.y);//之後可變彩色漸層色彩
  }
  endShape();
  float delta = deltaAngle();
  angle += delta;
  println(angle, delta);
  //float angle=atan2(mouseY-cy,mouseX-cx);
  float angle2= -angle * r0 / r1;
  float x=cx+(r0-r1)*cos(angle), y=cy+(r0-r1)*sin(angle);
  line(cx,cy, x, y);
  circle2(x,y, r1, angle2);
}
void circle2(float cx, float cy, float r, float angle){
  ellipse(cx,cy, r*2, r*2);
  for(float a=angle; a<angle+PI*2;a+=PI/4){
    line(cx,cy, cx+r*cos(a), cy+r*sin(a));
  }
}
float deltaAngle(){
  float angleNow=atan2(mouseY-cy,mouseX-cx);
  float angleOld=atan2(pmouseY-cy,pmouseX-cx);
  //不能 angleNow - angle, 要 angleNow-angleOld才行
  float delta = angleNow - angleOld;
  if( abs(delta)> PI ){
    if(delta>0) delta-=PI*2;
    else delta += PI*2;
  }
  return delta;
}
void mouseDragged(){//按下mouse才開始記錄點
  //float angle=atan2(mouseY-cy,mouseX-cx);
  float angle2= -angle * r0 / r1;
  float x=cx+(r0-r1)*cos(angle), y=cy+(r0-r1)*sin(angle);  
  float x2=x+r2*cos(angle2), y2=y+r2*sin(angle2); 
  points.add( new PVector(x2,y2) );
}

2. 複習Transformation 矩陣



3.講解 旋轉再移動 和 先移動再轉動 的差異
旋轉再移動

(由下往上讀)

生成車子 - 調整大小 - 旋轉物體 - 移動物體



移動再轉動
(由下往上讀)

生成車子 - 調整大小  -  移動物體 - 旋轉物體(像放物體在轉盤的邊緣)

4.期中練習網站


5.將上週mousemouse畫物體加上按鍵盤旋轉物體
#include <GL/glut.h>
#include<math.h>
#include<stdio.h>
float ang=0;
int n=0,vx[9999],vy[9999];
static void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    //glColor3b(1,0,0);
    glPushMatrix();
    glRotatef(ang,0,0,1);
    glBegin(GL_LINE_LOOP);
    for(int i=0;i<n;i++){
        glVertex2f((vx[i]-150)/150.0,-(vy[i]-150)/150.0);
    }
    glEnd();
    glPopMatrix();
    glutSwapBuffers();
}
void mouseFunc(int x,int y)
{
    vx[n]=x;
    vy[n]=y;
    n++;
    display();
}
void keyb(unsigned char key,int x,int y)
{
    ang++;
    display();
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

    glutCreateWindow("GLUT Shapes");
    glutKeyboardFunc(keyb);
    glutDisplayFunc(display);
    glutMotionFunc(mouseFunc);
    glutMainLoop();
}





沒有留言:

張貼留言

距地表面160 Week11

 #include "glm.h" GLMmodel* pmodel = NULL; void drawmodel(void) {     if (!pmodel) { pmodel = glmReadOBJ("data/porsche.obj...