- Processing開發實戰
- 黃文愷 吳羽 伍馮潔
- 65字
- 2019-01-03 10:41:31
第3章 數學基礎
在繪制圖形和動畫時往往需要計算點、線、面之間的關系,這其中包含了很多數學運算。Processing提供了很多數學函數,方便開發者使用。
3.1 數學計算
對于數學計算中常用到的運算,Processing給出了一系列函數,如表3-1所示。
表3-1 數學計算函數表

?abs(a)返回a的絕對值。
3-1 int a = abs(153); //a賦值為153 int b = abs(-15); //b賦值為15 float c = abs(12.234); //c賦值為12.234 float d = abs(-9.23); //d賦值為9.23
?ceil(a)向上取整。
3-2 float x = 8.22; int a = ceil(x); //a賦值為9
?max()取最大值,有兩種重載(min類似)。
3-3 int a = max(5, 9); //a賦值為9 int b = max(-4, -12); //b賦值為-4 float c = max(12.3, 230.24); //c賦值為230.24 int[] values = { 9, -4, 362, 21 }; //創建一個整型數組 int d = max(values); //d賦值為362
?log(a)返回以e為底,a為真數的對數lna。
3-4 // 求lg float a = log(5)/log(10); //a賦值為0.69897
?dist(x1, y1, x2, y2)返回兩點間的距離。
3-5 // 求點(1,1)到點(4,5)間的距離 float d = dist(1,1,4,5); //d賦值為5.0
3.2 三角函數
對于有關三角的常用運算,Processing給出了一系列函數,如表3-2所示。
表3-2 三角函數表

與數學中的不一樣,Processing中默認以順時針方向旋轉為正方向,另外用PI表示π。
3-6 float a = PI/6; println(sin(a)); //輸出0.5 println(degrees(a)); //輸出30.0 println(a); //輸出0.5235988
atan和atan2都是反正切函數,它們之間有以下兩點不同:
1)參數的填寫方式不同。
例如:有兩個點p1(x1, y1)和p2(x2, y2),這兩個點形成的斜率的弧度計算方法分別是:
3-7 float radian = atan( (y2-y1)/(x2-x1) );
或
3-8 float radian = atan2( y2-y1, x2-x1 );
2)在二、三象限函數的返回結果不同。
3-9 // 在第二象限時 float x = -1.7320508; float y = 1; float tan = atan(y/x); float tan2 = atan2(y/x); println(degrees(tan)); //輸出:-30.0 println(degrees(tan2)); //輸出:149.9999 3-10 // 在第三象限時 float x = -1.7320508; float y = -1; float tan = atan(y/x); float tan2 = atan2(y/x); println(degrees(tan)); //輸出:30.0 println(degrees(tan2)); //輸出:-149.9999
結論:為了根據x、y坐標求得正確的角度,建議使用atan2函數。
3.3 功能映射函數
對于有關映射的運算,Processing給出了一系列函數,見表3-3。
表3-3 映射函數表

?constrain()通過最大值和最小值來約束指定的數。
constrain(amt, low, high) amt: int或float low:最小值 high:最大值
原理:如果amt≥high為真則返回high,如果amt≤low為真則返回low,否則返回amt。
3-11 println(constrain(10,20,80)); //輸出20 println(constrain(50,20,80)); //輸出50 println(constrain(90,20,80)); //輸出90
?lerp()用于在指定的兩數之間線性插值。
lerp(start, stop, amt) start:開始值 stop:結束值 amt:int或float值
插值原理:start+(stop-start)*amt
3-12 float x=lerp(50, 100, 0.1); //將55.0賦值給x float y=lerp(50, 100, 0.5) ; //將75.0賦值給y
?norm()用于把指定數從指定范圍映射到0.0~1.0。
norm(value, start, stop) start:開始值 stop:結束值 value:int或float值
原理:(value-start)/(stop-start)
3-13 float x=norm(60, 50, 100); //將0.2賦值給x float y=norm(45, 50, 100) ; //將-0.1賦值給y float z=norm(110, 50, 100) ; //將1.2賦值給z
?map()用于把指定數從指定范圍映射到另一個范圍。
map (value, start1, stop1, start2, stop2) start1:第一個范圍開始值 stop1:第一個范圍結束值 start2:第二個范圍開始值 stop2:第二個范圍結束值 value:int或float值
原理:start2+(stop2-start2)*norm(value, start1, stop1)
3-14 float x=map(55, 50, 100,500,1000) ; //將550.0賦值給x float y=map(40, 50, 100,500,1000) ; //將400.0賦值給y float z=map(110, 50, 100,500,1000) ; //將1100賦值給z
3.4 隨機數
1.隨機數
在Processing中,如果想要獲取隨機的動畫效果,就要用到和隨機數相關的函數。
random()函數返回一個從0到指定數值范圍內的隨機數。
random(float x) x為float類型數值
示例:
3-15 float a=random(20); // a為0~20的一個隨機數
重載函數random(float x, float y)可以返回兩個指定數值之間的隨機數。
random(float x, float y) x為float類型數值 y為float類型數值
示例:
3-16 float a=random(10,20); //a為10~20的一個隨機數
當編程人員想獲取隨機整數時,需要對隨機數進行類型轉換。
示例:
3-17 int a=(int)random(10,20); //a為10~20的一個隨機整數
示例:在大小為400×400的窗口下繪制16個相等的正方形,使它們的顏色呈隨機灰度,如圖3-1所示。
3-18 void setup() { size(400,400); //窗口大小設置為400×400 } void draw() { for(int i=0; i<4; i++) //第i行 { for(int j=0; j<4; j++) //第j列 { fill(random(255)); //填充顏色為隨機灰度 rect(i*100, j*100,100,100); //畫出寬和高都為100的矩形 } } delay(100); //延遲100毫秒 }
2.隨機數種子
隨機數又分為兩種,一種是真隨機數,另一種是偽隨機數。
真隨機數是計算機通過對外界信息的采集而獲取的。例如,用戶敲擊鍵盤的時間,原子的放射性衰變的時間。這些信息都是不可預測的,于是就能獲取真隨機數。
在Processing中,通過random()函數產生的隨機數并不是真正的隨機數,它們是“偽隨機數”。所獲取的偽隨機數都是通過向計算機發送一個種子值,然后計算機通過算法計算并返回一個看上去像是隨機值的數。實際上,通過這種方法獲得的隨機數都是可以預測的。

圖3-1 隨機灰度格子
通過設置隨機數種子值就能每次都獲取相同的隨機數序列。
randomSeed(long x); x為long類型數值
示例:在窗口大小為400×400下繪制16個相等的正方形,使它們同一行灰度相同,不同行呈隨機灰度,如圖3-2所示。
3-19 void setup() { size(400,400); //窗口大小設置為400×400 } void draw() { for(int i=0; i<4; i++) //第i行 { randomSeed(5); //設置隨機數種子 for(int j=0; j<4; j++) //第j列 { fill(random(255)); //填充顏色為隨機灰度 rect(i*100, j*100,100,100); //畫出寬和高都為100的矩形 } delay(100); //延遲100毫秒 }

圖3-2 隨機數種子生成相同隨機數序列
示例:隨機產生幾個數,為圓的半徑,放入數組,每隔一秒調用一個數組的半徑。
float[] a=new float[10]; //定義一個長度為10的浮點型數組 int j=0; void setup() { frameRate(1); //每秒刷新一次畫面 for(int i=0; i<10; i++) a[i]=random(100); //把隨機生成的數放入數組 } void draw() { background(204); //背景設置為灰色 if(j<10) ellipse(50,50, a[j], a[j]); j++; }
- 高手是如何做產品設計的(全2冊)
- Learn Blockchain Programming with JavaScript
- Responsive Web Design with HTML5 and CSS3
- INSTANT Sencha Touch
- 人臉識別原理及算法:動態人臉識別系統研究
- PHP 編程從入門到實踐
- Oracle Database 12c Security Cookbook
- Raspberry Pi Home Automation with Arduino(Second Edition)
- C語言程序設計實訓教程與水平考試指導
- Laravel Application Development Blueprints
- Python自然語言理解:自然語言理解系統開發與應用實戰
- Learning Nessus for Penetration Testing
- R語言數據挖掘:實用項目解析
- 虛擬現實建模與編程(SketchUp+OSG開發技術)
- Getting Started with hapi.js