Source
%pip install ipywidgets
Requirement already satisfied: ipywidgets in c:\users\youri\anaconda3\lib\site-packages (8.1.7)
Requirement already satisfied: comm>=0.1.3 in c:\users\youri\anaconda3\lib\site-packages (from ipywidgets) (0.2.2)
Requirement already satisfied: widgetsnbextension~=4.0.14 in c:\users\youri\anaconda3\lib\site-packages (from ipywidgets) (4.0.14)
Requirement already satisfied: ipython>=6.1.0 in c:\users\youri\anaconda3\lib\site-packages (from ipywidgets) (7.31.1)
Requirement already satisfied: jupyterlab_widgets~=3.0.15 in c:\users\youri\anaconda3\lib\site-packages (from ipywidgets) (3.0.15)
Requirement already satisfied: traitlets>=4.3.1 in c:\users\youri\anaconda3\lib\site-packages (from ipywidgets) (5.14.3)
Requirement already satisfied: backcall in c:\users\youri\anaconda3\lib\site-packages (from ipython>=6.1.0->ipywidgets) (0.2.0)
Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in c:\users\youri\anaconda3\lib\site-packages (from ipython>=6.1.0->ipywidgets) (3.0.20)
Requirement already satisfied: jedi>=0.16 in c:\users\youri\anaconda3\lib\site-packages (from ipython>=6.1.0->ipywidgets) (0.18.1)
Requirement already satisfied: pickleshare in c:\users\youri\anaconda3\lib\site-packages (from ipython>=6.1.0->ipywidgets) (0.7.5)
Requirement already satisfied: setuptools>=18.5 in c:\users\youri\anaconda3\lib\site-packages (from ipython>=6.1.0->ipywidgets) (63.4.1)
Requirement already satisfied: pygments in c:\users\youri\anaconda3\lib\site-packages (from ipython>=6.1.0->ipywidgets) (2.11.2)
Requirement already satisfied: decorator in c:\users\youri\anaconda3\lib\site-packages (from ipython>=6.1.0->ipywidgets) (5.1.1)
Requirement already satisfied: matplotlib-inline in c:\users\youri\anaconda3\lib\site-packages (from ipython>=6.1.0->ipywidgets) (0.1.6)
Requirement already satisfied: colorama in c:\users\youri\anaconda3\lib\site-packages (from ipython>=6.1.0->ipywidgets) (0.4.5)
Requirement already satisfied: parso<0.9.0,>=0.8.0 in c:\users\youri\anaconda3\lib\site-packages (from jedi>=0.16->ipython>=6.1.0->ipywidgets) (0.8.3)
Requirement already satisfied: wcwidth in c:\users\youri\anaconda3\lib\site-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython>=6.1.0->ipywidgets) (0.2.5)
Note: you may need to restart the kernel to use updated packages.
1. Introductie: Waarom goniometrie?¶
Waarom zou je je überhaupt bezighouden met iets als sinus en cosinus? Het klinkt als iets uit een stoffig wiskundeboek, maar de kans is groot dat je vandaag al tientallen keren in aanraking bent gekomen met goniometrie — zonder dat je het wist.
Denk eens aan een schommel op een speeltuin. Of aan het kloppende ritme van je hart. Misschien luister je nu naar muziek — ook dat is in essentie niets anders dan een opeenvolging van geluidsgolven. Golven, trillingen, herhalingen — ze zijn overal. En of je nu natuurkunde, economie, scheikunde of muziek studeert: periodieke bewegingen zijn fundamenteel.
In de natuurkunde beschrijven we een trillende veer of een slinger met een sinusfunctie. In de scheikunde zie je golven in reactiemechanismen of spectroscopie. In de economie verschijnen cycli in marktbewegingen — ook dat zijn patronen die je kunt benaderen met goniometrie. Zelfs in animatie en gaming worden rotaties van objecten wiskundig uitgedrukt met sinus en cosinus.
Maar waar komt dat allemaal vandaan? Hoe kan een ronddraaiend punt op een cirkel ineens de sleutel zijn tot het beschrijven van een golf? Dat is waar deze notebook over gaat. We beginnen met iets intuïtiefs: een veer met een blokje eraan. Daarmee bouwen we het begrip op van harmonische beweging, en zien we hoe de cirkelbeweging en de golfbeweging uiteindelijk één en hetzelfde verhaal vertellen — in de taal van de wiskunde: goniometrie.
2. Radialen vs. Graden¶
Een hoek kun je meten in graden, maar ook in radialen. Beide zijn maatvoeringen voor dezelfde eigenschap: de grootte van een hoek.
Waarbij:
- ** ** staat voor een volledige cirkel
- ** radialen ** ook staat voor een volledige cirkel
2.1 Wat is een radiaal?¶
De omtrek van een cirkel is:
Stel dat je maar een deel van een cirkel hebt — een “taartpunt”. dan kun je de booglengte berekenen met:
Hierin is:
- : de hoek in graden
- : de straal van de cirkel
Analogie: Pizza¶
Stel je voor: een pizza van 360°, netjes in 8 stukken gesneden, dus 45° per stuk. Als je 3 stukken eet, heb je van de hele pizza.
Zo werkt het ook met hoeken. Een hoek van 90° is van een cirkel, dus:
Als de straal is (de eenheidscirkel), dan wordt dit:
Deze booglengte is gelijk aan de hoek in radialen, er onstaat dus een evenredigverband/ verhouding tussen graden en radialen:
2.4 Visualisatie¶
Gebruik hieronder de interactieve eenheidscirkel om te zien hoe de booglengte (in radialen) overeenkomt met de hoek (in graden).
- De blauwe straal geeft de hoek aan.
- De rode boog toont de bijbehorende radiaalwaarde.
- De radiaalwaarde verandert live mee met de schuifregelaar.
Source
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import IntSlider, interact
from matplotlib.lines import Line2D
# Updatefunctie
def update(theta_deg):
# Voorbereiding van figuur en plots
plt.figure(figsize=(6, 6))
plt.xlim(-1.2, 1.2)
plt.ylim(-1.2, 1.2)
plt.title("Eenheidscirkel met hoek θ")
plt.grid(True)
plt.axhline(0, color='black', linewidth=0.5)
plt.axvline(0, color='black', linewidth=0.5)
# Eenheidscirkel
circle_theta = np.linspace(0, 2 * np.pi, 1000)
circle_x = np.cos(circle_theta)
circle_y = np.sin(circle_theta)
plt.plot(circle_x, circle_y, 'lightgray')
# Lijnen en objecten die we gaan updaten
line_OP, = plt.plot([], [], 'r-', linewidth=2)
arc_line, = plt.plot([], [], 'b--', linewidth=2)
angle_arc, = plt.plot([], [], 'g-', linewidth=1.5)
point_P, = plt.plot([], [], 'ro')
# Teksten die we updaten
text_P = plt.text(0, 0, '', fontsize=12, color='red')
text_deg = plt.text(0, 0, '', fontsize=10, color='green', ha='center')
text_rad = plt.text(0, 0, '', fontsize=10, color='blue', ha='center')
# Extra vaste labels
plt.text(1.05, 0, 'x', fontsize=12)
plt.text(0, 1.05, 'y', fontsize=12)
plt.text(-0.1, -0.1, 'O', fontsize=12)
theta_rad = np.radians(theta_deg)
x = np.cos(theta_rad)
y = np.sin(theta_rad)
# Update lijn OP
line_OP.set_data([0, x], [0, y])
# Update boog
arc_theta = np.linspace(0, theta_rad, 300)
arc_line.set_data(np.cos(arc_theta), np.sin(arc_theta))
# Hoekboogje
angle_arc_theta = np.linspace(0, theta_rad, 100)
angle_arc_r = 0.3
angle_arc.set_data(angle_arc_r * np.cos(angle_arc_theta),
angle_arc_r * np.sin(angle_arc_theta))
# Punt P
point_P.set_data([x], [y])
text_P.set_position((x + 0.05 * np.sign(x), y + 0.05 * np.sign(y)))
text_P.set_text("P")
# Hoeklabels
text_deg.set_position((0.35 * np.cos(theta_rad / 2), 0.35 * np.sin(theta_rad / 2)))
text_deg.set_text(f"θ = {theta_deg}°")
text_rad.set_position((0.5 * np.cos(theta_rad / 2), 0.5 * np.sin(theta_rad / 2)))
text_rad.set_text(f"{round(theta_rad, 2)} rad")
# Titel
plt.title(f"θ = {theta_deg}° = {round(theta_rad, 2)} rad")
# Interactieve slider
interact(update, theta_deg=IntSlider(min=0, max=360, step=1, value=0, description="Hoek θ (°)"));
Tabel: graden vs. radialen¶
De meest voorkomende hoeken zijn in de onsterstaande tabel weergeven.
Hoek in graden (°) | Hoek in radialen (rad) |
---|---|
0° | 0 |
30° | |
45° | |
60° | |
90° | |
180° | |
270° | |
360° |
2.2 Omrekenen tussen graden en radialen¶
Rekenen met een verhoudingsfactor¶
We kunnen de relatie tussen graden en radialen als een formule opschrijven:
- Van graden naar radialen:
- Van radialen naar graden:
Zo kunnen we bijvoorbeeld berekenen dat: 1 radiaal ≈ 57,3°
Rekenen met een verhoudingstabel¶
Je kunt ook gebruik maken van een kruistabel:
Hele cirkel | Deel van de cirkel | |
---|---|---|
Graden | 360° | 90° |
Radialen | ? |
Kruisproduct:
3. De eenheidscirkel en goniometrische functies¶
De eenheidscirkel is een cirkel met straal en het middelpunt in de oorsprong .
Voor elke hoek kun je een punt op de cirkel aangeven. Dat punt ligt op de rand van de cirkel, op een afstand van 1 vanaf het middelpunt.
We zijn geïnteresseerd in de vraag:
“Hoe hangen de coördinaten en van het punt samen met de hoek ?”
3.1 Van een hoek naar coördinaten¶
Teken een straal van het middelpunt naar het punt op de cirkel. Dit vormt een rechthoekige driehoek als je een lijn tekent van loodrecht naar de -as.
We kunnen deze driehoek analyseren met behulp van goniometrische verhoudingen:
Sinus (SOS):
Cosinus (CAS):
Tangens (TOA):
Dus het punt op de eenheidscirkel kan worden uitgedrukt als:
Visualisatie¶
In de grafiek hieronder zie je de eenheidscirkel.
Met de schuifregelaar kun je de hoek aanpassen. Het bijbehorende punt verschuift over de cirkel, en je ziet hoe de x- en y-waarden veranderen.
- De rode lijn volgt de -waarde:
- De blauwe lijn volgt de -waarde:
Source
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import IntSlider, interact
import matplotlib.gridspec as gridspec
def plot_figure(theta):
# Zet figuur opnieuw op bij elke update
fig = plt.figure(figsize=(10, 12))
gs = gridspec.GridSpec(3, 1, height_ratios=[2, 1, 1])
ax_circle = plt.subplot(gs[0])
ax_cos = plt.subplot(gs[1])
ax_sin = plt.subplot(gs[2])
plt.subplots_adjust(left=0.1, bottom=0.15, hspace=0.4)
# Eenheidscirkel
circle = plt.Circle((0, 0), 1, color='purple', fill=False)
ax_circle.add_artist(circle)
ax_circle.set_xlim(-1.2, 1.2)
ax_circle.set_ylim(-1.2, 1.2)
ax_circle.set_aspect('equal')
ax_circle.grid(True)
ax_circle.set_title("Eenheidscirkel en Rechthoekige Driehoek")
# Assen door oorsprong
ax_circle.spines['left'].set_position('zero')
ax_circle.spines['bottom'].set_position('zero')
ax_circle.spines['right'].set_color('none')
ax_circle.spines['top'].set_color('none')
ax_circle.xaxis.set_ticks([-1, 1])
ax_circle.yaxis.set_ticks([-1, 1])
ax_circle.text(1.05, 0, 'x', fontsize=12)
ax_circle.text(0, 1.05, 'y', fontsize=12)
ax_circle.text(-0.15, -0.15, 'O', fontsize=12)
# Hoek en coördinaten
theta_rad = np.deg2rad(theta)
x = np.cos(theta_rad)
y = np.sin(theta_rad)
# Rechthoekige driehoek
ax_circle.plot([0, x], [0, y], color='black') # Hypotenusa
ax_circle.plot([0, x], [0, 0], color='red') # x-component
ax_circle.plot([x, x], [0, y], color='blue') # y-component
ax_circle.plot(x, y, 'ko') # Punt P
ax_circle.text(x + 0.05, y, f'P(', fontsize=10)
ax_circle.text(x + 0.15, y, f'{x:.2f}', fontsize=10, color='red')
ax_circle.text(x + 0.35, y, f', {y:.2f})', fontsize=10, color='blue')
# Hoekboog
arc_radius = 0.25
arc_angle = np.linspace(0, theta_rad, 100)
arc_x = arc_radius * np.cos(arc_angle)
arc_y = arc_radius * np.sin(arc_angle)
ax_circle.plot(arc_x, arc_y, 'gray')
ax_circle.text(
arc_radius * np.cos(theta_rad / 2),
arc_radius * np.sin(theta_rad / 2),
f'θ = {int(theta)}°',
fontsize=10
)
# Cos/Sin-grafieken
theta_deg = np.linspace(0, 360, 1000)
theta_rad_all = np.deg2rad(theta_deg)
cos_vals = np.cos(theta_rad_all)
sin_vals = np.sin(theta_rad_all)
ax_cos.plot(theta_deg, cos_vals, label='x(θ) = cos(θ)', color='red')
ax_cos.plot(theta, np.cos(theta_rad), 'ko')
ax_cos.text(theta + 5, np.cos(theta_rad), f'({int(theta)}°, {np.cos(theta_rad):.3f})', fontsize=9)
ax_sin.plot(theta_deg, sin_vals, label='y(θ) = sin(θ)', color='blue')
ax_sin.plot(theta, np.sin(theta_rad), 'ko')
ax_sin.text(theta + 5, np.sin(theta_rad), f'({int(theta)}°, {np.sin(theta_rad):.3f})', fontsize=9)
for ax, ylabel in zip([ax_cos, ax_sin], ['cos(θ)', 'sin(θ)']):
ax.set_xlim(0, 360)
ax.set_ylim(-1.2, 1.2)
ax.grid(True)
ax.axhline(0, color='black', linewidth=0.8)
ax.axvline(0, color='black', linewidth=0.8)
ax.set_ylabel(ylabel)
ax.set_xlabel('θ (graden)')
ax.spines['left'].set_position('zero')
ax.spines['bottom'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.set_xticks([0, 180, 360])
ax.set_yticks([-1, 1])
ax.legend()
plt.show()
# Interactieve slider
interact(plot_figure, theta=IntSlider(min=0, max=360, step=1, value=60, description='θ (graden)'));
3.2 Samenhang van eenheidscirkel en sinusgolf¶
Wanneer we een volledige omwenteling maken (van tot ), verandert het teken van en afhankelijk van het kwadrant waarin punt ligt:
Kwadrant | -bereik | Teken van | Teken van | Coördinaat |
---|---|---|---|---|
1e kwadrant | – | + | + | |
2e kwadrant | – | – | + | |
3e kwadrant | – | – | – | |
4e kwadrant | – | + | – |
De eenheidscirkel helpt je om goniometrische functies beter te begrijpen. Elk punt op de cirkel komt overeen met:
Zo zie je dus dat een cirkel beweging in verband staat met een golf beweging.
4. Periodieke functies en hun eigenschappen¶
Goniometrische functies zoals en ontstaan uit de eenheidscirkel. Ze zien eruit als golven: ze herhalen zich, hebben pieken en dalen, en bewegen rond een gemiddelde lijn. Dit noemen we periodieke functies. In dit hoofdstuk leer je hoe deze grafieken worden gevormd én hoe je aan de hand van de grafiek het functievoorschrift kunt bepalen.
4.1 Transformaties van de standaardfunctie ¶
De standaard sinusfunctie is een golffunctie met de volgende eigenschappen:
- Evenwichtsstand:
- Amplitude: 1
- Periode:
- Startpunt:
We kunnen deze functie aanpassen met vier parameters: , , , en :
Elke parameter heeft een specifieke invloed. Hieronder leggen we precies uit wat elke transformatie doet én waarom.
4.1.1 De evenwichtsstand — parameter ¶
De evenwichtsstand is het horizontale middelpunt tussen de toppen en dalen van de golf.
Bij ligt deze op de -as: .
Als we de hele grafiek omhoog of omlaag willen verschuiven, doen we een verticale translatie:
- Omhoog:
- Omlaag:
We voegen simpelweg toe aan elke -waarde van de grafiek.
Dit verandert niets aan de vorm of periode van de golf, enkel de positie op de -as.
Voorbeeldtransformatie:
Resultaat:
🔎 In de figuur zie je (grijs) en (blauw).
De verticale pijl geeft de verschuiving van elk punt met aan.
Source
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import FloatSlider, interact
# Data
x = np.linspace(-np.pi, 2*np.pi, 500)
def plot_translatie(a):
plt.figure(figsize=(10, 4))
plt.xlim(-np.pi, 2*np.pi)
plt.ylim(-3.5, 3.5)
plt.title("Verticale translatie: y = sin(x) → y = a + sin(x)")
plt.xlabel("x")
plt.ylabel("y")
# Assen
ax = plt.gca()
ax.spines['bottom'].set_position('zero')
ax.spines['left'].set_position('zero')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# Lijnen
plt.axhline(0, color='gray', linestyle='--', linewidth=1)
plt.axhline(a, color='blue', linestyle='--', linewidth=1)
plt.plot(x, np.sin(x), color='gray', alpha=0.9, linewidth=1.5, label="y = sin(x)")
plt.plot(x, a + np.sin(x), color='blue', linewidth=2, label="y = a + sin(x)")
# Pijltjes tekenen
for xi in np.linspace(-np.pi, 2*np.pi, 9):
y1 = np.sin(xi)
y2 = a + y1
plt.arrow(xi, y1, 0, y2 - y1, head_width=0.1, head_length=0.1, fc='red', ec='red')
plt.legend()
plt.grid(True)
plt.show()
# Slider toevoegen
interact(plot_translatie, a=FloatSlider(min=-2.0, max=2.0, step=0.1, value=0.0, description='a'));
4.1.2 De amplitude — parameter ¶
De amplitude is de maximale afwijking vanaf de evenwichtsstand.
Bij is de amplitude 1.
Als we de pieken en dalen hoger of lager willen maken, vermenigvuldigen we de functie met :
Hiermee doen we een vermenigvuldiging ten opzichte van de -as.
Elke -waarde wordt -maal zo groot — dus:
- Positieve toppen worden
- Negatieve dalen worden
Voorbeeldtransformatie:
Resultaat:
🔎 In de grafiek zie je (grijs) en (blauw).
Merk op hoe er bij een negatieve waarde een spiegeling plaatsvind.
Source
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import FloatSlider, interact
x = np.linspace(-np.pi, 2*np.pi, 500)
def plot_amplitude(b):
plt.figure(figsize=(10, 4))
plt.xlim(-np.pi, 2*np.pi)
plt.ylim(-2.5, 2.5)
plt.title("Amplitude: y = sin(x) → y = b·sin(x)")
plt.xlabel("x")
plt.ylabel("y")
ax = plt.gca()
ax.spines['bottom'].set_position('zero')
ax.spines['left'].set_position('zero')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.plot(x, np.sin(x), color='gray', alpha=0.6, label="y = sin(x)")
plt.plot(x, b * np.sin(x), color='blue', label="y = b·sin(x)")
for xi in np.linspace(-np.pi, 2*np.pi, 9):
y1 = np.sin(xi)
y2 = b * y1
plt.arrow(xi, y1, 0, y2 - y1, head_width=0.1, head_length=0.1, fc='red', ec='red')
plt.legend()
plt.grid(True)
plt.show()
interact(plot_amplitude, b=FloatSlider(min=-2.0, max=2.0, step=0.1, value=1.0, description='b'));
4.1.3 De hoeksnelheid en periode — parameter ¶
De periode is de lengte van één volledige golf.
Voor is deze standaard .
Als we de periode willen veranderen, moeten we een vermenigvuldiging t.o.v. de -as uitvoeren.
In tegenstelling tot vermenigvuldiging t.o.v. de -as waarbij we vermengivuldigen met de vergroting, gaan we nu juist delen met de vergroting.
Bijvoorbeeld: Als ik een periode van 1 wil vermenigvuldig ik de periode eigenlijk met , als ik een een periode wil moet ik dus vermenigvuldigen met .
- Een nieuwe periode vereist een schaalverandering met factor
- Dus:
Voorbeeldtransformatie:
Resultaat:
De nieuwe functie wordt dan:
waar de hoeksnelheid is: het aantal radialen per eenheid tijd.
🔎 In de figuur zie je (grijs) en (blauw).
De blauwe golf heeft een kleinere of grotere periode dan de standaardgrafiek.
Er zijn 6 horizontale pijlen zichtbaar tussen corresponderende punten.
Source
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import FloatSlider, interact
x = np.linspace(-3*np.pi, 5*np.pi, 1000)
def plot_periode(c):
plt.figure(figsize=(10, 4))
plt.xlim(-3*np.pi, 5*np.pi)
plt.ylim(-1.5, 1.5)
plt.title("Periode: y = sin(x) → y = sin(c·x)")
plt.xlabel("x")
plt.ylabel("y")
ax = plt.gca()
ax.spines['bottom'].set_position('zero')
ax.spines['left'].set_position('zero')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.plot(x, np.sin(x), color='gray', alpha=0.6, label="y = sin(x)")
plt.plot(x, np.sin(c * x), color='blue', label="y = sin(c·x)")
x_samples = np.linspace(-0.5*np.pi, 0.5*np.pi, 6)
for xi in x_samples:
y = np.sin(xi)
x_orig = xi / c
dx = xi - x_orig
plt.arrow(x_orig, y, dx, 0, head_width=0.05, head_length=0.2, fc='red', ec='red')
plt.legend()
plt.grid(True)
plt.show()
interact(plot_periode, c=FloatSlider(min=0.25, max=2.0, step=0.05, value=1.0, description='c'));
4.1.4 De faseverschuiving — parameter ¶
De faseverschuiving bepaalt waar de golf start op de -as.
Bij begint de golf bij en bij begint de golf bij . Als we willen dat de golf start bij , dan moeten we de invoer verschuiven naar rechts met :
BIj verticale tranlaties tellen we de verschuiving op bij het -coordinaat. Bij horizontale translaties trekken we de verschuiving er af
- : naar rechts met
- : naar links met
Voorbeeldtransformatie:
Resultaat:
🔎 In de grafiek zie je (grijs) en (blauw).
Een horizontale pijl toont hoe het startpunt verschuift van naar .
Source
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import FloatSlider, interact
x = np.linspace(-2*np.pi, 4*np.pi, 1000)
def plot_horizontale_translatie(d):
plt.figure(figsize=(10, 4))
plt.xlim(-2*np.pi, 4*np.pi)
plt.ylim(-1.5, 1.5)
plt.title("Horizontale translatie: y = sin(x) → y = sin(x - d)")
plt.xlabel("x")
plt.ylabel("y")
ax = plt.gca()
ax.spines['bottom'].set_position('zero')
ax.spines['left'].set_position('zero')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.plot(x, np.sin(x), color='gray', alpha=0.6, label="y = sin(x)")
plt.plot(x, np.sin(x - d), color='blue', label="y = sin(x - d)")
plt.arrow(0, 0, d, 0, head_width=0.1, head_length=0.2, fc='red', ec='red')
plt.legend()
plt.grid(True)
plt.show()
interact(plot_horizontale_translatie, d=FloatSlider(min=-5.0, max=5.0, step=0.1, value=0.0, description='d'));
4.1.5 De complete transformatie¶
Door alle parameters tegelijk toe te passen, ontstaat de algemene vorm:
🔎 In de grafiek hieronder zie je (grijs) en (blauw).
Je herkent de effecten van , , en afzonderlijk terug in deze totale transformatie.
4.2 Van grafiek naar functievoorschrift¶
Nu je weet wat elke parameter doet, kun je ook van een grafiek terug naar de formule.
Stappenplan:
Evenwichtsstand
Bepaal de horizontale lijn tussen pieken en dalen:Amplitude
Bepaal de afstand van evenwicht naar piek:Periode en hoeksnelheid
Meet de afstand tussen twee opeenvolgende toppen of dalen:Faseverschuiving
Bepaal waar de karakteristieke startpositie zich bevindt (bijv. start van stijgende sinus):
✅ Voorbeeld:
Stel je leest uit een grafiek:
- ,
- De toppen liggen op en
- Het stijgend snijpunt met de evenwichtslijn ligt op
Dan krijg je:
- , dus
Dus de functie is:
Met deze kennis kun je nu zowel een functie tekenen als een functievoorschrift afleiden uit een grafiek!
5. Oplossen van goniometrische vergelijkingen en exacte waarden van en ¶
Bij de vergelijking levert de balansmethode op, maar ook is een oplossing.
Dus:
Dit komt omdat er een symetrie as aanwezig is in bij de functie . Bij de goniometrische en met een constante, is er ook sprake van meerdere oplossingen door symetrie. Dit gaan we per functie uitzoeken.
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider
def plot_x2_symmetry(c):
x_vals = np.linspace(-4, 4, 1000)
y_vals = x_vals**2
fig, ax = plt.subplots(figsize=(10, 6))
ax.set_xlim(-4, 4)
ax.set_ylim(-1, 17)
ax.axhline(0, color='black')
ax.axvline(0, color='black')
# Plot parabool
ax.plot(x_vals, y_vals, color='blue', label=r'$f(x) = x^2$')
# Plot horizontale lijn y = c
ax.axhline(c, color='red', linestyle='--', label=rf'$y = {c:.2f}$')
if c >= 0:
x1 = np.sqrt(c)
x2 = -np.sqrt(c)
# Visualisatie van de snijpunten
ax.plot([x1, x2], [c, c], 'ko') # punten op de parabool
ax.plot([x1, x1], [0, c], color='green', linestyle='--')
ax.plot([x2, x2], [0, c], color='orange', linestyle='--')
ax.plot([x2, x1], [c, c], 'k--', lw=1)
ax.text(x1 + 0.1, c + 0.3, rf"$x_1 = {x1:.2f}$", color='green')
ax.text(x2 - 0.9, c + 0.3, rf"$x_2 = {x2:.2f}$", color='orange')
else:
ax.text(0, 1, "Geen oplossing voor $x^2 = c$ als $c < 0$", color='red', ha='center', fontsize=12)
ax.set_title(r"Symmetrie in de vergelijking $x^2 = c$")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.grid(True)
ax.legend()
plt.show()
# Interactieve slider
interact(plot_x2_symmetry, c=FloatSlider(value=4.0, min=-1.0, max=16.0, step=0.1, description='c'));
5.1 Oplossen van ¶
Stel dat je de vergelijking moet oplossen.
We starten met het idee van de eenheidscirkel.
De sinus van een hoek is de -coördinaat van het bijbehorende punt op de eenheidscirkel.
Dus we stellen de vraag:
Voor welke hoek is ?
Controle via de eenheidscirkel¶
In de interactieve figuur zie je een horizontale lijn op en twee snijpunten met de eenheidscirkel:
Het eerste snijpunt levert een scherpe hoek op:
Het tweede snijpunt ligt in het tweede kwadrant. De hoek bij dit snijpunt is stomp, maar samen met de scherpe hoek vormt deze een halve cirkel. Door symetrie in de x-as kunnen zien we dat eigenlijk de stompe hoek is in het linker figuur en eigenlijk de scherpe hoek is in het rechter figuur. We kunnen dus stellen dat :
Met het schuiven zie je dat dit klopt voor elke waarde van c dus,voor elke hoek klop dus dat:
Source
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Arc
from ipywidgets import interact, FloatSlider
# Tekenfunctie
def draw_unit_circle_sin(c):
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
def configure_axes(ax):
ax.set_aspect('equal')
ax.set_xlim(-1.2, 1.2)
ax.set_ylim(-1.2, 1.2)
ax.axhline(0, color='black', lw=1)
ax.axvline(0, color='black', lw=1)
ax.set_xticks([-1, 0, 1])
ax.set_yticks([-1, 0, 1])
ax.set_title("Eenheidscirkel")
for ax in (ax1, ax2):
configure_axes(ax)
# Paarse eenheidscirkel
t = np.linspace(0, 2*np.pi, 300)
ax.plot(np.cos(t), np.sin(t), color='purple')
ax.axhline(c, color='gray', linestyle='--')
# Eerste oplossing θ₁ = arcsin(c)
theta1 = np.arcsin(c)
x1, y1 = np.cos(theta1), np.sin(theta1)
ax1.plot([0, x1], [0, y1], color='black')
arc1 = Arc((0, 0), 0.4, 0.4, angle=0, theta1=0, theta2=np.degrees(theta1), color='black')
ax1.add_patch(arc1)
label1 = theta1 / 2
ax1.text(0.5 * np.cos(label1), 0.5 * np.sin(label1), f'θ₁ = {np.degrees(theta1):.1f}°', ha='center')
# Tweede oplossing θ₂ = π - θ₁
theta2 = np.pi - theta1
x2, y2 = np.cos(theta2), np.sin(theta2)
ax2.plot([0, x2], [0, y2], color='black')
arc2 = Arc((0, 0), 0.4, 0.4, angle=0, theta1=0, theta2=np.degrees(theta2), color='black')
ax2.add_patch(arc2)
label2 = theta2 / 2
ax2.text(0.5 * np.cos(label2), 0.5 * np.sin(label2), f'θ₂ = {np.degrees(theta2):.1f}°', ha='center')
ax1.text(-1.1, -1.1, r"$\sin(\theta) = y = $" + f"{y1:.2f}", fontsize=11)
ax2.text(-1.1, -1.1, r"$\sin(\pi - \theta) = y = $" + f"{y2:.2f}", fontsize=11)
plt.show()
# Interactie
interact(draw_unit_circle_sin, c=FloatSlider(min=-1.0, max=1.0, step=0.01, value=0.5, description='c'));
Controle via de grafiek van ¶
In de interactieve sinusgrafiek zie je de horizontale lijn snijden met de sinuscurve op twee plekken:
- Het eerste snijpunt bij
- Het tweede snijpunt symmetrisch ten opzichte van :
Deze symmetrie rond is typisch voor de sinusfunctie. We kunnen weer hetzelfde stellen als bij de eenheidcirkel:
Voor het oplossen van van de eerste golf gebruiken we dus: Uit de symmetrie van de sinusfunctie blijkt:
Netzoals hoe je oplost als:
Source
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider
def plot_sin_symmetry(c):
# Setup x-range
x_vals = np.linspace(-0.5 * np.pi, 1.5 * np.pi, 1000)
y_vals = np.sin(x_vals)
# Plot setup
fig, ax = plt.subplots(figsize=(12, 6))
ax.set_xlim(-0.5 * np.pi, 1.5 * np.pi)
ax.set_ylim(-1.2, 1.2)
ax.axhline(0, color='black', lw=1)
ax.axvline(0, color='black', lw=1)
ax.set_xticks([n * np.pi / 4 for n in range(-2, 7)])
ax.set_xticklabels(
[r"$-\frac{\pi}{2}$", r"$-\frac{\pi}{4}$", "0", r"$\frac{\pi}{4}$", r"$\frac{\pi}{2}$",
r"$\frac{3\pi}{4}$", r"$\pi$", r"$\frac{5\pi}{4}$", r"$\frac{3\pi}{2}$"]
)
ax.set_yticks([-1, -0.5, 0, 0.5, 1])
ax.text(1.5 * np.pi, -0.05, 'x', ha='right', va='top')
ax.text(-0.05, 1.2, 'y', ha='right', va='top')
ax.plot(x_vals, y_vals, color='blue', label=r'$\sin(x)$')
ax.axhline(c, color='blue', linestyle='--', label=rf'$y = {c:.2f}$')
ax.axvline(np.pi / 2, color='black', linestyle='--', label=r'$x = \frac{\pi}{2}$')
if abs(c) <= 1:
theta = np.arcsin(c)
x1 = theta
x2 = np.pi - theta
ax.plot([x1, x1], [0, c], color='green')
ax.plot([x2, x2], [0, c], color='orange')
ax.plot([0, x1], [c, c], color='green')
ax.plot([x2, np.pi], [c, c], color='green')
ax.plot([x2, np.pi], [0, 0], color='green')
ax.plot([0, x2], [0, 0], color='orange')
ax.plot([x1], [c], 'ko')
ax.plot([x2], [c], 'ko')
ax.text(x1 + 0.05, c / 2, rf"$x_1 = {x1:.2f}$", color='green')
ax.text(x2 + 0.05, c / 2, rf"$x_2 = {x2:.2f}$", color='orange')
ax.set_title(r'Interactieve visualisatie van $\sin(x) = \sin(\pi - x)$')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.grid(True)
ax.legend()
plt.show()
interact(plot_sin_symmetry, c=FloatSlider(value=0.5, min=-1.0, max=1.0, step=0.01))
Periodiciteit¶
De sinusfunctie is periodiek (herhalend) met een periode van .
Dus dezelfde waarden komen telkens terug bij een verschuiving van .
In de interactieve grafiek zie je dat:
- op
- en op
Daarom geldt algemeen:
met bedoelen we dat een positief geheel getal, negatief geheel getal of gelijk aan 0 is.
5.2 Oplossen van ¶
Stel dat je de vergelijking moet oplossen.
We starten opnieuw met het idee van de eenheidscirkel.
De cosinus van een hoek is de -coördinaat van het bijbehorende punt op de eenheidscirkel.
Dus we stellen de vraag:
Voor welke hoek is het -coördinaat gelijk aan ?
Controle via de eenheidscirkel¶
In de interactieve figuur zie je een verticale lijn op die de eenheidscirkel op twee punten snijdt:
Het eerste snijpunt levert een scherpe hoek op in het eerste kwadrant:
Het tweede snijpunt ligt in het vierde kwadrant en is de gespiegelde hoek ten opzichte van de -as. Deze hoek noemen we:
In de interactieve figuur zie je duidelijk dat deze twee hoeken een -coördinaat van hebben.
Dus geldt algemeen:
Source
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Arc
from ipywidgets import interact, FloatSlider
# Tekenfunctie
def draw_unit_circle_cos(c):
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
def configure_axes(ax):
ax.set_aspect('equal')
ax.set_xlim(-1.2, 1.2)
ax.set_ylim(-1.2, 1.2)
ax.axhline(0, color='black', lw=1)
ax.axvline(0, color='black', lw=1)
ax.set_xticks([-1, 0, 1])
ax.set_yticks([-1, 0, 1])
ax.set_title("Eenheidscirkel")
for ax in (ax1, ax2):
configure_axes(ax)
t = np.linspace(0, 2*np.pi, 300)
ax.plot(np.cos(t), np.sin(t), color='purple')
ax.axvline(c, color='gray', linestyle='--')
# Eerste oplossing θ₁ = arccos(c)
theta1 = np.arccos(c)
x1, y1 = np.cos(theta1), np.sin(theta1)
ax1.plot([0, x1], [0, y1], color='black')
arc1 = Arc((0, 0), 0.4, 0.4, angle=0, theta1=0, theta2=np.degrees(theta1), color='black')
ax1.add_patch(arc1)
label1 = theta1 / 2
ax1.text(0.5 * np.cos(label1), 0.5 * np.sin(label1), f'θ₁ = {np.degrees(theta1):.1f}°', ha='center')
ax1.text(x1 + 0.05, y1, f'({x1:.2f}, {y1:.2f})', fontsize=9)
# Tweede oplossing θ₂ = -θ₁
theta2 = -theta1
x2, y2 = np.cos(theta2), np.sin(theta2)
ax2.plot([0, x2], [0, y2], color='black')
arc2 = Arc((0, 0), 0.4, 0.4, angle=0, theta1=0, theta2=np.degrees(theta2), color='black')
ax2.add_patch(arc2)
label2 = theta2 / 2
ax2.text(0.5 * np.cos(label2), 0.5 * np.sin(label2), f'θ₂ = {np.degrees(theta2):.1f}°', ha='center')
ax2.text(x2 + 0.05, y2, f'({x2:.2f}, {y2:.2f})', fontsize=9)
ax1.text(-1.1, -1.1, r"$\cos(\theta) = x = $" + f"{x1:.2f}", fontsize=11)
ax2.text(-1.1, -1.1, r"$\cos(-\theta) = x = $" + f"{x2:.2f}", fontsize=11)
plt.show()
# Interactie
interact(draw_unit_circle_cos, c=FloatSlider(min=-1.0, max=1.0, step=0.01, value=0.5, description='c'));
Controle via de grafiek van ¶
In de interactieve grafiek zie je de horizontale lijn snijden met de cosinusgrafiek op twee plekken:
- Het eerste snijpunt bij
- Het tweede snijpunt bij
Deze symmetrie rond de -as is typerend voor de cosinusfunctie.
We kunnen stellen:
Dus als , dan is de tweede oplossing .
Periodiciteit¶
De cosinusfunctie is periodiek met een periode van .
Daarom geldt algemeen:
Source
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider
def plot_cos_symmetry(c):
# Setup x-range
x_vals = np.linspace(-1.5 * np.pi, 1.5 * np.pi, 1000)
y_vals = np.cos(x_vals)
# Plot setup
fig, ax = plt.subplots(figsize=(12, 6))
ax.set_xlim(-1.5 * np.pi, 1.5 * np.pi)
ax.set_ylim(-1.2, 1.2)
ax.axhline(0, color='black', lw=1)
ax.axvline(0, color='black', lw=1)
ax.set_xticks([n * np.pi / 2 for n in range(-3, 4)])
ax.set_xticklabels(
[r"$-\frac{3\pi}{2}$", r"$-\pi$", r"$-\frac{\pi}{2}$", "0", r"$\frac{\pi}{2}$", r"$\pi$", r"$\frac{3\pi}{2}$"]
)
ax.set_yticks([-1, -0.5, 0, 0.5, 1])
ax.text(1.5 * np.pi, -0.05, 'x', ha='right', va='top')
ax.text(-0.05, 1.2, 'y', ha='right', va='top')
ax.plot(x_vals, y_vals, color='blue', label=r'$\cos(x)$')
ax.axhline(c, color='blue', linestyle='--', label=rf'$y = {c:.2f}$')
ax.axvline(0, color='black', linestyle='--', label=r'$x = 0$')
if abs(c) <= 1:
theta = np.arccos(c)
x1, x2 = theta, -theta
ax.plot([x1, x1], [0, c], color='green')
ax.plot([x2, x2], [0, c], color='orange')
ax.plot([0, x1], [c, c], color='green')
ax.plot([x2, 0], [c, c], color='orange')
ax.plot([x1], [c], 'ko')
ax.plot([x2], [c], 'ko')
ax.text(x1 + 0.1, c + 0.05, rf"$x_1 = {x1:.2f}$", color='green')
ax.text(x2 - 0.1, c + 0.05, rf"$x_2 = {x2:.2f}$", color='orange')
ax.set_title(r'Interactieve visualisatie van $\cos(x) = \cos(-x)$')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.grid(True)
ax.legend()
plt.show()
interact(plot_cos_symmetry, c=FloatSlider(value=0.5, min=-1.0, max=1.0, step=0.01))
5.3 Algemeen stappenplan voor het oplossen van goniometrische vergelijkingen¶
Het oplossen van en gebeurt altijd in dezelfde drie stappen:
Voor ¶
Gebruik de inverse sinus om de eerste oplossing te vinden:
Gebruik symmetrie om de tweede oplossing te bepalen:
Dit volgt uit het feit dat:
💡 Denk aan de eenheidscirkel: geeft de scherpe hoek in het eerste kwadrant, en de bijbehorende stompe hoek in het tweede kwadrant.
- Gebruik periodiciteit om alle oplossingen te noteren:
waarbij (dus: )
Voor ¶
Gebruik de inverse cosinus om de eerste oplossing te vinden:
Gebruik symmetrie om de tweede oplossing te bepalen:
Dit volgt uit het feit dat:
💡 Denk aan de eenheidscirkel: geeft de hoek in het eerste kwadrant, en de spiegeling in de x-as naar het vierde kwadrant.
- Gebruik periodiciteit om alle oplossingen te noteren:
waarbij (dus: )
Opvallende overeenkomst¶
Bij beide vergelijkingen gebruik je steeds dezelfde stappen:
- Stap 1: trek of
- Stap 2: gebruik symmetrie — bij sinus: , bij cosinus:
- Stap 3: voeg toe om alle oplossingen te vinden
6. Wiskunde als gereedschap voor natuurkunde¶
Goniometrie, ook wel bekend als de studie van hoeken en cirkelfuncties (zoals sinus en cosinus), dient als handig gereedschap voor natuurkunde. In dit hoofdstuk koppelen we de wiskundige concepten van de goniometrie aan natuurkundige toepassingen, met name binnen het subdomein B1: Informatieoverdracht. We laten zien hoe sinus- en cosinusfuncties de basis vormen voor het beschrijven van trillingen en golven, en hoe dit inzicht ons helpt bij het begrijpen van onder andere geluid, muziek en radiotechnologie.
6.1 De harmonische trilling¶
Een harmonische trilling is een beweging waarbij de uitwijking van een punt uit evenwicht beschreven wordt door een sinus- of cosinusfunctie. De mate van maximale afwijking noemen we de amplitude , het startpunt noemen we de fase . De tijd waarin de beweging op en neer gaat noemen we de periode , en hoe vaak die beweging per seconde plaatsvindt, is de frequentie :
Met:
Grootheid | Symbool | Eenheid |
---|---|---|
Frequentie | Hz | |
Periode | s | |
Uitwijking | m | |
Tijdstip | s | |
Amplitude | m | |
Fase | - |
Een klassiek voorbeeld van een harmonische trilling is het massa-veersysteem. De eigenfrequentie van dit systeem wordt bepaald door de massa en de stugheid (veerconstante ) van de veer:
Source
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.animation import FuncAnimation
from IPython.display import HTML, display
from ipywidgets import FloatSlider, VBox, interactive_output
# Constantes
A = 0.5
t_max = 10
fps = 60
y_plafond = 2.0
y_eq = 1.0
block_height = 0.4
zigzag_segments = 20
def create_zigzag(y_top, y_bottom, width=0.05, segments=20):
ys = np.linspace(y_top, y_bottom, segments + 1)
xs = [width if i % 2 == 0 else -width for i in range(segments + 1)]
xs[0] = xs[-1] = 0
return xs, ys
def animate_system(m=1.0, C=8.0):
omega = np.sqrt(C / m)
T = 2 * np.pi / omega
t_vals = np.linspace(0, t_max, int(t_max * fps))
u_vals = A * np.cos(omega * t_vals)
fig, (ax_sys, ax_graph) = plt.subplots(1, 2, figsize=(13, 6))
fig.suptitle(f"Massa-veersysteem met m = {m:.2f} kg en C = {C:.2f} N/m", fontsize=14)
plt.subplots_adjust(bottom=0.25)
# Systeem
ax_sys.set_xlim(-1, 1)
ax_sys.set_ylim(-0.2, 2.4)
ax_sys.set_aspect('equal')
ax_sys.axis('off')
ax_sys.plot([-0.5, 0.5], [y_plafond, y_plafond], color='black', lw=3)
mass_rect = Rectangle((-0.2, y_eq - block_height / 2), 0.4, block_height, color='red')
ax_sys.add_patch(mass_rect)
zigzag_line, = ax_sys.plot([], [], color='black', lw=2)
# u(t)-grafiek
ax_graph.set_xlim(0, t_max)
ax_graph.set_ylim(-1.5, 1.5)
ax_graph.set_xlabel('tijd (s)')
ax_graph.set_ylabel('uitwijking u(t) (m)')
ax_graph.set_title('u(t) versus tijd')
ax_graph.grid(True)
line_u, = ax_graph.plot(t_vals, u_vals, label='u(t)')
dot_u, = ax_graph.plot([], [], 'ro')
ax_graph.legend()
def init():
dot_u.set_data([], [])
return mass_rect, zigzag_line, dot_u
def update(frame):
t = t_vals[frame]
u = u_vals[frame]
y_center = y_eq + u
y_mass_top = y_center - block_height / 2
mass_rect.set_y(y_mass_top)
zigzag_width = 0.03 + 0.1 * (u / A)
xs, ys = create_zigzag(y_plafond, y_center, width=zigzag_width, segments=zigzag_segments)
zigzag_line.set_data(xs, ys)
dot_u.set_data(t, u)
return mass_rect, zigzag_line, dot_u
ani = FuncAnimation(fig, update, frames=len(t_vals), init_func=init, interval=1000 / fps, blit=True)
plt.close(fig) # Voorkomt dubbele output in Jupyter
display(HTML(ani.to_jshtml()))
# Sliders
m_slider = FloatSlider(min=0.25, max=4.0, step=0.05, value=1.0, description='massa m (kg)')
C_slider = FloatSlider(min=5.0, max=10.0, step=0.1, value=8.0, description='veerconstante C (N/m)')
ui = VBox([m_slider, C_slider])
out = interactive_output(animate_system, {'m': m_slider, 'C': C_slider})
display(ui, out)
6.2 Lopende golven¶
Tot nu toe beschouwden we trillingen op één plek in de ruimte. Maar een golf kan zich ook verplaatsen. Neem bijvoorbeeld een transversale golf. Deze heeft een golflengte en verplaatst zich in de tijd. Zoals te zien is in de grafiek hieronder, verplaatst de golf zich sneller bij een hogere frequentie: de golflengte wordt in een kortere tijd afgelegd.
De golfsnelheid is dus het product van de golflengte en frequentie.
6.3 Staande golven¶
Een bijzonder type golf is de staande golf. Hierbij oscilleert de golf, maar het geheel beweegt niet door de ruimte. Een bekend voorbeeld zijn muziekinstrumenten zoals een snaar die aan beide uiteinden is ingeklemd.
Voor een snaar van lengte , die op beide uiteinden vastzit, geldt:
Waarbij het aantal buikgolven of modusnummer is. In de onderstaande interactieve visualisatie zie je links de eerste drie trillingsmodi ( t/m 3) van een snaar:
- Bij is een halve golflengte zichtbaar ()
- Bij een hele ()
- Bij anderhalf ()
Deze worden weergegeven als sinusvormige lijnen tussen twee vaste punten (de muren).
Rechts zie je een frequentiespectrum met staven voor elk . Met de slider kun je de lengte van de snaar aanpassen. Dit beïnvloedt:
- De golflengte:
- De frequentie:
Een grotere snaarlengte betekent een langere golflengte en dus een lagere frequentie . De staven in het spectrum bewegen dan naar links (lagere frequentie) bij toenemende lengte.