向量

tags: Competitive Programming Note 108 師大附中校隊培訓

本文已停止更新,新版請至 WiwiHo 的競程筆記

108 師大附中校隊培訓簡報

何謂向量

向量(Vector)表示特定的長度和方向,簡單來說,你可以想成向量是一個箭頭。例如物理上的力、位移都算是向量。

向量可以是任何維度的,也就是說,有二維向量、也有三維向量、一維向量……,然後一個

n 維向量可以用
n
個數字來表示,第
i
個數字表示要往第
i
個維度的正向走多少距離(如果是負數,就是往負向走),而這個向量可以被看成是一個從起點指向終點的箭頭,舉例來說:


這是一個二維向量,它表示向著
x
軸正向走
2
,並向著
y
軸正向走
3
,所以如果從原點開始走,會走到點
(2,3)

(詳細的數學定義有興趣可以自己去查。)

向量有幾種表示方式,有把數字放在矩陣裡,寫成

[v1v2...]
[v1v2...]
這種形式的,也有放在多元組裡,寫成
(v1,v2,...)
的,如果沒有特別需要用到矩陣,通常會用多元組來表示。

一個

n 維向量
(v1,v2,...,vn)
的長度可以用類似畢式定理來算:
i=1nvi2

長度為

0 的向量稱為「零向量」,零向量可以是任意方向的。為了方便,除非特別註明,接下來提到的向量都不包含零向量。

基本符號:

  • AB
    ,也可以寫成
    BA
    A
    B
    是點,表示由
    A
    指向
    B
    的向量。(注意向量沒有特定的起終點,只能規定它的方向和長度)
  • A
    A
    是點,等同於
    OA
    O
    是原點。
  • |v|
    ,向量
    v
    的長度。

基本運算

可以發現到,由原點指向某個點

(x,y) 的向量,就是
(x,y)
,所以也可以把點想成是向量、也可以把向量想成是點,這會有助於理解接下來的東西。

加減

兩個向量可以相加得到新的向量,就把所有維度的分量分別相加就好:

(u1,u2,u3,...)+(v1,v2,v3,...)=(u1+v1,u2+v2,u3+v3,...)

例如,

(2,3)+(3,1)=(5,4)

兩個向量相加等同於兩個力的合力,你也可以發現它會滿足平行四邊形法則。

至於減法,就移項一下就可以暸解要怎麼做了,也可以想成是一個向量加上另一個向量的反向,或者是把兩個向量想成點,

AB=AB,也就是一個從點
B
指向點
A
的向量,例如,
(2,3)(3,1)=(1,2)

純量乘法

沒有方向的量稱為純量,像是

1
12
π
這些數字都是純量。向量可以乘上一個純量,得到一個新的向量,也就是將這個向量的長度乘上某一個數字,得到一個新的向量,這個動作非常簡單,就把每個維度的分量都乘上這個純量就好:
i(v1,v2,v3,...)=(iv1,iv2,iv3,...)

例如,

2×(2,3)=(4,6)

內積(點積)

這是向量特有的運算,兩個夾角是

θ
n
維向量
u=(u1,u2,...,un)
v=(v1,v2,...,vn)
的內積記作
uv
,結果是一個純量:
uv=|u||v|cosθ=i=1nuivi

其實就是把每一個維度的分量長相乘後相加,例如二維向量

(x1,y1)(x2,y2)=x1x2+y1y2。意義是作一個
u
v
上垂直投影的向量,然後將這個向量的長和
v
的長相乘。


(內積是
|u|cosθ
再乘上
|v|
,你想要
θ
是裡面那個角還是外面那個角都沒差,畢竟
cosθ=cos(2πθ)
。如果夾角超過直角,那麼投影會在另一邊,此時
|u|cosθ
會是負數。)

FS 在力學上的意義是,對一個物體作一個力
F
,而物體的位移是
S
,則
FS
F
對這個物體所作的功。

既然內積只是多維版本的乘法,那內積也和乘法一樣,滿足交換律、分配律與結合律。

接下來針對兩個向量的夾角

θ 大小來討論內積的結果為何(以下會同時寫上角度和弧度):

  • θ=90=12π

    顯而易見地,如果作用在一個物體上的力和物體位移方向垂直,那麼這個力對這個物體不作功,且
    cos90=cos12π
    也確實為
    0
    ,因此我們知道,兩個垂直的向量內積是
    0
  • θ=0=0

    如果作用在一個物體上的力和物體位移方向相同,那麼這個力作的功等同於力的大小乘上位移距離,同樣
    cos0=cos0
    也是
    1
    ,因此兩個方向相同的向量
    u
    v
    的內積是
    |u||v|
  • θ=180=π

    如果作用在一個物體上的力和物體位移方向相反,那麼這個力作的會是負功,且這個負功的大小等於力的大小乘上位移距離,同樣
    cos180=cosπ
    1
    ,因此兩個方向相反的向量
    u
    v
    內積是
    |u||v|
  • 0=0<θ<90=12π

    也就是兩個向量方向在同一邊的時候,顯然如果作用在一個物體上的力和物體位移方向在同一邊,那麼這個力作的會是正功,同樣
    cosθ
    的範圍會是
    (0,1)
    ,因此兩個夾角是
    θ
    、方向在同一邊的向量
    u
    v
    內積會是一個正數且
    0<uv<|u||v|
  • 90=12π<θ<180=π

    也就是兩個向量方向在不同邊的時候,如果作用在一個物體上的力和物體位移方向在不同邊,那麼這個力作的會是負功,同樣
    cosθ
    的範圍會是
    (1,0)
    ,因此兩個夾角是
    θ
    、方向在不同邊的向量
    u
    v
    內積會是一個負數且
    |u||v|<uv<0

兩向量在不同夾角時的內積:

兩個長度為

1 的向量在不同夾角時的內積(
x
軸為夾角(弧度)、
y
軸為內積):

內積常被用來判斷兩個向量是否垂直,也可以用來判斷兩個向量的方向是否在同一邊、是否相同或者相反。

外積(叉積)

向量特有的運算,在定義上,它只能用在三維,兩個三維向量

u=(x1,y1,z1)
v=(x2,y2,z2)
的外積記作
u×v
,是一個新的二維向量 (
x3,y3,z3
):
u×v=|ijkx1y1z1x2y2z2|=(y1z2z1y2)i(x1z2z1x2)j+(x1y2y1x2)k

其中,

i
j
k
是三個維度的「基向量」,有興趣可以自己查。外積得到的向量會垂直於
u
v
構成的平面,且當
u
v
的夾角是
θ
,外積得到的向量長度是:
||u||v|sinθ|

它的長度等同於兩個向量所夾的平行四邊形面積。

至於它的方向,會依據右手定則,右手食指指向

u,中指指向
v
,大姆指的方向就會是
u×v
的方向。

以上看不懂都沒關係,因為它的三維定義不重要。二維向量的外積在比賽上比較常用,但剛剛不是說只能用在三維?你會發現把第三維全部代

0,就會變成:
u×v=(x1y2y1x2)k

k 的部分是第三維的基向量,在一般的直角座標系,它是
(0,0,1)
,長度是
1
,然後我們不要管它,把二維外積定義為三維外積的長度(純量),如果三維外積的結果向量向上,那二維外積是正的,否則就是負的,可以得出:
u×v=|x1y1x2y2|=x1y2y1x2=|u||v|sinθ

相同地,這個值等同於兩個向量所夾的平行四邊形面積,但它是「有向」的,如果

u 轉向
v
是逆時針,那會是正的,反之就會是負的(這邊的轉指往較近那邊轉),至於夾角
θ
是指
u
往逆時針轉到
v
的角度。

外積不滿足交換律,也就是說

u×vv×u,但它滿足「負交換律」,也就是
u×v=(v×u)
,因為:
(x1,y1)×(x2,y2)=x1y2x2y1=(x2y1x1y2)=(x2,y2)×(x1,y1)

外積不滿足結合律,但滿足分配律。

接下來我們針對各種夾角

θ 討論它的值:

  • θ=90=12π

    這樣兩個向量會夾一個長方形,且
    sin90=sin12π=1
    ,因此兩個夾角為直角的向量
    u
    v
    外積為
    |u||v|
  • θ=270=32π

    這樣兩個向量會夾一個長方形,且
    sin270=sin32π=1
    ,但
    u
    轉向
    v
    是順時針,因此
    u×v=|u||v|
  • θ=0=0

    兩個向量同向,那麼它們夾的平行四邊形面積為
    0
    ,且
    sin0=sin0=0
    ,因此此時外積值為
    0
  • θ=180=π

    兩個向量反向,此時它們夾的平行四邊形面積也為
    0
    ,且
    sin180=sinπ=0
    ,因此此時外積值為
    0
  • 0=0<θ<180=π

    u
    v
    轉是逆時針,且
    sinθ(0,1]
    ,則
    u×v>0
    。除非
    θ=90=12π
    ,不然
    sinθ<1
    ,則
    0<u×v<|u||v|
  • 180=π<θ<360=2π

    u
    v
    轉是順時針,且
    sinθ[1,0)
    ,則
    u×v<0
    。除非
    θ=270=12π
    ,不然
    sinθ>1
    ,則
    |u||v|<u×v<0

兩向量在不同夾角時的外積:

兩個長度為

1 的向量在不同夾角時的外積(
x
軸為夾角(弧度)、
y
軸為外積):

實作

有些人會把向量(或點)做成一個類別,不過我自己是習慣直接用 pair,然後再做運算子重載。

#define F first #define S second #define mp make_pair template<typename T> pair<T, T> operator+(pair<T, T> a, pair<T, T> b){ return mp(a.F + b.F, a.S + b.S); } template<typename T> pair<T, T> operator-(pair<T, T> a, pair<T, T> b){ return mp(a.F - b.F, a.S - b.S); } template<typename T> //純量乘法 pair<T, T> operator*(pair<T, T> a, T i){ return mp(i * a.F, i * a.S); } template<typename T> //純量除法 pair<T, T> operator/(pair<T, T> a, T i){ return mp(a.F / i, a.S / i); } template<typename T> //內積 pair<T, T> dot(pair<T, T> a, pair<T, T> b){ return mp(a.F * b.F, a.S * b.S); } template<typename T> //外積 T cross(pair<T, T> a, pair<T, T> b){ return mp(a.F * b.S, a.S * b.F); } template<typename T> //向量長的平方 T vabs2(pair<T, T> a){ return a.F * a.F + a.S * a.S; }