Topik ini membahas teorema Pythagoras pada segitiga siku-siku beserta turunannya, yaitu perhitungan sisi miring, jarak Euclidean antar dua titik, dan identitas trigonometri dasar. Setiap rumus diverifikasi dengan NumPy agar kecocokannya terlihat dalam angka, bukan sekadar pada tulisannya. Setelah topik ini selesai dibaca, jarak antar titik dan identitas trigonometri dapat diturunkan dari satu teorema yang sama serta dihitung dengan tepat dalam kode.
Teorema Pythagoras#
Segitiga siku-siku memiliki satu sudut , dan teorema Pythagoras menghubungkan ketiga sisinya. Sisi yang menghadap sudut siku-siku disebut hipotenusa, yaitu sisi terpanjang pada segitiga tersebut. Teorema menyatakan bahwa kuadrat hipotenusa sama dengan jumlah kuadrat kedua sisi lainnya.
Dengan menyatakan hipotenusa, rumus tersebut menghitung sisi mana pun apabila dua sisi lainnya diketahui. Teorema ini hanya berlaku pada segitiga yang salah satu sudutnya tepat , sehingga keberadaan sudut siku-sikunya wajib dipastikan sebelum rumusnya digunakan. Skrip berikut menggambar contoh segitiga siku-siku dengan sisi 3, 4, dan 5.
import numpy as np
import matplotlib
matplotlib.use("Agg") # backend tanpa jendela, cocok untuk menyimpan berkas
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(5, 3.5))
ax.set_aspect("equal")
a, b = 3.0, 4.0
# segitiga siku-siku: sisi tegak a, sisi datar b, sisi miring c
ax.plot([0, 0], [0, a], color="#1f77b4", linewidth=2.2)
ax.plot([0, b], [0, 0], color="#2ca02c", linewidth=2.2)
ax.plot([0, b], [a, 0], color="#d62728", linewidth=2.2)
# penanda sudut siku-siku di titik asal
ax.plot([0, 0.35, 0.35], [0.35, 0.35, 0], color="#666666", linewidth=1.2)
# label sisi
ax.text(-0.22, a / 2, "a = 3", color="#1f77b4", fontsize=13, ha="right", va="center")
ax.text(b / 2, -0.26, "b = 4", color="#2ca02c", fontsize=13, ha="center", va="top")
miring = np.rad2deg(np.arctan2(a, b))
ax.text(2.25, 1.85, "c = 5", color="#d62728", fontsize=13, ha="center",
rotation=miring, rotation_mode="anchor")
ax.set_xlim(-1.1, 4.8)
ax.set_ylim(-0.9, 3.7)
ax.axis("off")
plt.tight_layout()
plt.savefig("segitiga-pythagoras.svg")Pasangan , , adalah contoh klasik karena yang akarnya tepat . Nilai sisi miring berupa bilangan bulat seperti ini jarang terjadi, misalnya menghasilkan yang merupakan bilangan irasional. Perhitungan pada praktiknya oleh karena itu hampir selalu dilakukan dalam kode, dan itulah yang dibahas pada bagian berikutnya.
Menghitung sisi miring dengan NumPy#
NumPy menyediakan np.hypot untuk menghitung secara langsung. Skrip berikut menghitung sisi miring untuk tiga pasang sisi, lalu memeriksa teorema dari arah sebaliknya, yaitu menghitung sisa yang seharusnya nol. Sisa bernilai nol berarti persamaannya terpenuhi.
import numpy as np
contoh = [(3.0, 4.0), (5.0, 12.0), (1.0, 1.0)]
for a, b in contoh:
c = np.hypot(a, b)
print(f"a = {a:4.1f}, b = {b:4.1f} -> c = {c:.4f}")
# persamaan diperiksa dari sisanya: a² + b² - c² harus 0
a, b = 5.0, 12.0
c = np.hypot(a, b)
print(f"sisa a² + b² - c² = {a ** 2 + b ** 2 - c ** 2:.2e}")a = 3.0, b = 4.0 -> c = 5.0000
a = 5.0, b = 12.0 -> c = 13.0000
a = 1.0, b = 1.0 -> c = 1.4142
sisa a² + b² - c² = 0.00e+00Dua pasangan pertama menghasilkan sisi miring bulat, sedangkan pasangan ketiga menghasilkan yang tercetak . Sisa perhitungan menegaskan bahwa persamaan terpenuhi hingga presisi float pada pasangan yang diuji. Pemeriksaan dari arah sisa semacam ini lebih aman daripada menguji kesamaan panjang sisi secara langsung, karena hasil pembulatan yang kecil tidak membuat pemeriksaannya gagal.
Demo berikut menghitung sisi miring untuk dua sisi yang dapat digeser. Gerakkan salah satu penggesernya, lalu bandingkan nilai jumlah kuadrat kedua sisi dengan panjang sisi miring yang tercetak di bawah kanvas. Kedua sisi dapat diatur dari 1 sampai 8 dengan langkah setengah satuan.
Kode sumber demo
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<title>Demo teorema Pythagoras</title>
<style>
body { font-family: sans-serif; margin: 0; padding: 10px; color: #222; }
canvas { background: #fafafa; border: 1px solid #ddd; max-width: 100%; }
.baris { margin-top: 6px; font-size: 14px; }
.nilai { font-weight: bold; }
</style>
</head>
<body>
<canvas id="kanvas" width="560" height="280"></canvas>
<div class="baris">
<label for="sisiA">Sisi a: <span id="teksA">3</span> Sisi b: <span id="teksB">4</span></label>
<input type="range" id="sisiA" min="1" max="8" step="0.5" value="3" style="width: 48%">
<input type="range" id="sisiB" min="1" max="8" step="0.5" value="4" style="width: 48%">
</div>
<div class="baris">a² + b² = <span class="nilai" id="nilaiKuadrat"></span> → c = √(a² + b²) = <span class="nilai" id="nilaiC"></span></div>
<script>
const kanvas = document.getElementById('kanvas');
const ctx = kanvas.getContext('2d');
const sliderA = document.getElementById('sisiA');
const sliderB = document.getElementById('sisiB');
const skala = 26; // piksel per satuan panjang
function gambar() {
const a = Number(sliderA.value);
const b = Number(sliderB.value);
ctx.clearRect(0, 0, kanvas.width, kanvas.height);
// titik sudut segitiga; sumbu y kanvas ke bawah sehingga sisi a digambar ke atas
const x0 = 60, y0 = 240;
const atasY = y0 - a * skala;
const kananX = x0 + b * skala;
ctx.lineWidth = 2.2;
ctx.strokeStyle = '#1f77b4'; // sisi a yang tegak
ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(x0, atasY); ctx.stroke();
ctx.strokeStyle = '#2ca02c'; // sisi b yang datar
ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(kananX, y0); ctx.stroke();
ctx.strokeStyle = '#d62728'; // sisi miring c
ctx.beginPath(); ctx.moveTo(x0, atasY); ctx.lineTo(kananX, y0); ctx.stroke();
// penanda sudut siku-siku
ctx.strokeStyle = '#666666';
ctx.lineWidth = 1.2;
ctx.strokeRect(x0, y0 - 9, 9, 9);
// label nilai sisi
ctx.fillStyle = '#1f77b4';
ctx.fillText('a = ' + a, x0 - 48, y0 - a * skala / 2);
ctx.fillStyle = '#2ca02c';
ctx.fillText('b = ' + b, x0 + b * skala / 2 - 16, y0 + 16);
ctx.fillStyle = '#d62728';
ctx.fillText('c', x0 + b * skala / 2 + 12, y0 - a * skala / 2 - 6);
const c = Math.sqrt(a * a + b * b);
document.getElementById('teksA').textContent = String(a);
document.getElementById('teksB').textContent = String(b);
document.getElementById('nilaiKuadrat').textContent = (a * a + b * b).toFixed(2);
document.getElementById('nilaiC').textContent = c.toFixed(4);
}
sliderA.addEventListener('input', gambar);
sliderB.addEventListener('input', gambar);
gambar();
</script>
</body>
</html>Pada kode sumbernya, sisi miring dihitung dengan Math.sqrt(a * a + b * b) yang persis merupakan bentuk teoremanya. Penanda sudut siku-siku pada kanvas dibentuk oleh strokeRect, dan kedua nilai pada baris terakhir diperbarui setiap kali penggeser bergerak. Nilai jumlah kuadrat kedua sisi ditampilkan di samping nilai sisi miringnya, sehingga hubungan kedua angka itu terlihat berdampingan.
Jarak Euclidean antar dua titik#
Jarak terpendek antar dua titik pada bidang adalah sisi miring dari segitiga siku-siku yang kakinya berupa selisih koordinat. Kaki segitiganya berupa jarak horizontal dan jarak vertikal antar kedua titik tersebut. Untuk titik dan , jaraknya dinyatakan sebagai berikut.
Rumus yang sama tetap berlaku pada dimensi berapa pun dengan menambahkan suku kuadrat untuk setiap selisih koordinat, dan bentuk dimensi inilah yang disebut jarak Euclidean. Machine learning menggunakan jarak ini untuk mengukur kemiripan antar dua vektor data, misalnya mencari catatan lama yang paling dekat dengan catatan baru. Skrip berikut menghitung jarak antar dua catatan sensor yang masing-masing memuat suhu dan kelembapan.
import numpy as np
u = np.array([24.5, 61.0]) # catatan sensor: suhu (°C) dan kelembapan (%)
v = np.array([26.0, 58.0]) # catatan sensor pada pengukuran berikutnya
selisih = v - u
jarak_norm = np.linalg.norm(selisih)
jarak_manual = np.sqrt(np.sum(selisih ** 2))
print(f"selisih : {selisih}")
print(f"norm : {jarak_norm:.4f}")
print(f"hitung manual: {jarak_manual:.4f}")selisih : [ 1.5 -3. ]
norm : 3.3541
hitung manual: 3.3541Selisih koordinatnya adalah , sehingga jaraknya . Dua cara perhitungan pada skrip, yaitu np.linalg.norm dan penjumlahan kuadrat secara manual, menghasilkan angka yang sama. Fungsi np.linalg.norm lebih disukai karena bekerja untuk vektor dengan dimensi berapa pun tanpa mengubah bentuk kodenya.
Identitas trigonometri dari Pythagoras#
Lingkaran satuan memberikan jembatan antara teorema Pythagoras dan trigonometri. Pada titik , jari-jari menuju titik tersebut adalah hipotenusa berpanjang satu, sedangkan kedua koordinatnya adalah sisi tegak dan sisi datar segitiganya. Teorema Pythagoras yang diterapkan pada segitiga kecil itu menghasilkan identitas berikut.
Identitas kedua muncul setelah tangen didefinisikan sebagai . Membagi setiap suku identitas pertama dengan menghasilkan hubungan berikut. Kedua identitas itu berlaku pada sudut mana pun yang -nya tidak nol.
Skrip berikut memeriksa ketiga hubungan itu pada sejuta titik yang rapat, dengan mencetak sisa terbesar untuk masing-masing. Urutan baris keluarannya mengikuti urutan identitas di atas, sehingga perbandingannya mudah dibaca. Jalankan skripnya, kemudian perhatikan ordo setiap barisnya.
import numpy as np
t = np.linspace(0.0, 2 * np.pi, 1000001)
# identitas Pythagoras: sin²θ + cos²θ = 1
sisa_1 = np.max(np.abs(np.sin(t) ** 2 + np.cos(t) ** 2 - 1.0))
print(f"maks |sin²θ + cos²θ - 1| = {sisa_1:.2e}")
# definisi tangen, diperiksa hanya pada sudut yang cos θ-nya cukup jauh dari nol
aman = np.abs(np.cos(t)) > 1e-3
sisa_2 = np.max(np.abs(np.sin(t[aman]) / np.cos(t[aman]) - np.tan(t[aman])))
print(f"maks |sin θ/cos θ - tan θ| = {sisa_2:.2e}")
# identitas turunannya: 1 + tan²θ = 1/cos²θ
sisa_3 = np.max(np.abs(1.0 + np.tan(t[aman]) ** 2 - 1.0 / np.cos(t[aman]) ** 2))
print(f"maks |1 + tan²θ - 1/cos²θ| = {sisa_3:.2e}")maks |sin²θ + cos²θ - 1| = 2.22e-16
maks |sin θ/cos θ - tan θ| = 2.27e-13
maks |1 + tan²θ - 1/cos²θ| = 2.33e-10Ketiga sisa berada jauh di bawah ambang yang bermakna, tetapi besarannya naik dari baris pertama ke baris ketiga. Penyebabnya terletak pada sudut yang mendekati , tempat mendekati nol sehingga dan membesar tajam. Pembagian dengan nilai yang mendekati nol memperbesar hampiran yang sudah tersimpan, dan itulah yang terlihat pada ordo hingga . Baris pemeriksaan tangen pada skrip juga melewatkan titik-titik yang -nya terlalu dekat dengan nol agar pembagiannya tetap terdefinisi.
Di mana hal ini ditemui dalam kode#
Jarak Euclidean termasuk besaran yang paling sering dihitung pada kode machine learning, misalnya untuk mencari data latih yang paling mirip dengan data baru atau mengelompokkan data yang saling dekat. Fungsi np.linalg.norm menghitungnya untuk vektor dengan dimensi berapa pun, sedangkan identitas Pythagoras digunakan saat menormalisasi vektor agar panjangnya satu. Contoh berikut menggunakan identitas tersebut untuk menyusun empat titik yang berjarak sama pada lingkaran.
import numpy as np
t = np.linspace(0.0, 2 * np.pi, 4, endpoint=False)
titik = np.column_stack([np.cos(t), np.sin(t)])
print(titik)
print(np.sum(titik ** 2, axis=1))[[ 1.0000000e+00 0.0000000e+00]
[ 6.1232340e-17 1.0000000e+00]
[-1.0000000e+00 1.2246468e-16]
[-1.8369702e-16 -1.0000000e+00]]
[1. 1. 1. 1.]Baris kedua keluaran menunjukkan bahwa jumlah kuadrat kedua koordinat bernilai satu untuk keempat titik, persis seperti identitasnya. Nilai berordo pada beberapa koordinat adalah hampiran nol yang tersisa dari np.cos dan np.sin. Pola ini digunakan pada grafika untuk menyusun titik berjarak sama pada lingkaran, sedangkan pada machine learning pola yang sama muncul ketika vektor dinormalisasi sebelum dibandingkan.
Ringkasan#
- Teorema menghubungkan ketiga sisi segitiga siku-siku dan dihitung secara stabil melalui
np.hypot. - Jarak Euclidean merupakan penerapan teorema yang sama pada selisih koordinat, dan
np.linalg.normmenghitungnya untuk vektor dimensi berapa pun. - Identitas adalah teorema Pythagoras pada lingkaran satuan, sedangkan diperoleh dari pembagian identitas pertama dengan .
- Sisa verifikasi numerik berordo hingga berasal dari aritmetika float, dan membesar apabila perhitungan membagi nilai yang mendekati nol.
Referensi#
- numpy.hypot — NumPy Developers — Dokumentasi fungsi penghitung sisi miring yang aman terhadap peluapan nilai antara.
- numpy.linalg.norm — NumPy Developers — Dokumentasi fungsi norma yang digunakan untuk jarak Euclidean pada vektor.
- Mathematics for Machine Learning — Deisenroth, Faisal, and Ong — Buku terbuka yang membahas norma dan jarak Euclidean pada bagian aljabar linier untuk machine learning.
- Algebra and Trigonometry 1e — OpenStax — Buku teks terbuka yang menurunkan identitas trigonometri dari teorema Pythagoras.