pygame的Vector2()、Vector3()支援許多向量的運算,例如
vec + vec
vec - vec
vec * number
number * vec
vec / number
vec // number
vec += vec
vec -= vec
vec *= number
vec /= number
vec //= number
round(vec, ndigits=0)
vec * vec 等同於 dot()
cross()
magnitude() 等同於 length()
normalize()
scale_to_length()
更多更詳細的向量運算,可查閱pygame的說明文件。
接下來,就來看看向量的減法、乘法、除法實際上是怎麼計算的。
先來看向量的減法。假設
u = (ux, uy)
v = (vx, vy)
則
u - v = u + (-v) = (ux, uy) + (-vx, -vy) = (ux - vx, uy - vy)
因為-v是個大小和v相等,但方向相反的向量,所以,減掉一個向量,其實就是加上一個方向相反的向量而已。
下面這個例子,是要在滑鼠游標位置和畫面中心點間畫出直線,而這條直線所代表的,就是畫面中心點到滑鼠游標位置的向量。
Example 1.3: Vector Subtraction
# python version 3.10.9
import sys
import pygame # version 2.3.0
pygame.init()
pygame.display.set_caption("Example 1.3: Vector Subtraction")
BLACK = (0, 0, 0)
GRAY = (180, 180, 180)
WHITE = (255, 255, 255)
screen_size = WIDTH, HEIGHT = 640, 360
screen = pygame.display.set_mode(screen_size)
FPS = 60
frame_rate = pygame.time.Clock()
center = pygame.Vector2(WIDTH//2, HEIGHT//2)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill(WHITE)
mouse = pygame.Vector2(pygame.mouse.get_pos())
pygame.draw.line(screen, BLACK, center, mouse, 5)
pygame.draw.line(screen, GRAY, (0, 0), center, 5)
pygame.draw.line(screen, GRAY, (0, 0), mouse, 5)
pygame.display.update()
frame_rate.tick(FPS)
這個例子在原書中的做法,是使用向量減法算出從畫面中心點到滑鼠游標位置的向量,接著將座標系統的原點平移到畫面中心點,最後畫出新的原點到向量間的直線。因為pygame並沒有轉換座標系統的函數可供使用,所以就直接畫出從畫面中心到滑鼠游標位置的線段。這個例子,對pygame而言,並不是那麼適合用來展現向量減法的用途和好處。
接下來介紹向量的乘法。
向量的乘法指的是向量乘上一個實數,也就是縮放向量的大小。假設要把u縮放α倍,做法如下:
u × α = (ux, uy) × α = (uxα, uyα)
這也就是說,要縮放向量,只要同時把各個分量乘上相同的縮放倍數就可以了。
向量乘法滿足交換率、結合律和分配率(distributive rule):
交換率:u × α = α × u
結合律:(α × β) × u = α × (β × u)
分配律:
(α + β) × u = α × u + β × u
(u + v) × α = u × α + v × α
下面這個例子,是從畫面中心點到滑鼠游標位置畫出一條線段,然後將其縮短1/2。
Example 1.4: Multiplying a Vector
# python version 3.10.9
import sys
import pygame # version 2.3.0
pygame.init()
pygame.display.set_caption("Example 1.4: Multiplying a Vector")
BLACK = (0, 0, 0)
GRAY = (180, 180, 180)
WHITE = (255, 255, 255)
screen_size = WIDTH, HEIGHT = 640, 360
screen = pygame.display.set_mode(screen_size)
FPS = 60
frame_rate = pygame.time.Clock()
center = pygame.Vector2(WIDTH//2, HEIGHT//2)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill(WHITE)
mouse = pygame.Vector2(pygame.mouse.get_pos())
pygame.draw.line(screen, GRAY, center, mouse, 3)
endpoint = center + 0.5*(mouse - center)
pygame.draw.line(screen, BLACK, center, endpoint, 5)
pygame.display.update()
frame_rate.tick(FPS)
程式的重點在於端點的求法。以向量的觀點來看,端點為
endpoint = center + 0.5*(mouse - center)
如果純粹以座標的觀點來看,端點為
endpoint = 0.5*(mouse + center)
事實上,這兩個不同觀點算出來的,是一模一樣的東西,只是呈現的方式不同罷了。
結束這節前,也來看一下除法的計算方式。和乘法一樣,除法的計算方式也是依各分量分別計算就可以了,也就是說
u / α = (ux, uy) / α = (ux/α, uy/α)
除法和乘法其實是一體兩面,因為
u / α = (1/α)×u