background image

KMO2D

Kolizje między-obiektowe w 2D

background image

I. Wstęp

3 lata temu na temat kolizji nie miałem żadnego pojęcia. Przyszedł jednak 
czas, gdy postanowiłem napisać pierwszą porządną grę i pojawił się, 
wtedy problem. Kolizje, zderzenia i fizyka. Na ich temat informacji w 
polskim internecie było tak nie wiele (i dalej chyba się to nie zmieniło), że 
nawet służba zdrowia w Polsce jest w lepszym stanie. Poszukiwałem, więc 
informacji zagranicą, gdzie znalazłem potężny zbiór wiedzy na ten temat, 
jednak zapoznanie się z tym wszystkim zajęło mi sporo czasu, gdyż 
czytanie takich rzeczy w obcym języku idzie wolniej niż w ojczystym.
W trakcie przechodzenia przez te wszystkie strony, publikacje, artykuły - 
męczenia się z nimi - pomyślałem, że można innym ułatwić trochę drogę i 
postanowiłem, że kiedyś napisze coś na temat kolizji. Tak oto powstał ten 
artykuł. Mam nadzieję, że znajdziecie tu wszytko czego szukacie i 
zapraszam do czytania.

II. Podstawy

Jeśli dopiero zaczynasz naukę i nie wiesz nic na temat wektorów to ten 
rozdział jest jak najbardziej dla Ciebie. Jeśli jednak jest przeciwnie to 
spokojnie możesz go opuścić. Opisane w nim zagadnienia odnoszą się do 
podstawowych treści takich jak dodawanie, odejmowanie czy mnożenie 
wektorów.

I. Wektory w prostokątnym układzie współrzędnych

I. Wektor
Co to jest wektor? Najprościej mówiąc wektor jest to uporządkowana para 
liczb. Jest zapisywany w postaci:

u=[ x ,y ]

gdzie x i y są jego 

współrzędnymi w prostokątnym układzie współrzędnych.

background image

Jeśli zaczepimy wektor w jakimś dowolnym punkcie w układzie to 
nazywamy go, wtedy wektorem zaczepionym. Współrzędne takiego 
wektora obliczamy w następujący sposób:

AB=[ x

b

x

a

,y

b

y

a

]

gdzie

x

a

, y

a

to współrzędne punktu A (początek wektora),

x

b

,y

b

to 

współrzędne punktu B (koniec wektora).

II. Działania na wektorach
Wektory można do siebie dodawać i od siebie odejmować w wyniku 
czego otrzymujemy nowy wektor. Jest to bardzo prosta operacja 
polegająca na zsumowaniu odpowiednich współrzędnych (przy 
odejmowaniu zmienia się tylko znak). Matematycznie wygląda to 
następująco: mamy dwa wektory

u=[ x

u

, y

u

]

i

v=[ x

v

,y

v

]

, a ich 

sumą jest wektor

c=[ x

v

x

u

, y

v

y

u

]

(dodawanie) i 

c=[ x

v

x

u

, y

v

y

u

]

(odejmowanie).

Następną operacją jaką możemy przeprowadzić na wektorach jest ich 
mnożenie przez skalar (można je również dzielić przez skalar - dzielenie to 
po prostu odwrotność mnożenia). Mnożenie takie można również nazwać 
mnożeniem wektora przez liczbę, gdyż skalar jest jakąś konkretną dla nas 
liczbą. Działanie to polega na pomnożeniu każdej ze współrzędnych 

background image

wektora przez skalar i otrzymaniu nowego wektora.
Matematyka:

Jeśli mamy wektor 

u=[ x

u

, y

u

]

i liczbę 

k

to ich iloczyn zapisujemy w 

postaci

c=uk

czyli

c=[ x

u

k ,y

u

]

. Dzielenie przebiega 

analogicznie

c=u/k

czyli

c=[ x

u

/k , y

u

/k]

.

III. Normalizacja i długość wektora
Mnożenie i dzielenie przez skalar, można zastosować przy normalizowaniu 
wektora, czyli sprowadzaniu jego długości do wartości równej 1. Aby tego 
dokonać należy najpierw znaleźć długość wektora, którą można obliczyć 
stosując twierdzenia Pitagorasa: 

u

=

x

u

y

u

2

.

Posiadając juz długość wektora wystarczy podzielić go przez nią i w ten 
sposób otrzymać wektor

c=u/

u

.

IV. Iloczyn skalarny dwóch wektorów
Jednym z kolejnych działań jest iloczyn skalarny dwóch wektorów. Wyraża 
się on dwoma wzorami (

u , v

- wektory,

u

,

v

- długości wektorów,

- kąt pomiędzy nimi ):

u⋅v=

u

v

∗cos

z geometrii syntetycznej oraz

u⋅v=u

x

v

x

u

y

v

y

z geometrii analitycznej

background image

Iloczyn skalarny ma bardzo szerokie zastosowanie, sam przekonasz się jak 
często będziesz go używać. Oto przykład:
Mamy wektory

u

i

v

. Chcemy obliczyć cosinus kąta pomiędzy nimi. 

Jak? Bardzo prosto, jeśli zauważymy, że we wzorze

u⋅v=

u

v

∗cos

można pozbyć się czynnika

u

v

normalizując długość wektorów 

(czynnik

u

v

jest wtedy równy 1) . Wzór przyjmuje postać 

u⋅v=cos

gdzie jeśli za

u⋅v

podstawimy

u⋅v=u

x

v

x

u

y

v

y

to 

otrzymamy

cos=u

x

v

x

u

y

v

y

. Wniosek taki, że po 

znormalizowaniu obydwu wektorów, ich iloczyn skalarny daje właśnie 
liczbę co do wartości równa

cos

.

V. Wektor prostopadły i równoległy – wyznacznik wektorów
Następnym ważnym pojęciem jest wektor prostopadły. Jeśli mamy 
wektor

u

to wektor do niego prostopadły

v

możemy obliczyć ze wzoru

v=[−y

u

, x

u

]

lub

v

2

=[y

u

,x

u

]

. Każdy wektor ma dwa do siebie 

prostopadłe i są one równie szeroko stosowane jaki i iloczyn skalarny.

background image

Jeśli wektory mogą być prostopadłe to mogą pewnie być i równoległe. Jak 
to sprawdzić? Wektory są równoległe gdy mają ten sam kierunek 
(znajdują się na jednej prostej - w przypadku wektorów zaczepionych 
obliczamy przed ich porównaniem współrzędne wektora swobodnego). Co 
nam to daje? Wiemy dzięki temu, że wektory są równoległe, gdy pierwszy 
pomnożony przez jakąś liczbę rzeczywistą daje drugi lub odwrotnie. 
Matematycznie wygląda to następująco:

u∥⇔ ∃

R

u=k∗∨ v=k∗u

(wektor u jest równoległy do v, wtedy i tylko wtedy, gdy istnieje takie k 
należące do liczb rzeczywistych, że 

u=k∗v

lub 

v=k∗u

).

Zamiast jednak korzystać z tej zależności, można sprawdzić czy wektory 
są równoległe w inny sposób. Można obliczyć wyznacznik wektorów i 
jeśli będzie on równy 0, to wektory są równoległe. Jak się oblicza 
wyznacznik wektorów? Bardzo prosto. Jeśli mamy wektory

u

i

v

, a 

macierz zapisujemy tak:

x

u

y

u

x

v

y

v

 to wyznacznik wektorowy obliczamy z 

wyznacznika macierzy, czyli następująco: 

u ,=

x

u

y

u

x

v

y

v

=x

u

y

v

y

u

x

v

.

Na tym etapie artykułu nie jest ważne co to jest macierz, ani jej 
wyznacznik. Na ten temat znajduje się trochę informacji w osobnym 
rozdział pt. „Macierze”. Wracajmy jednak do wektorów. Istnieje również 
drugi wzór na wartość wyznacznika wektorowego:

u ,

=

u

v

∗sinu , v

. Wyznacznik wektorowy ma bardzo 

szerokie zastosowanie. Można dzięki niemu obliczy np. sinus kąta 
pomiędzy wektorami czy pole trójkąta pomiędzy nimi.

II. Ważne wzory

W dalszej części artykułu bardzo często będziemy korzystać z zawartych w 
tym rozdziale informacji. 

I. Równanie prostej
Każdy wie jak wygląda linia prosta. Prosta ze względu, iż jest pojęciem 
pierwotnym nie posiada definicji. Można ją jednak opisać jako zbiór 
punktów spełniających równanie:

AxByC=0

gdzie

A

i

B

 to 

odpowiednio: współrzędna

x

n

i

y

n

wektora prostopadłego do tej linii 

prostej (do normalnej tej prostej),

C

to przesunięcie prostej (to znaczy 

odległość prostej od punktu (0,0) osi współrzędnych), a

x

i

y

to 

współrzędne punktu ze zbioru. Bardzo ładnie obrazuje nam to rysunek 
poniżej:

background image

Aby wyznaczyć współczynniki równania naszej prostej -

A , B ,C

potrzebujemy 2 punktów leżących na niej. Współczynniki

A

i

B

obliczamy licząc wektor prostopadły do wektora tworzonego przez nasze 2 
punkty, a współczynnik

C

obliczamy przekształcając nasze równanie

AxByC=0

do postaci

−AxBy=C

i podstawiając za

x

i

y

współrzędne któregoś z naszych punktów.

Posiadając równanie konkretnej prostej możemy w prosty sposób 
sprawdzić czy dany punkt leży czy nie leży na niej, podstawiając 
współrzędne punktu pod odpowiednie zmienne równania czy np. obliczyć 
część wspólna dwóch prostych (punkt ich przecięcia, jeśli istnieje). Ważne 
jest to, że prosta posiada dwie strony: dodatnią i ujemną (można to 
rozumieć jako: coś może być „pod” lub „nad” prostą). Jeśli dla jakiegoś 
punktu równanie jest dodatnie to znajduje się on po stronie, na którą 
wskazuje wektor normalny tej prostej (analogicznie sytuacja odwrotna).

background image

II. Odległość punktu od prostej
Korzystając z poznanej przed chwilą zależności, możemy wyprowadzić 
wzór na odległość punktu od prostej. Nie będę go wyprowadzał sam, tylko 
skorzystam z gotowego już wzoru, a dla dociekliwych proponuje wziąć 
kartkę, długopis i go przeanalizować. Wzór:

d=

AxByC

A

B

2

gdzie d to nasza szukana odległość,

x

i

y

to 

współrzędne punktu, a

A , B ,C

to kolejno: współrzędne wektora 

prostopadłego do prostej i przesunięcie prostej.

III. Rzuty

Bardzo powszechnie i ogólnie stosowaną przez nas techniką będzie 
rzutowanie. Rzutowanie jest to najprościej mówiąc „odzwierciedlenie” 
czegoś na czymś np. w rzutowaniu prostopadłym punktu na prostą 
otrzymujemy nowy punkt, który leży na tej prostej, a odcinek utworzony 
przez oba punkty jest prostopadły do tej prostej.

background image

Opisze tutaj dwa rzutowania: równoległe i prostopadłe (które jest 
szczególnym przypadkiem rzutu równoległego).

I. Rzut równoległy punktu na prostą.
Aby dokonać takiego rzutu potrzebujemy punktu i dwóch prostych – 
jedną, która wyznaczy nam kierunek rzutu, drugą, na którą będzie 
odbywał się rzut punktu. W wyniku takiego rzutowania otrzymamy punkt 
będący przecięciem prostej, na która rzutowaliśmy i prostej przechodzącej 
przez nasz wcześniejszy punkt, równoległej do prostej wyznaczającej 
kierunek.

Gdzie:

n

to prosta wyznaczająca kierunek,

k

prosta, na która 

rzutujemy,

P

i

P

1

punkt rzutowany i po rzutowaniu.

Współrzędne punktu po rzutowaniu możemy policzyć następująco: 
najpierw obliczamy równanie prostej przechodzącej przez rzutowany punkt 
i równoległej do prostej wyznaczającej kierunek (proste równoległe różnią 
sie tylko współczynnikiem przesunięcia C), a następnie wyznaczamy punkt 
spełniający nowo powstałe równanie i równanie prostej, na którą 
rzutujemy. Matematyka: Jeśli punkt rzutowany to

 x

p

, y

p

, równanie 

prostej wyznaczającej kierunek to 

k : A

k

xB

k

yC

k

=0

, a prostej, na 

która rzutujemy

l : A

l

xB

l

yC

l

=0

to:

1. Wyznaczamy równanie prostej równoległej do

k

, przechodzącej 

przez punkt

P

(obliczamy nowy współczynnik

C

równania):

C

p

=− A

k

x

p

B

k

y

p

gdzie

C

p

to współczynnik

C

dla nowo 

powstałej prostej

r : A

k

xB

k

yC

p

=0

.

2. Wyznaczamy wspólne rozwiązanie dla nowo powstałej prostej i 

prostej, na którą rzutujemy:

A

k

xB

k

yC

p

=0

A

l

xB

l

yC

l

=0

.

Po przekształceniu otrzymujemy wzory na współrzędne punktu po 

rzutowaniu:

x=

B

k

C

l

A

l

C

p

A

k

B

l

A

l

B

k

i

y=

A

l

C

p

A

k

C

l

A

k

B

l

A

l

B

k

.

background image

II. Rzut prostopadły punktu na prostą.
Rzut taki oczywiście jest jednym z przypadków rzutu równoległego, więc 
wyznaczenie współrzędnych punktu po rzutowaniu można obliczyć z 
wcześniej poznanych wzorów. Chciałbym jednak pokazać inny sposób, z 
którego my będziemy korzystać w takiej sytuacji.
Istnieje coś takiego jak rzut wektora na wektor. Polega on na 
wykorzystaniu pewnej własności iloczynu skalarnego dwóch wektorów. 
Załóżmy, że mamy dwa wektory

u

i

v

, z czego

u

chcemy rzutować na

v

. Iloczyn skalarny w przypadku, gdy jeden z wektorów jest wektorem 

jednostkowym daje wartości równą długości rzutu wektora 
niejednostkowego na wektor jednostkowy. Korzystając z tej własności 
iloczynu, możemy wyznaczyć współrzędne wektora

u

po rzutowaniu na 

wektor

v

następująco: normalizujemy wektor

v

i mnożymy go przez 

wektor

u

, a następnie wartość, która otrzymamy mnoży przez 

znormalizowany wektor

v

. Otrzymujemy wektor

u

po rzucie na wektor

v

czyli

u

1

.

Matematyka przedstawia się tak:

d=u

v

v

=

u⋅v

v

- długość rzutu,

u

1

=

v

v

d

- wektor po rzutowaniu.

Rzutowanie wektorów możemy wykorzystać przy rzutowaniu prostopadłym 
punktu na prosta. Jeśli mamy prosta opisaną za pomocą dwóch punktów i 
trzeci punkt, który będziemy rzutować, to można z tych punktów 
wyznaczyć wektory tak jak na rysunku poniżej:

background image

Dalej rzutowanie przebiega tak jak przy wektorach z jedna różnicą: należy 
dodać do nowo powstałego wektora punkt A (wektor należy zaczepić w 
tym punkcie i traktować jak punkt).

III. Najbliższy punkt na prostej i odcinku.
Rzut prostopadły punktu na prostą możemy wykorzystać przy obliczaniu 
najbliższego punktu na prostej, a także najbliższego punktu na 
odcinku
. O tyle jak obliczenie tego pierwszego to po prostu normalny 
rzut, to z tym drugim sprawa się komplikuje o jedną rzecz. Punkt po 
zrzutowaniu może nie znajdować się pomiędzy końcami odcinka, wiec 
zanim obliczymy rzut trzeba sprawdzić ten fakt. Jeśli nie leży, jest to jeden 
z końców odcinka, jeśli przeciwnie to jest to punkt po zrzutowaniu. Jak 
więc sprawdzić czy punkt leży pomiędzy końcami odcinka? Zauważ, że 
przy rzucie wektora na wektor otrzymujemy długość rzutu. „Długość” 
rzutu może być ujemna, jeśli wektory maja różne zwroty. Wykorzystajmy, 
więc ten fakt. 

Rysunek po lewej przedstawia sytuacje, gdy mnożąc wektor

AP

i wektor

AB

otrzymamy wartość ujemną (widać, że najbliższym punktem na 

odcinku

AB

dla punktu

P

jest punkt

A

). Rysunek po prawej 

przedstawia sytuacje, gdy mnożąc wektor

AP

i wektor

AB

otrzymamy 

wartość większą niż długość odcinka

AB

(widać, że najbliższym punktem 

na odcinku

AB

dla punktu

P

jest punkt

B

). Szukając, więc 

background image

najbliższego punktu na odcinku, należy najpierw sprawdzić czy wynik 
iloczynu skalarnego wektorów

AP

i

AB

jest większy od

0

oraz 

mniejszy od długości odcinka

AB

. Jeśli spełnia obydwa warunki, to jest 

to po prostu rzut punktu na prostą, na której leży nasz odcinek. Jeśli nie i 
jest on mniejszy lub równy

0

, to najbliższym punktem jest punkt

A

odcinka, a jeśli jest on większy od

0

, ale mniejszy od długości odcinka

AB

, to jest to punkt

B

odcinka.

Do sprawdzenia czy punkt po zrzutowaniu leży pomiędzy końcami odcinka

AB

, można również wykorzystać właściwości kątów

 PAB

i

 ABP

Nie będę, jednak tłumaczył jak. Pozostawiam to już do wglądu we 
własnym zakresie.

IV. Obroty

Obracanie figur nie jest jakoś bezpośrednio związane z kolizjami, jednak 
może się przydać. Istnieją dwa obroty: wokół środka układu 
współrzędnych oraz wokół punktu (de facto ten pierwszy jest po prostu 
przypadkiem tego drugiego). Nie ma się w sumie nad czym za bardzo 
rozpisywać - obracanie punktu jest bardzo proste do wyobrażenia i mamy 
tylko dwa równie proste wzory. 

I. Obrót wokół środka układu współrzędnych
Obrót wokół środka układu współrzędnych wygląda następująco:

gdzie:

B

i

B

1

to punkt przed i po obrocie, a

to kąt o jaki obracamy.

Aby w tym przypadku obliczyć współrzędne punktu po obrocie korzystamy 
z tych wzorów:

x

1

=x∗cos−y∗sin

i

y

1

=x∗siny∗cos

gdzie:

to kąt obrotu,

x

1

i

y

1

to współrzędne punkt po obrocie, a

x

i

y

przed nim. 

background image

II. Obrót wokół punktu
Obrót wokół punktu nie różni się niczym od obrotu wokół środka układu 
współrzędnych, z tym, że zanim przystąpimy do obracania należy cofnąć 
wszystkie punkty o współrzędne punktu wokół którego obracamy, a po 
obliczeniu obrotu dodać te współrzędne z powrotem.

gdzie:

P

to punkt wokół, którego kręcimy,

B

i

B

1

to punkt przed i po 

obrocie,

to kąt o jaki obracamy, a

u

to ten wektor, o który cofamy 

(ma współrzędne równe punktowi

P

). Wzory zmienią sie tylko trochę:

x

1

= xx

u

∗cosx

u

−yy

u

∗siny

u

i

y

1

=xx

u

∗sinx

u

yy

u

∗cosy

u

gdzie:

to kąt obrotu,

x

u

i

y

u

to współrzędne wektora

u

,

x

1

i

y

1

to współrzędne punkt po obrocie, a

x

i

y

przed nim. 


Document Outline