TEORİDEN UYGULAMAYA · PYTHON EŞLİKÇİSİ

Parabol

Prof. Dr. Zühal Küçükarslan Yüzbaşı · Prof. Dr. Bahadır Yüzbaşı

Bölüm 12 · v1.0 · Türkçe

Bu bölümün laboratuvarı, kitaptaki örnekleri yeniden üretmek ve sayısal sonuçları incelemek için hazırlanmıştır. Matematiksel tanımlar, ispatlar ve sorular kitapta yer alır.

Laboratuvarı indir (.py) Tam Python paketi (.zip)

Laboratuvar kodu

"""Bölüm 12: ideal parabolik reflektör ve yansıma laboratuvarı.

Model, bir antenin yalnız iki boyutlu parabol kesitini ve geometrik optik
yansımasını temsil eder. Dalga boyu, kırınım, kazanç, besleme örüntüsü,
yüzey hatası, malzeme ve yapısal deformasyon içermez.
"""

from __future__ import annotations

import numpy as np

from agbook import (
    canonical_array_sha256,
    focus_directrix_diagnostics,
    parabola_algebraic_residuals,
    parabola_frame_from_vertex_axis,
    parabola_points,
    parabola_reflection_diagnostics,
    parabola_tangent_line,
    parabolic_reflector_focal_length,
    rotation_matrix_2d,
)


def main() -> None:
    aperture_diameter_m = 8.0
    depth_m = 1.0
    focal_length_m = parabolic_reflector_focal_length(
        aperture_diameter_m,
        depth_m,
    )
    vertex_m = np.array([0.0, 0.0])
    axis = np.array([0.0, 1.0])
    frame = parabola_frame_from_vertex_axis(vertex_m, axis, focal_length_m)

    rim_parameter = aperture_diameter_m / (4.0 * focal_length_m)
    parameters = np.linspace(-rim_parameter, rim_parameter, 9)
    surface_points_m = parabola_points(
        frame.vertex,
        frame.axis_direction,
        frame.focal_length,
        parameters,
    )
    algebraic_residuals_m2 = parabola_algebraic_residuals(
        surface_points_m,
        frame.vertex,
        frame.axis_direction,
        frame.focal_length,
    )
    locus = focus_directrix_diagnostics(
        surface_points_m,
        frame.focus,
        frame.directrix,
        1.0,
        reference_scale=aperture_diameter_m,
    )
    reflection = parabola_reflection_diagnostics(
        frame.vertex,
        frame.axis_direction,
        frame.focal_length,
        parameters,
    )
    tangent_lines = np.vstack(
        [
            parabola_tangent_line(
                frame.vertex,
                frame.axis_direction,
                frame.focal_length,
                parameter,
            )
            for parameter in parameters
        ]
    )
    tangent_point_residuals_m = np.sum(
        tangent_lines[:, :2] * surface_points_m,
        axis=1,
    ) + tangent_lines[:, 2]

    rim_depths_m = surface_points_m[[0, -1], 1] - frame.vertex[1]
    rim_span_m = np.linalg.norm(surface_points_m[-1] - surface_points_m[0])
    np.testing.assert_allclose(rim_depths_m, depth_m, atol=1e-14)
    np.testing.assert_allclose(rim_span_m, aperture_diameter_m, atol=1e-14)
    np.testing.assert_allclose(algebraic_residuals_m2, 0.0, atol=2e-14)
    np.testing.assert_allclose(tangent_point_residuals_m, 0.0, atol=2e-14)
    assert locus.maximum_absolute_residual < 2e-14
    assert reflection.maximum_direction_error < 2e-14
    assert reflection.maximum_focus_line_residual < 2e-14

    rotation = rotation_matrix_2d(np.deg2rad(29.0))
    translation_m = np.array([12.0, -7.0])
    moved_vertex_m = rotation @ frame.vertex + translation_m
    moved_axis = rotation @ frame.axis_direction
    moved = parabola_reflection_diagnostics(
        moved_vertex_m,
        moved_axis,
        frame.focal_length,
        parameters,
    )
    expected_moved_points_m = surface_points_m @ rotation.T + translation_m
    np.testing.assert_allclose(moved.points, expected_moved_points_m, atol=3e-14)
    np.testing.assert_allclose(
        moved.reflected_directions,
        reflection.reflected_directions @ rotation.T,
        atol=3e-14,
    )

    focal_length_mm = parabolic_reflector_focal_length(
        1000.0 * aperture_diameter_m,
        1000.0 * depth_m,
    )
    np.testing.assert_allclose(focal_length_mm, 1000.0 * focal_length_m)

    signature_values = np.concatenate(
        [
            np.array(
                [
                    aperture_diameter_m,
                    depth_m,
                    focal_length_m,
                    rim_parameter,
                ]
            ),
            frame.vertex,
            frame.focus,
            frame.directrix,
            frame.axis_direction,
            parameters,
            surface_points_m.ravel(),
            tangent_lines.ravel(),
            reflection.reflected_directions.ravel(),
            rotation.ravel(),
            translation_m,
            moved.points.ravel(),
        ]
    )

    print("birim: m")
    print("model: sentetik_iki_boyutlu_ideal_parabolik_reflektor")
    print("elektromanyetik_tasarim_mi: False")
    print("aciklik_capi_m:", aperture_diameter_m)
    print("merkez_derinligi_m:", depth_m)
    print("odak_uzakligi_m:", focal_length_m)
    print("odak_orani_f_bolu_D:", focal_length_m / aperture_diameter_m)
    print("tepe_m:", frame.vertex)
    print("odak_m:", frame.focus)
    print("dogrultman:", frame.directrix)
    print("yuzey_noktasi_sayisi:", surface_points_m.shape[0])
    print("kenar_noktalari_m:", surface_points_m[[0, -1]])
    print(
        "en_buyuk_odak_dogrultman_artigi_m:",
        f"{locus.maximum_absolute_residual:.3e}",
    )
    print(
        "en_buyuk_cebirsel_artik_m2:",
        f"{np.max(np.abs(algebraic_residuals_m2)):.3e}",
    )
    print(
        "en_buyuk_teget_nokta_artigi_m:",
        f"{np.max(np.abs(tangent_point_residuals_m)):.3e}",
    )
    print(
        "en_buyuk_yansima_yon_hatasi:",
        f"{reflection.maximum_direction_error:.3e}",
    )
    print(
        "en_buyuk_odak_cizgisi_artigi_m:",
        f"{reflection.maximum_focus_line_residual:.3e}",
    )
    print("rijit_noktalar_korundu_mu:", bool(np.allclose(moved.points, expected_moved_points_m)))
    print("mm_olceginde_odak_uzakligi:", focal_length_mm)
    print("bilimsel_imza:", canonical_array_sha256(signature_values))


if __name__ == "__main__":
    main()
Doğrulama çalıştırmasının çıktısı
birim: m
model: sentetik_iki_boyutlu_ideal_parabolik_reflektor
elektromanyetik_tasarim_mi: False
aciklik_capi_m: 8.0
merkez_derinligi_m: 1.0
odak_uzakligi_m: 4.0
odak_orani_f_bolu_D: 0.5
tepe_m: [0. 0.]
odak_m: [0. 4.]
dogrultman: [0. 1. 4.]
yuzey_noktasi_sayisi: 9
kenar_noktalari_m: [[ 4.  1.]
 [-4.  1.]]
en_buyuk_odak_dogrultman_artigi_m: 0.000e+00
en_buyuk_cebirsel_artik_m2: 0.000e+00
en_buyuk_teget_nokta_artigi_m: 0.000e+00
en_buyuk_yansima_yon_hatasi: 3.342e-16
en_buyuk_odak_cizgisi_artigi_m: 4.441e-16
rijit_noktalar_korundu_mu: True
mm_olceginde_odak_uzakligi: 4000.0
bilimsel_imza: 6fe49633baeb48261e4e1a8bc440dc24aaa9f5f818b0bc8e42f1b81799a0b27b
Metindeki Python kodları

Kod dosyasını indir

# Kitaptaki kod blokları; bu dosya içinde sırayla çalıştırılır.
# --- 1. Bölüm 12: reflektör çerçevesi ve yüzey noktaları ---
import numpy as np
from agbook import (
    focus_directrix_diagnostics,
    parabola_frame_from_vertex_axis,
    parabola_points,
    parabola_reflection_diagnostics,
    parabolic_reflector_focal_length,
)

D, d = 8.0, 1.0  # metre
f = parabolic_reflector_focal_length(D, d)
frame = parabola_frame_from_vertex_axis([0., 0.], [0., 1.], f)
t_rim = D / (4.0 * f)
t = np.linspace(-t_rim, t_rim, 9)
points = parabola_points(frame.vertex, frame.axis_direction, f, t)
locus = focus_directrix_diagnostics(
    points, frame.focus, frame.directrix, 1.0, reference_scale=D
)
reflection = parabola_reflection_diagnostics(
    frame.vertex, frame.axis_direction, f, t
)
print(f, frame.focus, points[[0, -1]])
print(locus.maximum_absolute_residual)
print(reflection.maximum_direction_error)

# --- 2. Bölüm 12 laboratuvarı: teğet ve rijit değişmezlik ---
from agbook import parabola_tangent_line, rotation_matrix_2d

tangents = np.vstack([
    parabola_tangent_line(frame.vertex, frame.axis_direction, f, value)
    for value in t
])
tangent_residuals = np.sum(tangents[:, :2] * points, axis=1) + tangents[:, 2]

Q = rotation_matrix_2d(np.deg2rad(29.0))
b = np.array([12.0, -7.0])  # metre
moved = parabola_reflection_diagnostics(Q @ frame.vertex + b, Q @ frame.axis_direction, f, t)
expected_points = points @ Q.T + b
print(np.max(np.abs(tangent_residuals)))
print(np.max(np.abs(moved.points - expected_points)))
print(np.max(np.abs(moved.reflected_directions - reflection.reflected_directions @ Q.T)))

Kaydedilen çıktı

1. Bölüm 12: reflektör çerçevesi ve yüzey noktaları
4.0 [0. 4.] [[ 4.  1.]
 [-4.  1.]]
0.0
3.3422138886441676e-16

2. Bölüm 12 laboratuvarı: teğet ve rijit değişmezlik
0.0
1.7763568394002505e-15
6.661338147750939e-16
Çözümlerdeki Python kodları

Kod dosyasını indir

# Kitaptaki kod blokları; bu dosya içinde sırayla çalıştırılır.
# --- 1. Doğrultman ölçeği ve dejenere durum ---
import numpy as np
from agbook import parabola_frame_from_focus_directrix

focus = np.array([2., 1.])
lines = ([1., 0., 2.], [7., 0., 14.], [-3., 0., -6.])
frames = [parabola_frame_from_focus_directrix(focus, line)
          for line in lines]
for frame in frames:
    print(frame.vertex, frame.axis_direction, frame.focal_length)

assert all(np.allclose(frame.vertex, [0., 1.]) for frame in frames)
assert all(np.allclose(frame.axis_direction, [1., 0.]) for frame in frames)
assert all(np.isclose(frame.focal_length, 2.) for frame in frames)

try:
    parabola_frame_from_focus_directrix([0., 1.], [1., 0., 0.])
except ValueError as error:
    print(type(error).__name__, str(error))

# --- 2. Parabol noktaları ve teğet artıkları ---
import numpy as np
from agbook import (
    parabola_algebraic_residuals, parabola_points, parabola_tangent_line,
)

t = np.array([-2., -1., 0., 1., 2.])
points = parabola_points([0., 0.], [1., 0.], 2., t)
membership = parabola_algebraic_residuals(
    points, [0., 0.], [1., 0.], 2.
)
lines = np.vstack([
    parabola_tangent_line([0., 0.], [1., 0.], 2., value)
    for value in t
])
tangent = np.sum(lines[:, :2] * points, axis=1) + lines[:, 2]
print(points)
print(np.max(np.abs(membership)))
print(np.max(np.abs(tangent)))

# --- 3. Yansımanın rijit hareket altında denetimi ---
import numpy as np
from agbook import parabola_reflection_diagnostics, rotation_matrix_2d

t = np.linspace(-2., 2., 17)
before = parabola_reflection_diagnostics([0., 0.], [1., 0.], 3., t)
Q = rotation_matrix_2d(np.deg2rad(37.))
b = np.array([5., -3.])
after = parabola_reflection_diagnostics(b, Q @ np.array([1., 0.]), 3., t)

point_error = np.max(np.abs(after.points - (before.points @ Q.T + b)))
direction_error = np.max(np.abs(
    after.reflected_directions - before.reflected_directions @ Q.T
))
print(before.maximum_direction_error, point_error, direction_error)
assert before.maximum_direction_error < 2e-14
assert point_error < 3e-14
assert direction_error < 3e-14

# --- 4. Metre--milimetre ölçek denetimi ---
import numpy as np
from agbook import parabolic_reflector_focal_length

D_m, d_m = 8., 1.
f_m = parabolic_reflector_focal_length(D_m, d_m)
D_mm, d_mm = 1000. * D_m, 1000. * d_m
f_mm = parabolic_reflector_focal_length(D_mm, d_mm)

print(f_m, f_mm, f_m / D_m, f_mm / D_mm)
assert np.isclose(f_mm, 1000. * f_m)
assert np.isclose(f_m / D_m, f_mm / D_mm)

Kaydedilen çıktı

1. Doğrultman ölçeği ve dejenere durum
[0. 1.] [1. 0.] 2.0
[0. 1.] [1. 0.] 2.0
[0. 1.] [1. 0.] 2.0
ValueError Odak doğrultman üzerinde veya eşiğe çok yakındır.

2. Parabol noktaları ve teğet artıkları
[[ 8. -8.]
 [ 2. -4.]
 [ 0.  0.]
 [ 2.  4.]
 [ 8.  8.]]
0.0
0.0

3. Yansımanın rijit hareket altında denetimi
3.1401849173675503e-16 3.552713678800501e-15 6.661338147750939e-16

4. Metre--milimetre ölçek denetimi
4.0 4000.0 0.5 0.5

Çalıştırma rehberi

Önce tam Python paketini indirin ve arşivi açın. Aşağıdaki komutları arşivin üst klasöründen başlatın. İlk kurulum internet bağlantısı ve Python 3.12 veya 3.13 gerektirir. Bağımlılıklar sabittir; sistem Python'unu değiştirmemek için ayrı sanal ortam kullanılır.

macOS / Linux
cd analitik-geometri-python-v1.0
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"
python labs/bolum_12_parabol_yansima.py
python -m pytest
Windows PowerShell
cd analitik-geometri-python-v1.0
py -3.13 -m venv .venv
.venv\Scripts\python.exe -m pip install -e ".[dev]"
.venv\Scripts\python.exe labs/bolum_12_parabol_yansima.py
.venv\Scripts\python.exe -m pytest

Laboratuvar dosyaları agbook yardımcı paketini kullanır; tek bir dosyayı indirmek paketi kurmanın yerini tutmaz. Metin/çözüm kodları kendi dosyaları içinde sırayla çalıştırılır; gizli bir notebook oturumu gerekmez. Son ondalık basamaklar platforma göre değişebilir.