官术网_书友最值得收藏!

第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++;
}
主站蜘蛛池模板: 红桥区| 曲周县| 壶关县| 镇安县| 杭锦旗| 武汉市| 康马县| 子洲县| 阳西县| 宁远县| 宁陵县| 延寿县| 宜宾市| 南平市| 科技| 敦煌市| 铁岭市| 溆浦县| 额尔古纳市| 通辽市| 休宁县| 常州市| 清丰县| 田阳县| 伊宁县| 临泽县| 亳州市| 渝北区| 西宁市| 游戏| 天气| 涿州市| 乐至县| 宝坻区| 太保市| 左权县| 泉州市| 邵武市| 铁岭县| 保山市| 威远县|