If you're seeing this message, it means we're having trouble loading external resources on our website.

Jeżeli jesteś za filtrem sieci web, prosimy, upewnij się, że domeny *.kastatic.org i *.kasandbox.org są odblokowane.

Główna zawartość

Amplituda i okres oscylacji

Czy już jesteście zdumieni? W sekcji o ruchu kątowym opanowaliśmy całkiem niezłe zastosowania tangensa (na przykład znajdowanie kąta wektora), sinusa i cosinusa (do konwersji z współrzędnych biegunowych do kartezjańskich). Moglibyśmy w tym momencie zatrzymać się i być zadowolonym. Ale nie zatrzymamy się. To dopiero początek. To, co może dla Was zrobić sinus i cosinus wykracza poza wzory matematyczne i trójkąty prostokątne.
Spójrzmy na wykres przedstawiający funkcję sinus, gdzie y = sin(x)
Można zauważyć, że wynikiem funkcji sinus jest gładka krzywa kursująca pomiędzy –1 i 1. Ten rodzaj zachowania jest znany jako oscylacja, okresowy ruch pomiędzy dwoma punktami. Szarpanie struny gitarowej, ruch wahadła, skakanie na drążku pogo—są to przykłady ruchu oscylacyjnego.
I tak oto szczęśliwie odkrywamy, że możemy symulować oscylacje w programach korzystających z ProcessingJS przypisując wynik funkcji sinus do lokalizacji obiektu. Zauważcie, że w analogiczny sposób używaliśmy szumu Perlina w dziale o szumach.
Zacznijmy od prostego scenariusza. Chcemy, aby nasze kółko oscylowało od lewej do prawej strony płótna.
To jest tak zwany prosty ruch harmoniczny (albo, żeby brzmieć mądrzej, “są to okresowe sinusoidalne drgania obiektu”). Ten program bardzo łatwo jest napisać, ale zanim zabierzmy się za programowanie, zapoznajmy się z pewnymi zwrotami używanymi przy okazji oscylacji (i fal).
Ruch harmoniczny może być wyrażony w postaci dowolnego położenia (w naszym przypadku chodzi o współrzędną x) jako funkcja czasu, z następującymi dwoma elementami:
  • Amplituda: Odległość od środka ruchu do skrajnego położenia
  • Okres: Czas potrzebny na jeden pełen cykl ruchu
Patrząc na powyższy wykres sinusa, możemy zauważyć, że amplituda wynosi 1 a okres jest równy TWO_PI; wartość tej funkcji nigdy nie wykracza poza 1 lub -1, a co TWO_PI radianów (albo 360 stopni) wzór fali się powtarza.
W naszym świecie ProcessingJS, czym jest amplituda, a czym okres? Amplitudę można łatwo wyrazić w pikselach. W przypadku okna szerokiego na 200 pikseli, oscylujemy o 100 pikseli na prawo od środka, oraz 100 pikseli na lewo. Dlatego też:
// Nasza amplituda mierzona w pikselach
var amplitude = 100;
Okres to czas, który jest wymagany do wykonania pełnego cyklu, ale czym jest czas w ProcessingJS? Mam na myśli to, że na pewno chcielibyśmy być w stanie ustawić, aby nasze kółko oscylowało co trzy sekundy. Możemy śledzić ile milisekund upłynęło w naszym programie (za pomocą milis()) i wymyślić odpowiedni algorytm który będzie oscylował obiekt na podstawie rzeczywistego czasu.
Możemy jednak wykorzystać inny sposób: możemy użyć tego, że ProcessingJS ma wbudowane pojęcie "ramki" i domyślnie program stara się działać z prędkością 30 "klatek na sekundę." ProcessingJS posiada zmienną frameCount, która informuje nas na której ramce aktualnie się znajdujemy, oraz funkcję frameRate() która pozwala nam zmienić preferowaną liczbę klatek na sekundę. 30 klatek na sekundę to domyślna wartość, pozwalająca wygenerować płynną animację oszukującą ludzki mózg, ale czasami warto spowolnić działanie programu, na przykład podczas testów.
Możemy więc określić nasz okres na podstawie liczby klatek które już były wyświetlone, gdyż ma to bardzo mocne odniesienie do czasu w prawdziwym świecie - możemy powiedzieć, że ruch oscylacyjny powinien się powtarzać co 30 ramek, albo co 50 ramek, albo co 100 ramek itp.
// Nasz okres jest liczony w klatkach (naszej jednostce czasu dla animacji)
var period = 120;
Skoro mamy już amplitudę i okres, pora napisać wzór który wyliczy x w zależności od czasu, który podmienimy na naszą aktualną liczbę klatek.
var x = amplitude * sin(TWO_PI * frameCount / period);
Podzielmy nasz wzór aby zrozumieć każdą jego część. Pierwsza jest prawdopodobnie najłatwiejsza. Cokolwiek zostanie wyliczone przez funkcję sinusa mnożymy przez amplitudę. Wiemy, że sinus oscyluje pomiędzy -1 a 1. Jeżeli weźmiemy tą wartość i pomnożymy ją przez amplitudę, otrzymamy oczekiwany wynik: wartość oscylującą pomiędzy -amplitude a amplitude. (Uwaga: w tym miejscu możemy również użyć funkcji map() z ProcessingJS aby odwzorować wartość funkcji na nasz zakres.)
A teraz zobaczmy, co znajduje się wewnątrz funkcji sinus:
TWO_PI * frameCount / period
Co tu się dzieje? Zacznijmy od tego, co wiemy. Wiemy, że sinus powtórzy swoją wartość co 2PI radianów—zaczynając od 0 i powtarzając się na 2PI, 4PI, 6PI i tak dalej. Jeżeli okres wynosi 120 klatek, chcemy aby ruch oscylacyjny powtarzał się gdy frameCount będzie wynosić 120 klatek, 240 klatek, 360 klatek i tak dalej. frameCount to jedyna zmienna: zaczyna się od 0 i rośnie. Zobaczmy, jakie wyniki daje ten wzór przy tych wartościach.
frameCountframeCount / periodTWO_PI * frameCount / period
000
600.5PI
1201TWO_PI
24022 * TWO_PI (or 4* PI)
itp.  
frameCount podzielony przez okres mówi nam ile cyklów już się odbyło—czy jesteśmy dopiero w połowie pierwszego cyklu? Czy skończyliśmy już dwa cykle? Mnożąc tą liczbę razy TWO_PI, otrzymamy wynik który chcemy, ponieważ TWO_PI to liczba radianów wymagana przez sinus do skończenia jednego cyklu.
Podsumowując to wszystko, oto program który oscyluje współrzędną x kółka za pomocą amplitudy równej 100 pikseli oraz okresem 120 klatek.
Warto również wprowadzić teraz pojęcie częstotliwości: liczba cykli na jednostkę czasu. Częstotliwość równa jest wartości jeden podzielonej przez okres. Jeżeli okres wynosi 120 klatek, tylko 1/120 cyklu jest wykonana w jednej sekundzie, tak więc częstotliwość = 1/120 cyklów/klatkę. W powyższym przykładzie, po prostu określiliśmy jak często występuje oscylacja poprzez pojęcie okresu, więc nie potrzebowaliśmy zmiennej dla częstotliwości.
Zauważcie, że to wszystko osiągnęliśmy za pomocą samej funkcji sinusa (sin() w ProcessingJS), ale te same kwestie mają też zastosowanie w przypadku funkcji cosinus. Okres jest taki sam dla obu przypadków, a jedyną różnicą jest to, że wartość początkowa jest równa 1 albo 0.

Ten kurs "Symulacje Natury" jest pochodną z "Natury Kodu " stworzonej przez Daniela Shiffmana, użytej pod licencją Creative Commons Attribution-NonCommercial 3.0 Unported License.

Chcesz dołączyć do dyskusji?

Na razie brak głosów w dyskusji
Rozumiesz angielski? Kliknij tutaj, aby zobaczyć więcej dyskusji na angielskiej wersji strony Khan Academy.