Metody interpolacjiCopyright (c) 2007 Krystian Komisarek
Wstęp Jest to prosty i krótki artykuł poświęcony temat interpolacji liniowej, kubicznej, splinów. No to ‘fajnie jak w kombajnie’ wiemy teraz wszystko:). Omówię matematykę związaną z krzywymi interpolacji oraz przedstawię przykładowy kod. W artykule pojawi się kilka ciekawych optymalizacji i usprawnień do standardowego podejścia. Oczywiście wszystko będzie tak wytłumaczone, że nie jest potrzebna żadna wiedza tajemna ani pochodzenie z rodziny Einsteina, aby to zrozumieć. Wymagania optymalne aby czytać artykuł to znajomość języka polskiego i podstawy matematyki na poziomie liceum. Jak zwykle postaram się odpowiadać na najważniejsze pytanie "dlaczego?". Na koniec artykułu dla wytrwałych zajmę się interpolacją wektorów i obrotów zapisanych kwaternionami. Co to interpolacja oraz do czego służy? Zanim przejdę do sedna sprawy musze odpowiedzieć na pewne ważne pytanie nurtujące nie jedną osobę, która przypadkowo mogła wybrać mój artykuł nie wiedząc tak naprawdę, o czym będzie i czeka z niecierpliwością, aż wytłumaczę, czym tak naprawdę jest interpolacja. Synonim do słowa „interpolacja” to „przejście od do w czasie”. Tak wiem dość rozbudowany i dziwny synonim, ale krótszego nie wymyślę, dlatego korzysta się z uproszczonej nazwy tego mechanizmu :). Jeśli nadal nic nie jest jasne to wytłumaczę w inny sposób. Wyobraźmy sobie 2 punkty A i B w dowolnej przestrzeni R1 (dla tych, którzy nie wiedzą, co mam namyśli to R oznacza wymiar w liczbach rzeczywistych np. R3 = 3D), R2, R3, a jak ktoś potrafi to nawet w R4 lol. Teraz wyobraźmy sobie, że mija czas w przedziale t <0,1> (ci, co sobie wyobrażali R4 pewnie mają teraz problem :). Teraz opiszmy problem, który ten artykuł ma za zadanie rozwiązać. Jak przedostać się z punktu A do B w czasie t <0,1>? Dokładniej. W jaki sposób określić pozycję punktu pośredniego pomiędzy A i B w czasie t gdzie t = 0 odpowiada punktowi A, a t = 1 to B? Odpowiedź prosta Interpolując te punkty po czasie t :). P(t) to funkcja która zwróci nam wyszukiwany wynik. Pozostaje do rozwikłania jeszcze jedna zagadka, po co nam to ? Interpolacja może nam się przydać w wielu przypadkach pogranicza nas tylko wyobraźnia. Konkretniej mam na myśli:
To tylko wybrane przypadki w których ja korzystam z interpolacji, tak naprawdę jest o wiele więcej dlatego zachęcam do skrupulatnego czytania artykułu. Postać ogólna funkcji interpolującej Mógłbym pominąć ten krok wypisać wzory na kolejne rodzaje interpolacji, które są dość proste, ale niewiele z nich da się wywnioskować bezpośrednio. Czytelnicy artykułu uznaliby, że mówię prawdę i tym samym używaliby ich jak czarnej magii. Nie zrobię tak jednak, ponieważ nie było to celem mojego artykułu a raczej rozwikłanie zagadki matematycznej. Aby cokolwiek zrobić trzeba poznać odrobinę teorii związanej z zagadnieniem w tym przypadku musimy dowiedzieć się jak wygląda ogólna postać funkcji interpolacji, a wtedy stanie się jasność. Podam teraz szablonowy wzór interpolacji:
Postać ogólna funkcji interpolującej.
P(t) - Szukany punkt interpolowany w czasie t. Dlaczego tak jest? Wypada wytłumaczyć, aby to zrobić przekształćmy wzór do odrobinę innej formy:
Geometryczna forma wzoru na inteprolację.
P(t) - Szukany punkt interpolowany w czasie t. Naturalnie to właśnie funkcja g(t) wpływa na sposób interpolacji pomiędzy punktami może to być dowolna funkcja spełniająca następujące warunki:
Interpolacja liniowa (linear)
Najprostszy sposób interpolacji, jaki
można sobie wyobrazić to przenoszenie punktu po linii prostej z równomiernym
rozkładem. Wytłumaczę to w bardzo prymitywny sposób, jaki znam.
Interpolacja nazywa się liniowa, ponieważ do funkcja
interpolująca g(t) jest liniowa zapiszmy ją w następujący sposób wraz z
warunkami: Mamy więc naszą szukaną funkcje interpolującą w pełnej okazałości. Co z pewnością zachwyca nas prostotą :). Wraz z wykresem. g(t) = t P(t) = A*(1-t) +B*(t) Tutaj wprowadzimy pewną modyfikację wzoru zauważmy, że korzystając z równania zapisanego geometrycznie obliczeń będzie mniej, ponieważ pozbywamy się jednego mnożenia na rzecz odejmowania wektorów (to taka mała optymalizacja).
Wzór na interpolacje liniową gdzie A B to punkty kontrolne t czas na przedziale <0,1>
Na koniec kod naszej funkcji zajmującej się interpolacją pisany w Delphi: Liniowy sposób interpolacji jest bardzo prosty i szybki ma jednak jedną wadę interpolacja wykonuje się ciągłe z tą samą prędkością, tak więc przejście z punktu do drugiego punktu odbywa się ostrym startem i ostrym finiszem. W niektórych przypadkach jednak to podejście się bardzo przydaje. Interpolacja kubiczna/sześcienna (cubic) Drugi rodzaj interpolacji niweluje największy problem poprzedniego a więc ostry start i finisz. Tym razem startując z punktu 0 wraz ze wzrostem t punkt powoli przyspieszy a w momencie osiągnięcia t=0.5 będzie miał największą prędkość później znowu zwolni aż w punkcie 1 będzie miał prędkość 0. Tak jak poprzednim razem interpolacja otrzymała swoją nazwę od sposobu, w jakim powstała. Interpolacja kubiczna - sześcienna powstała z wielomianu trzeciego stopnia. Sprawdźmy, więc i tym razem warunki początkowe oraz wzór ogólny wielomianu:
g(t) = a*t3 + b*t2 + c*t + d
Z tych warunków wzoru nie wyprowadzimy. Przyjrzyjmy się wykresowi funkcji, jaką chcielibyśmy uzyskać. Wiemy także, że pochodna funkcji g(t) w punktach krańcowych musi się równać 0. Dla niewtajemniczonych w interpretacji geometrycznej wartość pochodnej w punkcie jest współczynnikiem kierunkowym stycznej do wykresu w tym punkcie. My chcemy, aby te współczynniki w punkcie 0 i 1 były równe 0 wtedy na krańcowych wartościach zmiana prędkości będzie najmniejsza.
Obliczmy więc pochodną:
Kolejny raz sukces. Mamy więc naszą szukaną funkcje interpolacyjną kubiczną . Dla ciekawskich dodam, że wyprowadzona funkcja ma nawet swojego imiennika jest to jedna z czterech podstawowych funkcji mieszania Hermita używanych w interpolacji. Czasem nazywanych też funkcjami wtapiania "blending functions". Mało tego drugą funkcję można uzyskać z zależności g2(t) := 1-g(t). Pozostałe dwie funkcje poznamy w dalszej części artykułu.
Interpolacja kubiczna wyraża się, więc wzorem: Na koniec kod naszej funkcji zajmującej się interpolacją kubiczną: Zauważmy, że w podobny sposób możemy wyprowadzić dowolną funkcję interpolująca pod warunkiem ze znamy jej własności. Warto, więc dokładnie zrozumieć teorię by można dzięki temu stworzyć na przykład funkcję hybrydową do interpolacji liniowej i kubicznej gdzie punkt będzie powoli ruszał z miejsca i gwałtownie się zatrzymywał. Nie wyprowadzę tutaj wzoru, ale radzę poćwiczyć by zyskać trochę praktyki. Interpolacja splejnów (Cubic Hermite Spline)
Podobnie jak w poprzednim przypadku korzystając z wiadomości o
stycznych i miejscach zerowych wielomianu możemy wyprowadzić
wzory na m(t) i n(t) obliczenia jednak pominę i pozostawię do
samodzielnego sprawdzenia się.
Wynik naszych działań to kolejne funkcje Hermita:
W rezultacie po podstawieniu i paru przekształceniach optymalizacyjnych
nasza funkcja interpolacji prędkości jest odrobinę nieczytelna, ale
najważniejsze, że wiemy, dlaczego właśnie tak wygląda:
Jest jeszcze druga wersja tego wzoru,
którą warto używać w przypadku, gdy współczynniki funkcji Hermita mamy wcześniej
obliczone wygląda ona następująco. Obliczanie stycznej w punkcie (Spline Tangent) Musimy sobie zdawać ze interpolacja nie ogranicza się tylko do dwóch punktów zyskuje na przydatności, gdy stworzymy n punktów kontrolnych, które w odpowiedniej kolejności chcemy przechodzić wraz z mijającym czasem. Pojawia się jeszcze jedna kwestia do rozwiązania, a mianowicie nie wiemy, w jaki sposób liczyć wektory styczne dla wierzchołków. W tym przypadku także z pomocą przychodzi nam matematyka, istnieje wiele metod określenia wartości stycznej. Najprostszy i moim zdaniem najlepszy sposób to skorzystać z wierzchołków pobliskich. Dlatego też my ograniczymy się do wpływu tylko dwóch sąsiadów poprzednika oraz następnika. Załóżmy, że nasza krzywa jest cykliczna tzn. zamknięta. Pk to wybrany punkt z krzywej. Tk (od Tangent) to nasza styczna w punkcie Pk. Potrzebny nam będzie jeszcze a - współczynnik dobrany doświadczalnie określający siłę wpływu sąsiadów na styczną (ja wybieram 0.7).
Wzór na styczną w punkcie kontronym: Krzywa musi posiadać minimalnie trzy punkty. Nie jest to jedyny wzór, ale całkowicie wystarcza w szczególnych przypadkach, gdy chcemy, aby krzywa miała ostre zakończenie możemy pozostawić, Tk = 0. Interpolacja wektorów i kwatrnionów Interpolacja nie miałaby zbyt wielu zastosowań gdyby nie to ze można z niej korzystać również dla wektorów a po wprowadzeniu odpowiednich warunków dla kwaternionów kwaternionów. W przypadku wektorów nie będziemy mieli najmniejszego problemu zamiast używać wartości skalarnych wystarczy działać na kolejnych współrzędnych wektora i wszystkie wzory w takim przypadku będą poprawnie działały. Interpolacja obrotów nie jest już jednak tak oczywista, ponieważ mamy tam odczynienia z okresowością. Najlepiej będzie pokazać problem na przykładzie. Załóżmy ze nasz obiekt jest obrócony o kąt 360 stopni i chcemy go interpolować liniowo do kąta 0 stopni. Korzystając z interpolacji liniowej w czasie t = 0.5 otrzymujemy obrót 180 stopni, co jest niepoprawnym wynikiem, ponieważ nasz obiekt nie powinien się wcale ruszyć przecież 360 stopni jest równe 0. Jak radzić sobie z tego typu problemami? Zauważmy, że kwatrnion przeciwny (q*-1) reprezentuje ten sam obrót z tą różnicą, że biedzie się interpolował w przeciwnym kierunku. Wystarczy sprawdzić czy iloczyn skalarny kwaternionów interpolowanych jest mniejszy od 0 wtedy jeden z nich znajduje się w drugiej połówce i wiemy, że trzeba zmienić kierunek interpolacji. Oto odrobina pseudokodu:
A,B - kwaterniony punkty kontrolne
A,B - kwaterniony punkty kontrolne Dla interpolacji splejnów należy wykonać podobną operacje trzy razy jednak styczne będzie trzeba na nowo obliczyć.
A,B,C,D - kwaterniony punkty kontrolne (t jest pomiędzy B i C) Zakończenie
To już wszystko, to tylko skrawek tego, co ukrywa się pod
pojęciem interpolacja, a tym bardziej krzywe. Domyślam się,
iż w tej chwili każdy czytelnik artykułu ma dosyć słowa,
które przewinęło się tu kilkadziesiąt razy. Wytrwałym
dziękuję za uwagę z nadzieją, iż artykuł był przydatny
myślę o następnym, w którym pokażę jak korzystać z zdobytej
wiedzy. Mam nadzieje, że mało herezji było w tym co napisałem
jeśli jednak coś znajdziecie proszę pisać różnież czekam na
pochwały skargi zażalenia oraz trudne pytania. |