###### tags:`Precessing` `2023寒假` `Beady` `找專研題目` `寫程式` # 2023寒假_串珠Beady [Beady: Interactive Beadwork Design and Construction](https://www.is.ocha.ac.jp/~yuki/beady/index-e.html?fbclid=IwAR2IUOgB1pi31MR6ELdc6QyLu-EWcxvQiPpRAnbF7hKQN4yN4xMqplPbdLc) ## processing 的基礎3D功能 ### 角度、打光、移動、旋轉 <font color="#f00">P3D</font> 開啟processing的OpenGL 3D功能 <font color="#f00">box( )</font> 類似電腦圖學C語言中的 glutSolidCube() 座標原點在左上角 為了讓物體在畫面中心,需要將物體移到==translate(寬度/2,高度/2)== ==radians( )== 是換算 degrees度數 及 radians弧度 <font color="#f00">linghts( )</font> 打光 ```p void setup(){ size(300, 300, P3D); } void draw(){ lights(); background(#FFFFF2); pushMatrix(); translate(150,150); rotateY(-radians(mouseX)); rotateX(-radians(mouseX)); box(100); popMatrix(); } ``` ![](https://i.imgur.com/0AmaN78.png) ### 頂點、畫圖、球體 ==beginShape()== 開始畫 // glBegin(POLYGON); ==endShape()== 結束畫 // glEnd(); ==vertex()== 頂點 // glVertex2f(x,y); ```p void setup(){ size(300, 300, P3D); } void draw(){ lights(); background(#FFFFF2); pushMatrix(); translate(150,150); rotateX(-radians(mouseY)); rotateY(-radians(mouseX)); myShape();//box(100); popMatrix(); } void myShape(){ beginShape(); // glBegin(POLYGON); vertex(-50, -50); // glVertex2f(x,y); vertex(-50, 50); vertex(50, 50); vertex(50, -50); endShape(CLOSE); // glEnd(); } ``` 四個頂點 >>矩形 三個頂點 >>三角形.. ![](https://i.imgur.com/PFBke8Q.png) ==sphere( )== 表面有線條的球 加上 ==noStroke( )== 不要線條 加上打光、移動至視窗中心 ```size(300,300,P3D); lights(); noStroke(); translate(150,150); sphere(112); ``` ![](https://i.imgur.com/d4GCKdM.png) ## 模仿Beady(1)在box的邊上擺球 * 方塊、球不相關 把sphere( )、box( )放進來 ```p= void setup(){ size(300,300,P3D); } void draw(){ lights(); background(255,255,250); pushMatrix(); translate(150,150); rotateY(-radians(mouseX)); fill(255,228,97); box(100); popMatrix(); drawshape(0,0,0); } void drawshape(float x,float y, float z){ fill(#6AA5F5); translate(x,y,z); noStroke(); sphere(50); } ``` ![](https://i.imgur.com/8DpLlt3.png) 為什麼這兩顆球會疊在一起啊? :::danger 新手茫區 :dart: : ![](https://i.imgur.com/uTFONZm.png) 記得要在pushMatrix、popMatrix的組合裡。不然移動會疊加 ::: * 把球放在方塊的邊上 ```processing= void setup(){ size(300,300,P3D); } void draw(){ lights(); background(255,255,250); pushMatrix(); translate(150,150); rotateY(-radians(mouseX)); fill(255,228,97); box(100); drawshape(50,0,50); drawshape(-50, 0, 50); drawshape( 50, 0, -50); drawshape(-50, 0, -50); popMatrix(); } void drawshape(float x,float y, float z){ pushMatrix(); fill(#6AA5F5); translate(x,y,z); noStroke(); sphere(50); popMatrix(); } ``` ![](https://i.imgur.com/IZznUL0.png) processing裡的Z軸指向使用者 ![](https://i.imgur.com/i0N369T.png) ## 讀入OBJ檔、縮放 下載[beady_en.zip](https://www.is.ocha.ac.jp/~yuki/beady/beady_en.zip)解壓縮,找到模型檔以記事本打開 ![](https://i.imgur.com/ajD80cS.png)>>發現頂點的範圍介於-1~1之間 把penguin.obj檔丟進processing裡 ==**PShape**== name ; 宣告 name = ==**loadShape**("name.obj")==; 讀檔 ==**shape**( name );== 畫出模型 因為頂點太小>>要放大 <font color="#f00">scale( )</font> 縮放 ### 轉動的企鵝 ```p PShape penguin; void setup() { size(500, 500, P3D); penguin =loadShape("penguin.obj"); } void draw() { background(255, 255, 255); lights(); translate(250, 250); rotateZ(radians(161)); rotateX(radians(379)); println(mouseX); rotateY(radians(mouseX)); scale(300); shape(penguin); } ``` ![](https://i.imgur.com/vwF8LKa.png) ### 用sphere( )秀出頂點 ![](https://i.imgur.com/9KygOaG.png) v(頂點) 點座標 f(面) int1 int2 int3...第幾個頂點 把第一個面的頂點秀出來>>> f 2 3 8 12 17 * **<font color="#f00">陣列</font>** : 設***已知數量***的點座標 * 宣告 float [ ][ ]v =new float[5][3]; [5][3]因為f1有五個點、每個點有xyz值 直接給每個頂點的值,再把五個頂點讀入v裡 把penguin秀出來 mySphere()在(x,y,z)處畫出球體 用迴圈在5個頂點處 畫出球體 ==frameCount==楨數(60Hz) ```p void draw(){ background(#FFFFF2); lights(); translate(250,250); rotateY(radians(frameCount)); noStroke(); scale(300); shape(penguin); for(int i=0; i<5; i++){ mySphere( v[i][0], v[i][1], v[i][2]); } } void mySphere(float x, float y, float z){ pushMatrix(); translate(x,y,z); sphere(0.03); popMatrix(); } ``` ### 用線串珠_把球連起來 :::danger **第i個點與下一個點連接**,避免超出範圍 迴圈的範圍要減一 ![](https://i.imgur.com/caU0YVp.png) **頭跟尾無法連接、少一條** ![](https://i.imgur.com/tWzxSqn.png) ::: ```p for(int i=0;i<5;i++){ stroke(255,0,0); //紅色的線 strokeWeight(0.01); //線的粗細 line(v[i][0],v[i][1],v[i][2],v[(i+1)%5][0],v[(i+1)%5][1],v[(i+1)%5][2]); //第i個頂點x、y、z } ``` **i=0~i < N ==(i+1)%N取餘數==**... v[0]-v[1] v[1]-v[2] v[2]-v[3] v[3]-v[4] v[4]-v[0] i的範圍:0 1 2 3 4 當i=4時 與第一個點(整除為0)相連 ![](https://i.imgur.com/ZrDfZI7.png) ## 自動讀obj檔,根據頂點找到邊edge,把邊變成珠珠 ### 讀入模型的所有頂點 * 宣告字串,把模型檔以字串讀入 **String[] lines= ==loadStrings==(file);** ![](https://i.imgur.com/WFFduR4.png) ![](https://i.imgur.com/jfLze7U.png) * 把頂點v和面f 分開 **字串的第幾個**lines[i]==**.charAt()**== ```p= void myLoadShape(String file){ String[] lines=loadStrings(file); int V=0,F=0;// How much vertex for(int i=0;i<lines.length;i++){ println(lines[i]); char c=lines[i].charAt(0); if(c=='v')V++; if(c=='f')F++; } println("total vertex:"+V,"total face:"+F); } void setup(){ myLoadShape("penguin.obj"); } ``` ![](https://i.imgur.com/HUizy6O.png) * 把讀到的頂點由String變成PVector ![](https://i.imgur.com/buh5Fz6.png) 1. 宣告陣列來放頂點PVector [ ]OBJv; 2. 決定陣列大小=V+1(因為模型檔f的頂點v是由1開始數的) 3. 用 ==**split()**== 以空白鍵**分割字串**後,放入新設定的字串nums裡![](https://i.imgur.com/yMyoOal.png) 4. V=1,由第一個點開始把向量丟進去x,y,z 5. 每丟好一個後,V++ ```p OBJv=new PVector[V+1];//obj檔裡的f的頂點v是由1開始數,盒子的總數要加一 V=1;//obj檔裡的f的頂點v是由1開始數 for(int i=0;i<lines.length;i++){ char c=lines[i].charAt(0); if(c=='v'){ String[]nums=split(lines[i]," ");//把lines[i]切成3個數字 OBJv[V]=new PVector(float(nums[1]),float(nums[2]),float(nums[3]));//第一個是v println(OBJv[V]); V++; } } ``` * 用頂點做出模型 **beginShape()** vertex.... **endShape()** ![](https://i.imgur.com/C0JfOrD.png) ```p void draw(){ background(#FFFFF3); scale(300); lights(); beginShape(); for(int i=1;i<V;i++){ vertex(OBJv[i].x,OBJv[i].y,OBJv[i].z); } endShape(); } ```
{"metaMigratedAt":"2023-06-17T18:26:49.081Z","metaMigratedFrom":"Content","title":"2023寒假_串珠Beady","breaks":true,"contributors":"[{\"id\":\"ff615329-71af-4c50-803c-9ebfabc4522e\",\"add\":6276,\"del\":96}]"}
Expand menu