向量的正規化,是指在不改變向量方向的情況下,讓它的長度變成1,也就是變成單位向量(unit vector)。
要找出向量u的單位向量,記做û,其實挺簡單的,計算方式為
û = u / ‖u‖
稍微計算一下,就可以知道‖û‖=1。
在pygame中,可以使用normalize()
來做向量的正規化。
在做向量的正規化時,由於要除以向量的長度,所以長度為0的向量,也就是零向量,是沒辦法正規化的。因此,在寫程式的時候,必須先排除零向量的情況,然後才能進行向量正規化。例如,要做向量vec
的正規化時,可以這樣寫:
unit_vec = vec.normalize() if vec.length() > 0 else 0*vec
這樣子,如果vec
是零向量,就不會進行正規化,而直接把單位向量設定成零向量。要注意的是,視vec
是二維或三維向量而定,程式中的0*vec
也可以寫成pygame.Vector2(0, 0)
或pygame.Vector3(0, 0, 0)
。寫成0*vec
的好處,在於可以不需要多費心去注意vec
是二維或三維向量,最後得到的,一定會是和vec
有相同維度的零向量。
接下來的這個例子,是由畫面中心點,沿著滑鼠游標位置的方向,畫出長度為50的向量。不管滑鼠游標如何移動改變位置,向量的長度都固定為50。
Example 1.6: Normalizing a Vector
# python version 3.10.9
import sys
import pygame # version 2.3.0
pygame.init()
pygame.display.set_caption("Example 1.6: Normalizing 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)
# 計算向量及其單位向量,如果向量是零向量,則不進行正規化,並將單位向量設為零向量
vec = mouse - center
unit_vec = vec.normalize() if vec.length() > 0 else 0*vec
# 畫長度為50的向量
endpoint = center + 50*unit_vec
pygame.draw.line(screen, BLACK, center, endpoint, 10)
pygame.display.update()
frame_rate.tick(FPS)