全球首創智慧型效果器!Tri-in營運長李冠儀:做硬體如果不認真,做不出東西|數位時代

效果器是搖滾樂團中不可或缺的音色調味料,但至今技術上卻未能創新。平均年齡只有22歲的台灣團隊Tri-in,沒資金、沒經驗,卻開發全球首創的智慧型效果器,他們已準備好席捲六十年如一日的電吉他效果器市場!

來源: 全球首創智慧型效果器!Tri-in營運長李冠儀:做硬體如果不認真,做不出東西|數位時代

它山之石可以攻錯,如何查出一個網站用了什麼外觀主題?

當你逛到一個使用WordPress架的網站,覺得他的頁面不錯,想要知道這個網站用了什麼外觀主題,也可以來使用看看,這個網站可以幫你分析出一個特定的網站內部的主題情報。

WordPress Theme Detector – Free online tool to find a site´s theme

Did you ever wonder what WordPress theme or plugins is that awesome site using? WordPress Theme Detector is the perfect free online tool to find out.

來源: WordPress Theme Detector – Free online tool to find a site´s theme

【程式設計-C#】Array陣列的操作

陣列的排序

Array.Sort() 方法
可用來對指定的一維陣列物件由小而大做遞增排序。
語法1:將一維陣列物件中的元素做由小到大排序 :將一維陣列物件中的元素做由小到大排序
Array.Sort(陣列物件);
語法2:
用來將 陣列物件1 中的元素做由小到大排序,
且 陣列物件2 的元素會隨著 陣列物件1 的
索引位置跟著做排序的動作。
Array.Sort(陣列物件1, 陣列物件2);

陣列的反轉

Array.Reverse() 方法
用來反轉整個一維陣列的順序。
上例用Array.Sort() 方法對指定陣列由小而大遞增排序。
若希望改由大而小作遞減排序,需再將已做完遞增排序
的陣列再用 Array.Reverse() 方法即可將陣列由大而小
作遞減排序。
Array.Reverse() 語法:
Array.Reverse(陣列物件);

[例] 欲對陣列名稱avg做由大而小遞減排序,寫法:
Array.Sort(avg);
Array.Reverse(avg);
若同時有兩個相關陣列 name 和 avg,若以 avg 陣列
為基準由大而小做遞減排序,相關陣列需要同時 ,相關陣列需要同時反轉,
寫法:
Array.Sort(avg,name);
Array.Reverse(avg);
Array.Reverse(name);

陣列的搜尋

.NET Framework 類別程式庫的 Array 類別提供
1. Array.IndexOf()方法
2. Array. BinarySearch() 方法
用來搜尋某個資料是否在陣列物件中。
1. Array.IndexOf()方法
使用 Array.IndexOf 可用來搜尋陣列中是否有相符
資料。
 若有找到,則會傳回該陣列元素的註標值。
若沒有找到,會傳回-1。
語法:
Array.IndexOf(陣列名稱 ,查詢資料 [ ,起始註標] [ ,查詢距離] );

[例] 假設字串陣列 name 中有
{“Jack”,”Tom”,”Fred”,”Mary”,”Lucy”, “Jane” }
共六個陣列元素,觀察下列各陳述式輸出結果:
 Array.IndexOf(name,”Tom”);
[結果] 由註標0開始找起,傳回值為1。
Array.IndexOf(name, ”Tom”, 3) ;
[結果] 由註標3開始找起,傳回值為-1。
若str1=”Lucy” , start=1, offset=2
Array.IndexOf(name, str1, start, offset);
[結果] 由註標1開始往下找2個陣列元素的內容是否
有 ”Lucy” 字串。傳回值為-1。

 

2. Array.BinarySearch()方法
– 用來搜尋陣列中的資料,陣列未經排序 ,陣列未經排序,每次
搜尋資料都由最前面開始,資料量大時,愈後
面的資料查詢所花費的時間愈多,資料平均搜
尋時間不平均。
– 為不管資料前後次序,使得資料平均搜尋時間都
差不多,在 .NET Framework 類別程式庫另提供
此二分化搜尋方法來搜尋資料是否在陣列中。
– 此方法使用前陣列 才可使用
適用於資料量大的陣列。
語法:Array.BinarySearch(陣列名稱, 查詢資料);

陣列的拷貝

將某個陣列複製給另一個陣列時,可用 Array.Copy()
方法進行拷貝陣列。
語法:
Array.Copy (srcAry , srcIndex , dstAry , dstIndex , length );
srcAry :來源陣列即被拷貝的陣列。
srcIndex:代表 srcAry 來源陣列的註標,由指定的註標開始複製。
dstAry :接收資料的目的陣列。
dstIndex:代表 dstAry 目的陣列的註標,由指定的註標開始儲存。
length :表示要複製的陣列元素個數。

陣列的清除

當需要將某個陣列中指定範圍內的陣列元素的內容
清除,可透過 Array.Clear() 方法。語法:
Array.Clear(aryname, startindex, length);
【例1】將 myary 陣列中,註標為 3~4 陣列元素的內容
清除, 寫法:
Array.Clear(myary, 3, 2);
【例2】 將 myary 陣列中所有陣列元素的內容清除,
假設該 陣列共有六個陣列元素。寫法:
Array.Clear(myary, 0, 6);

 

 

【資料結構】陣列

陣列的觀念

【定義】陣列是指一群具有相同名稱及資料型態的變數之集合。

【特性】

  1. 佔用連續記憶體空間。
  2. 用來表示有序串列之一種方式。
  3. 各元素的資料型態皆相同。
  4. 支援隨機存取(Random Access)與循序存取(Sequential Access)。
  5. 插入或刪除元素時較為麻煩。因為須挪移其他元素。

 

【優點】

(1)利用註標(Index)可以快速的輸入資料。

輸入:for(i=0;i<5;i++) //利用「迴圈結構」

A[i]=i*2+1; //快速「輸入資料」到「陣列」中

(2) 利用註標(Index)一次可以輸出大批的資料。

輸出:for(i=0;i<5;i++) //利用「迴圈結構」

WriteLine(A[i]); //從「陣列」一次「輸出大批」的資料

【定義】宣告陣列時,其括弧內的「註標」個數,只有一個時稱為「一維陣列」。在一維陣列中,常使用的運算指令有五種。

  1. 讀取(Read)
  2. 寫入(Write)
  3. 插入(Insert)
  4. 刪除(Delete)
  5. 複製(Copy)

讀取(Read)

【定義】利用註標(Index)來「讀取」資料。

【例如】將A陣列的第二個元素放到X目的變數中。

【寫法】X= A[1]; //陣列的註標是從0開始

【圖解】

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-1

 

寫入(Write)

【定義】利用註標(Index)來「寫入」資料。

【例如】將數值50寫入到陣列的第二個索引位置中。

【寫法】A[1]=50; //陣列的註標是從0開始

【圖解】
%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-2

插入(Insert)

【定義】在指定的註標 i 的位置插入一項新元素,原來註標 i 和之後的元素都必須要再往後挪移一個位置。

【例如】將在註標1的位置插入一項新元素(15)。

【演算法】

Procedure ArrayInsert(int A[],int Max,int i ,int value)  
Begin
  If(i>0 && i<=Max)  //判斷欲插入位置i是否存在,如果有,則
{
  for(count=Max-1;count>i;count--)   //i位置及後面的元素逐一往後挪
    A[count]=A[count-1];
  A[i]=value;                        //最後再將新元素插入到第i位置
}
   Else                              //如果欲插入位置i不存在,則
     Return 0;                      //傳回0
End
End Procedure

 

【圖解】
%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-3
【說明】

首先將30往後挪移一個位置,再將A[1]的元素20,往後挪移放到A[2]位置中,最後再插入15到A[1]中。

刪除(Delete)

【定義】指刪除指定的註標 i 位置的元素,原來註標 i的元素被刪除,為了避免浪費記憶體空間,因此,之後的元素都必須要再往前挪一個位置。

【例如】將在註標1的位置刪除一項舊元素(20)。

【演算法】

Procedure ArrayDelete(int A[],int Max,int i)  
Begin
  If(i>0 && i<=Max)                                       //判斷欲刪除元素位置i是否存在,如果有,則
  {
    for(count=i;count<Max-1;count++)     //i位置後面的元素逐一往前挪
    A[count]=A[count+1];
    A[Max-1]=0;                                           //最後再將0放到最後一個位置
  }
   Else                                                             //如果欲插入位置i不存在,則
     Return 0;                                                   //傳回0
End
End Procedure

【圖解】

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-4

 

【說明】 首先將A[1]的元素20刪除,再將A[2]的元素30往前挪移一個位置,最後再寫入0到A[2]中。

複製(Copy)

【定義】指將「來源陣列」的元素內含值全部逐一copy到「目的陣列」。

【例如】將A陣列的元素內含值全部逐一copy到B陣列中。

【演算法】

Procedure ArrayCopy(int A[],int B[], int Max)  
Begin
  If(Max>0)                                                    //判斷陣列是否有元素內含值,如果有,則
{
  for(count=0;count<Max-1;count++)    //A陣列全部逐一copy到B陣列
    B[count]=A[count];
}
   Else                                                             //如果陣列沒有元素,則
     Return 0;                                                   //傳回0
End
End Procedure

【圖解】

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-5

【說明】

A陣列的元素內含值全部逐一copy到B陣列中,例如A[0]元素會被copy到B[0]中,A[1]元素放到B[1]中,以此類推。

陣列的宣告

(1) 變數宣告

int A, B, C;  //宣告三個變數(A,B,C)為整數型態

以上三個變數與變數之間都是個別獨立的記憶體空間。

(2) 陣列宣告

int A[3];  //宣告一維陣列A,共有A[0]、A[1]、A[2]三個元素

以上三個記憶體空間,可以讓我們連續儲存多項資料,並且資料與資料之間都是按照順序排列的記憶體空間。

 

陣列的儲存方式

【定義】陣列名稱之後加上“註標”即可存取陣列元素。

【舉例】宣告一個A[3]的陣列,並分別儲存10,20,30

 C#
Procedure ArrayCopy(int A[],int B[], int Max)  
Begin
  If(Max>0)                                                    //判斷陣列是否有元素內含值,如果有,則
{
  for(count=0;count<Max-1;count++)    //A陣列全部逐一copy到B陣列
    B[count]=A[count];
}
   Else                                                             //如果陣列沒有元素,則
     Return 0;                                                   //傳回0
End
End Procedure

 

【實例】請依序輸入六位同學的成績到陣列中,並計算及輸出「總和」

第一種寫法:使用陣列,但未使用for迴圈演算法

int A[6] = {100, 98, 88, 67, 75, 90};
int sum = A[0] + A[1] + A[2] + A[3] + A[4] + A[5];
Console.WriteLine("總和為:" + Sum);

第二種寫法:使用陣列,並且使用for迴圈演算法 (最佳)

int A[6] = {100, 98, 88, 67, 75, 90};
int sum = 0;
for (int i = 0; i < 6; i++) {
  sum = sum  + A[i];
}
Console.WriteLine("總和為:" + Sum);

二維陣列的觀念

在前面所介紹一維陣列,可以視為直線方式來存取資料,這對於一般的問題都可以順利的處理,但是對於比較複雜的問題時,那就必須要使用二維陣列來處理。否則會增加程式的複雜度。

例如:計算4位同學的5科成績之總分與平均的問題。

【定義】宣告陣列時,其括弧內的「註標」個數,有兩個時稱為「二維陣列」。

【語法】資料型態 陣列名稱[M][N];

【說明】M代表列數,N代表行數

【存取方法】利用二維陣列中的兩個註標來表示。

 

多維陣列的觀念

【定義】宣告陣列時,其括弧內的「註標」個數,是二個以上時,就稱為「多維陣列」。其中最常見是三維陣列,其圖形為三度空間的立體圖形,並且我們可以將三維陣列視為多個二維陣列的組合。

【語法】資料型態 陣列名稱[L][M][N];

【說明】L代表二維陣列個數,M代表列數,N代表行數

【舉例】設計有某一個大學,3次月考,全班4位同學的5科目成績時。利用三維陣列來存取每人學生的成績。

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-6

【說明】

此例子中Score陣列共有三個註標,故Score陣列是一個三維 陣列。

//其中,第一個註標為:二維陣列的個數: 0~2 共有3個二維陣列

第二個註標為:列註標表示範圍: 0~3 共有4列

第三個註標為:行註標表示範圍: 0~4 共有5行

【圖解】

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-7

【說明】宣告Score是由3個(0~2)二維陣列,每個二維陣列包含4列  (0~3),5行(0~4)組合而成的整數三維陣列。並且共計有3×4×5=60元素。

 

陣列在記憶體中的表示法

陣列是由一連串的記憶體組合而成,其陣列元素之儲存位址計算,

大致上,可分為一維陣列與二維陣列來說明:

Ⅰ. 一維陣列

[題目1]若陣列A有N個元素,其陣列的起始位址為Lo,並且索引值從0開始,d 為元素大小,則A[i]的起始位置為多少?

 

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-8

令:ŒLo為起始位址,d為元素大小,則A[i]之位置計算=Lo+i*d。

【舉例】假設每一個整數佔用2個byte,若A陣列的起始位址是100開始,則A[5]的起始位址為多少?

令:Œ起始位址Lo=100

元素大小d=2

則A[5]之位置計算=Lo+i*d =100+5*2=100+10=110

[題目2]若陣列A的索引從L到U,其陣列的起始位址為Lo, d為元素大小,則A[i]的起始位置為多少?

 

宣告方式:A[L…U]

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-9

令:ŒLo為起始位址,d為元素大小,則A[i]之位置計算=Lo+(i-L)*d

【舉例】假設每一個整數佔用2個byte,若A[10]起始位址是200開始,則A[20]的位址為多少?

令:ŒLo起始位址=200 ,d元素大小=2

則A[20]之位置計算=Lo+(i-L)*d =200+(20-10)*2=200+10*2=220

二維陣列

宣告方式:A[0…M-1, 0…N-1], 其中:M代表列數(Row),橫向,N代表行數(Column),縱向。所以,共有M*N格。

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-10

說明:¡圖的儲存位置:A[1,4],△圖的儲存位置:A[2,1],o圖的儲存位置:A[M-1,N-2]

Row-major(以列為主)

【定義】以列為主的二維陣列要轉為一維陣列時,是將二維陣列「由上往下」一列一列讀入一維陣列。亦即將二維陣列儲存的邏輯位置轉換成實際電腦中主記憶體的存儲方式。

【圖解】

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-11

【以列為主的儲存公式】

Œ令Lo為起始位址,d為元素大小,則二維陣列A[i,j]位置會儲存到一維陣列的那一個位置呢?

公式=Lo+[i*N+j]*d

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-12

Column-major(以行為主)

【定義】以行為主的二維陣列要轉為一維陣列時,必須將二維陣列「由左往右」一行一行讀入一維陣列。亦即將二維陣列儲存的邏輯位置轉換成實際電腦中主記憶體的存儲方式。

【圖解】

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-13

【以行為主的儲存公式】

Œ令Lo為起始位址

d為元素大小

則二維陣列A[i,j]位置會儲存到一維陣列的那一個位置呢?

公式=Lo+[j*M+i]*d

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-14

 

多項式(polynomials)

多項式(polynomial)的表示式為
%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-30

其中Ai為非零項的係數,且多項式的每一項均使用三個欄位來表示(分別為 coef, exp, link) 。其節點的資料結構如下所示:

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-15

其中:Coef:表示該變數的係數

Exp:表示該變數的指數

Link:表示指向下一個節點的指標

【表示方法】

【方法一】依照指數高低依序儲存係數

【作法】假設最高指數為n,則準備一個一維陣列A[1..n+2],

其內容如下:

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-16

【練習】假設f(x)=7X4+5X2+3X

因為最高指數為4,則準備一個一維陣列A[1..6],

【解答】

步驟一:準備一個一維陣列A[1..6]

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-17

步驟二:存入最高指數及分別存入Xn, Xn-1,…,X0之係數

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-18

【優點】

(1)只要儲存係數,比較節省儲存指數空間。

(2)適用於零項次較少的多項式。

【缺點】

不適用於零項次極多的多項式,儲存時非常浪費空間。

Ex: f(X)=5X100+1

則必須要準備一個一維陣列A[1..102],在實際使用上只用了3格,因此,會浪費99格。

 

【方法二】只儲存非零項次的係數與指數

【作法】假設多項式有K個非零項次,則準備一個一維陣列A[1..2K+1],其內容如下:

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-19

 

【練習】假設f(X)=5X100+1

因為有2個非零項次,則準備一個一維陣列A[1..5]

【解答】

步驟一:準備一個一維陣列A

步驟二:存入K 、係數及指數

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-20

【優點】適用於零項次極多的多項式。

【缺點】當非零項次極多時,不適用。

矩陣(Matrices)

【定義】

類似二維陣列,它是利用一個m × n矩陣來表示這個矩陣擁有

m列(Rows)和n行(Columns)。

一般而言,資料結構上常用到的矩陣有四種:

  • 矩陣轉置(Matrix Transposition)
  • 矩陣相加(Matrix Addition)
  • 矩陣相乘(Matrix Multiplication)
  • 稀疏矩陣(Sparse Matrix)

 

矩陣轉置(Matrix Transposition)

【定義】

假設有一個(m × n)矩陣A,則我們可以將A矩陣轉置為(n × m)的B矩陣,並且B矩陣的第j列第i行的元素等於A矩陣的第i列第j行的元素,

以數學式來表示為:Bji=Aij

【假設】A矩陣與B矩陣的m與n都是從1開始計算,因此,A,B矩陣的表示如下:

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-21

說明:A矩陣的第i列第j行的元素等於B矩陣的第j列第i行的元素

【演算法】

Procedure Matrix_Transpose(int m, int n, int A[m][n], int B[n][m])
Begin
  for(i = 1; i <= m; i++)         //外迴圈,先掃瞄第1列到第m列
    for(j = 1; j <= n; j++)       //內迴圈,再掃瞄第1行到第n行
//將A陣列的第i列第j行的元素放到B陣列的第j列第i行的元素中
        B[j][i] = A[i][j];        
End
End Procedure

矩陣相加(Matrix Addition)

【定義】

假設A,B都是(m × n)矩陣,則我們可以將A矩陣加上B矩陣以得到一個C矩陣,並且此C矩陣亦為(m × n)矩陣。因此:

在C矩陣上的第i列第j行的元素必定等於A矩陣的第i列第j行的元素加上B矩陣的第i列第j行的元素。

以數學式來表示為:Cij= Aij+Bij

【假設】A、B、C矩陣的m與n都是從1開始計算,因此,A,B兩個矩陣相加等於C矩陣,其表示如下:

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-22 %e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-23

【演算法】

Procedure Matrix_Add(int m, int n, int A[m][n], int B[m][n], int C[m][n])
Begin
for(i = 1; i <= m; i++)          //外迴圈,先掃瞄第1列到第m列
     for(j = 1; j <= n; j++)         //內迴圈,再掃瞄第1行到第n行
       /*將A陣列的第i列第j行的元素加上B陣列的第i列第j行的元素之後,
          放到C陣列的第i列第j行的元素中 */
      C[i][j] = A[i][j] + B[i][j];
End
End Procedure

矩陣相乘(Matrix Multiplication)

【定義】

假設A為(m × n)矩陣,而B為(n × p)矩陣,則我們可以將A矩陣乘上B矩陣以得到一個(m × p)的C矩陣,因此,在C矩陣上的第i列第j行的元素必定等於A矩陣的第i列乘上B矩陣的第j行(兩個向量的內積),以數學式來表示為:

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-24

【假設】A、B、C矩陣的m與n都是從1開始計算,因此,A,B兩個矩陣相乘等於C矩陣,其表示如下:

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-25

 

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-26

【演算法】

Procedure Matrix_Mul(int m, int n, int p, int A[m][n], int B[n][p], int C[m][p])
Begin
  for(i = 0; i < m; i++)      //外迴圈,先掃瞄第1列到第m列
    for(j = 0; j < n; j++)     //內迴圈,再掃瞄第1行到第n行
      {
        C[i][j]=0;
/*將A矩陣的第i列第j行的元素加上B矩陣的第i列第j行的
元素的結果放到C矩陣上的第i列第j行的元素中*/
        for(k=0;k<p;k++)
          C[i][j] = C[i][j] + A[i][k] * B[k][j];
     }
End
End Procedure

 

C#程式

#include <iostream>  
 
void MultiplyWithOutAMP() {  
 
    int aMatrix[3][2] = {{1, 4}, {2, 5}, {3, 6}};  
    int bMatrix[2][3] = {{7, 8, 9}, {10, 11, 12}};  
    int product[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};  
 
    for (int row = 0; row < 3; row++) {  
        for (int col = 0; col < 3; col++) {  
            // Multiply the row of A by the column of B to get the row, column of product.  
            for (int inner = 0; inner < 2; inner++) {  
                product[row][col] += aMatrix[row][inner] * bMatrix[inner][col];  
            }  
            std::cout << product[row][col] << "  ";  
        }  
        std::cout << "\n";  
    }  
}  
 
void main() {  
    MultiplyWithOutAMP();  
    getchar();  
}

稀疏矩陣(Sparse Matrix)

【定義】 是指矩陣中大部份元素都沒有使用,元素稀稀落落,所以稱為稀疏矩陣。

【概念】在M × N 的矩陣中,多數的資料值為0。

【處理方法】

【方法一】直接利用M × N的二維陣列來一一對應儲存。

【缺點】

1. 浪費空間:因為多數為0。

2. 浪費時間:因為要處理一些不必要的計算。

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-27

【方法二】利用3-tuple結構來儲存非零元素

【作法】假設有一個M*N的稀疏矩陣中共有K個非零元素,則必須要準備一個二維陣列A[0..K,0..2]

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-28

%e8%b3%87%e6%96%99%e7%b5%90%e6%a7%8b-%e9%99%a3%e5%88%97-29

 

Adobe 請來 88 歲「攝影超新星」西本喜美子,教大家活用 PS 與 LR | 攝影札記 Photoblog – 新奇好玩的攝影資訊、攝影技巧教學

之前我們介紹過 88 歲的攝影師西本喜美子,近日和日本 Adobe 合作,以 Lightroom 和 Photoshop 製作了 2017 年的年賀狀(新年賀卡)

來源: Adobe 請來 88 歲「攝影超新星」西本喜美子,教大家活用 PS 與 LR | 攝影札記 Photoblog – 新奇好玩的攝影資訊、攝影技巧教學

【DSM教學】拉動 Pull – 掃掠 Sweep

在DSM中,拉動是以平面垂直的方向進行,除此之外,DSM提供了另一個拉動功能-掃掠,可以自定非直線拉動的軌跡。

dsm-sweep

首先畫一個圓(大小不拘)

dsm-sweep-basic-1

 

進入3D模式,讓圓形成平面。 再選擇草圖模式,選擇Z軸的平面:

dsm-sweep-basic-3

用雲形曲線繪出掃掠的軌跡:

dsm-sweep-basic-5

dsm-sweep-basic-6

dsm-sweep-basic-7

選取拉動功能,選擇要拉動的平面。

選擇掃掠功能。

選擇至,點選拉動軌跡的末端: dsm-sweep-basic-9

完成:dsm-sweep-basic-11

 

 

【範例】

 

 

 

 

【Sweeping with multiple trajectories】

 

【練習 繪製手榴彈】 Hand Grenade