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

Küre ve Küre Sistemleri

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

Bölüm 20 · 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 20: küre ve küre sistemleri laboratuvarı.

Uygulama, dört bilinen merkeze olan tam ve gürültüsüz uzaklıklardan sentetik
bir uzay noktasını bulur. İlk üç küre ayna simetrili iki aday bırakır; dördüncü
küre rankı tamamlayıp tek ortak noktayı seçer. Bu dosya GNSS, fiziksel ölçüm
belirsizliği veya kabul kararı modeli değildir.
"""

from __future__ import annotations

import numpy as np

from agbook import (
    canonical_array_sha256,
    radical_plane_diagnostics,
    sphere_plane_section_diagnostics,
    sphere_point_power,
    sphere_sphere_intersection_diagnostics,
    sphere_system_diagnostics,
    tangent_plane_at_sphere_point,
)


def main() -> None:
    length_unit = "m"
    rank_tolerance = 1.0e-12
    absolute_tolerance_m = 1.0e-11
    relative_tolerance = 1.0e-12
    reference_scale_m = 20.0
    system_options = {
        "rank_tolerance": rank_tolerance,
        "absolute_tolerance": absolute_tolerance_m,
        "relative_tolerance": relative_tolerance,
        "reference_scale": reference_scale_m,
    }
    geometry_options = {
        "absolute_tolerance": absolute_tolerance_m,
        "relative_tolerance": relative_tolerance,
        "reference_scale": reference_scale_m,
    }

    target = np.array([4.0, 6.0, 12.0])
    centers = np.array(
        [
            [0.0, 0.0, 0.0],
            [12.0, 0.0, 0.0],
            [0.0, 16.0, 0.0],
            [0.0, 0.0, 20.0],
        ]
    )
    squared_ranges = np.array([196.0, 244.0, 260.0, 116.0])
    ranges = np.sqrt(squared_ranges)

    three_sphere = sphere_system_diagnostics(
        centers[:3],
        ranges[:3],
        **system_options,
    )
    four_sphere = sphere_system_diagnostics(
        centers,
        ranges,
        **system_options,
    )
    first_pair = sphere_sphere_intersection_diagnostics(
        centers[0],
        ranges[0],
        centers[1],
        ranges[1],
        **geometry_options,
    )
    first_radical_plane = radical_plane_diagnostics(
        centers[0],
        ranges[0],
        centers[1],
        ranges[1],
        **geometry_options,
    )
    horizontal_section = sphere_plane_section_diagnostics(
        centers[0],
        ranges[0],
        [0.0, 0.0, 1.0, -12.0],
        **geometry_options,
    )
    tangent_plane = tangent_plane_at_sphere_point(
        centers[0],
        ranges[0],
        target,
        **geometry_options,
    )

    rotation = np.array(
        [
            [0.0, -1.0, 0.0],
            [1.0, 0.0, 0.0],
            [0.0, 0.0, 1.0],
        ]
    )
    translation = np.array([30.0, -10.0, 7.0])
    moved_centers = centers @ rotation.T + translation
    moved_target = rotation @ target + translation
    moved = sphere_system_diagnostics(
        moved_centers,
        ranges,
        rank_tolerance=rank_tolerance,
        absolute_tolerance=absolute_tolerance_m,
        relative_tolerance=relative_tolerance,
        reference_scale=60.0,
    )

    centimetre_scale = 100.0
    centimetre = sphere_system_diagnostics(
        centimetre_scale * centers,
        centimetre_scale * ranges,
        rank_tolerance=rank_tolerance,
        absolute_tolerance=centimetre_scale * absolute_tolerance_m,
        relative_tolerance=relative_tolerance,
        reference_scale=centimetre_scale * reference_scale_m,
    )

    target_powers = np.array(
        [
            sphere_point_power(centers[index], ranges[index], target)
            for index in range(centers.shape[0])
        ]
    )

    assert three_sphere.relation == "line"
    assert three_sphere.rank == 2
    assert three_sphere.common_locus_type == "two_points"
    np.testing.assert_allclose(three_sphere.anchor, [4.0, 6.0, 0.0], atol=2.0e-13)
    np.testing.assert_allclose(
        three_sphere.common_points,
        [[4.0, 6.0, -12.0], [4.0, 6.0, 12.0]],
        atol=2.0e-12,
    )
    assert four_sphere.relation == "point"
    assert four_sphere.rank == 3
    assert four_sphere.common_locus_type == "point"
    np.testing.assert_allclose(four_sphere.anchor, target, atol=2.0e-13)
    np.testing.assert_allclose(target_powers, 0.0, atol=1.0e-13)
    np.testing.assert_allclose(four_sphere.power_values, 0.0, atol=2.0e-12)
    assert first_pair.relation == "intersection_circle"
    assert first_radical_plane.relation == "plane"
    np.testing.assert_allclose(
        first_pair.circle_plane,
        first_radical_plane.plane_coefficients,
        atol=2.0e-15,
    )
    assert horizontal_section.relation == "circle"
    np.testing.assert_allclose(horizontal_section.section_center, [0.0, 0.0, 12.0])
    np.testing.assert_allclose(horizontal_section.section_radius, np.sqrt(52.0))
    np.testing.assert_allclose(tangent_plane[:3], target / ranges[0], atol=2.0e-15)
    np.testing.assert_allclose(
        tangent_plane[:3] @ target + tangent_plane[3],
        0.0,
        atol=3.0e-15,
    )
    np.testing.assert_allclose(moved.anchor, moved_target, atol=3.0e-13)
    np.testing.assert_allclose(
        centimetre.anchor,
        centimetre_scale * target,
        atol=3.0e-11,
    )
    assert centimetre.relation == four_sphere.relation
    np.testing.assert_allclose(
        centimetre.condition_number,
        four_sphere.condition_number,
        rtol=2.0e-15,
    )

    signature_values = np.concatenate(
        [
            target,
            centers.ravel(),
            squared_ranges,
            ranges,
            three_sphere.anchor,
            three_sphere.direction_basis.ravel(),
            three_sphere.common_points.ravel(),
            four_sphere.anchor,
            four_sphere.singular_values,
            four_sphere.equation_residuals,
            four_sphere.power_values,
            first_pair.circle_center,
            np.array([first_pair.circle_radius]),
            first_radical_plane.plane_coefficients,
            horizontal_section.section_center,
            np.array([horizontal_section.section_radius]),
            tangent_plane,
            moved.anchor,
            centimetre.anchor,
            np.array(
                [
                    four_sphere.condition_number,
                    four_sphere.length_threshold,
                    four_sphere.power_threshold,
                    rank_tolerance,
                    absolute_tolerance_m,
                    relative_tolerance,
                    reference_scale_m,
                ]
            ),
        ]
    )

    print("uzunluk_birimi:", length_unit)
    print("model: sentetik_gurultusuz_mesafe_kureleriyle_konumlama")
    print("gercek_gnss_modeli_mi: False")
    print("olculmus_veri_mi: False")
    print("olcum_belirsizligi_hesabi_mi: False")
    print("hedef_nokta_m:", target)
    print("uzakliklar_m:", ranges)
    print("ilk_uc_kure_ranki:", three_sphere.rank)
    print("ilk_uc_kure_esit_guc_yeri:", three_sphere.relation)
    print("ilk_uc_kure_ortak_yeri:", three_sphere.common_locus_type)
    print("ayna_adaylari_m:", three_sphere.common_points)
    print("dort_kure_ranki:", four_sphere.rank)
    print("dort_kure_esit_guc_yeri:", four_sphere.relation)
    print("dort_kure_ortak_yeri:", four_sphere.common_locus_type)
    print("cozum_m:", four_sphere.anchor)
    print("guc_degerleri_m2:", four_sphere.power_values)
    print("guc_yayilimi_m2:", f"{four_sphere.power_spread:.12e}")
    print("kosul_sayisi:", f"{four_sphere.condition_number:.12f}")
    print("birinci_ikili_kesisim:", first_pair.relation)
    print("birinci_radikal_duzlem:", first_radical_plane.plane_coefficients)
    print("z_12_kesit_yaricapi_m:", f"{horizontal_section.section_radius:.12f}")
    print("hedefte_teget_duzlem:", tangent_plane)
    print("rijit_harekette_cozum_korundu_mu:", np.allclose(moved.anchor, moved_target))
    print(
        "metreden_santimetreye_cozum_orani:",
        centimetre.anchor / four_sphere.anchor,
    )
    print("rank_esigi:", f"{rank_tolerance:.12e}")
    print("mutlak_uzunluk_esigi_m:", f"{absolute_tolerance_m:.12e}")
    print("bagil_uzunluk_esigi:", f"{relative_tolerance:.12e}")
    print("referans_uzunlugu_m:", f"{reference_scale_m:.12f}")
    print("bilimsel_imza:", canonical_array_sha256(signature_values))


if __name__ == "__main__":
    main()
Doğrulama çalıştırmasının çıktısı
uzunluk_birimi: m
model: sentetik_gurultusuz_mesafe_kureleriyle_konumlama
gercek_gnss_modeli_mi: False
olculmus_veri_mi: False
olcum_belirsizligi_hesabi_mi: False
hedef_nokta_m: [ 4.  6. 12.]
uzakliklar_m: [14.         15.62049935 16.1245155  10.77032961]
ilk_uc_kure_ranki: 2
ilk_uc_kure_esit_guc_yeri: line
ilk_uc_kure_ortak_yeri: two_points
ayna_adaylari_m: [[  4.   6. -12.]
 [  4.   6.  12.]]
dort_kure_ranki: 3
dort_kure_esit_guc_yeri: point
dort_kure_ortak_yeri: point
cozum_m: [ 4.  6. 12.]
guc_degerleri_m2: [2.84217094e-14 2.84217094e-14 5.68434189e-14 4.26325641e-14]
guc_yayilimi_m2: 2.842170943040e-14
kosul_sayisi: 1.666666666667
birinci_ikili_kesisim: intersection_circle
birinci_radikal_duzlem: [ 1.  0.  0. -4.]
z_12_kesit_yaricapi_m: 7.211102550928
hedefte_teget_duzlem: [  0.28571429   0.42857143   0.85714286 -14.        ]
rijit_harekette_cozum_korundu_mu: True
metreden_santimetreye_cozum_orani: [100. 100. 100.]
rank_esigi: 1.000000000000e-12
mutlak_uzunluk_esigi_m: 1.000000000000e-11
bagil_uzunluk_esigi: 1.000000000000e-12
referans_uzunlugu_m: 20.000000000000
bilimsel_imza: 2f366b8c5b303a0ee1bb8f1170dfa3558292dec5690fc7e63c325b7254c85aa4
Metindeki Python kodları

Kod dosyasını indir

# Kitaptaki kod blokları; bu dosya içinde sırayla çalıştırılır.
# --- 1.  ---
import numpy as np
from agbook import sphere_system_diagnostics

centers = np.array([
    [0.0, 0.0, 0.0],
    [12.0, 0.0, 0.0],
    [0.0, 16.0, 0.0],
    [0.0, 0.0, 20.0],
])
radii = np.sqrt([196.0, 244.0, 260.0, 116.0])
options = dict(
    rank_tolerance=1e-12,
    absolute_tolerance=1e-11,
    relative_tolerance=1e-12,
    reference_scale=20.0,
)

three = sphere_system_diagnostics(centers[:3], radii[:3], **options)
four = sphere_system_diagnostics(centers, radii, **options)

assert three.relation == "line"
assert three.common_locus_type == "two_points"
np.testing.assert_allclose(
    three.common_points,
    [[4.0, 6.0, -12.0], [4.0, 6.0, 12.0]],
)
assert four.relation == "point"
assert four.common_locus_type == "point"
np.testing.assert_allclose(four.anchor, [4.0, 6.0, 12.0])
np.testing.assert_allclose(four.power_values, 0.0, atol=1e-12)

Kaydedilen çıktı

1. 
Çözümlerdeki Python kodları

Kod dosyasını indir

# Kitaptaki kod blokları; bu dosya içinde sırayla çalıştırılır.
# --- 1. Genel küre sınıflarının ve ölçek değişmezliğinin sınanması ---
import numpy as np
from agbook import general_sphere_diagnostics

cases = [
    ([1, 0, 0, 0, -4], "sphere"),
    ([1, 0, 0, 0,  0], "point"),
    ([1, 0, 0, 0,  1], "empty"),
]
for coefficients, expected in cases:
    base = general_sphere_diagnostics(coefficients)
    scaled = general_sphere_diagnostics(
        -7.0 * np.asarray(coefficients, dtype=float)
    )
    assert base.locus_type == expected
    assert scaled.locus_type == expected
    np.testing.assert_allclose(
        scaled.normalized_coefficients,
        base.normalized_coefficients,
    )

# --- 2. Doğru ve düzlem kesitlerinin artıklarla sınanması ---
import numpy as np
from agbook import (
    line_sphere_intersections_3d,
    sphere_plane_section_diagnostics,
)

opts = dict(
    absolute_tolerance=1e-12,
    relative_tolerance=1e-12,
    reference_scale=10.0,
)
line_cases = [
    (5.0, [0, 3, 0], "secant"),
    (5.0, [0, 5, 0], "tangent"),
    (5.0, [0, 6, 0], "disjoint"),
    (0.0, [0, 0, 0], "point"),
]
for radius, anchor, expected in line_cases:
    out = line_sphere_intersections_3d(
        [0, 0, 0], radius, anchor, [1, 0, 0], **opts
    )
    assert out.relation == expected
    np.testing.assert_allclose(out.line_residuals, 0, atol=1e-12)
    if expected in {"secant", "point"}:
        np.testing.assert_allclose(out.radial_residuals, 0, atol=1e-12)

plane_cases = [
    (5.0, [0, 0, 1,  0], "circle"),
    (5.0, [0, 0, 1, -5], "tangent"),
    (5.0, [0, 0, 1, -6], "disjoint"),
    (0.0, [0, 0, 1,  0], "point"),
]
for radius, plane, expected in plane_cases:
    out = sphere_plane_section_diagnostics(
        [0, 0, 0], radius, plane, **opts
    )
    assert out.relation == expected
    np.testing.assert_allclose(
        out.section_center_plane_residual, 0, atol=1e-12
    )

# --- 3. İki kürenin yedi konumunun sınanması ---
from agbook import sphere_sphere_intersection_diagnostics

opts = dict(
    absolute_tolerance=1e-12,
    relative_tolerance=1e-12,
    reference_scale=20.0,
)
cases = [
    ([0,0,0], 5, [0,0,0], 5, "coincident"),
    ([0,0,0], 5, [0,0,0], 3, "concentric_disjoint"),
    ([0,0,0], 5, [11,0,0], 5, "separate"),
    ([0,0,0], 5, [10,0,0], 5, "externally_tangent"),
    ([0,0,0], 5, [6,0,0], 5, "intersection_circle"),
    ([0,0,0], 5, [2,0,0], 3, "internally_tangent"),
    ([0,0,0], 5, [1,0,0], 3, "contained"),
]
for c1, r1, c2, r2, expected in cases:
    forward = sphere_sphere_intersection_diagnostics(
        c1, r1, c2, r2, **opts
    )
    reverse = sphere_sphere_intersection_diagnostics(
        c2, r2, c1, r1, **opts
    )
    assert forward.relation == reverse.relation == expected

# --- 4. Permütasyon, rijit hareket ve birim dönüşümü ---
import numpy as np
from agbook import sphere_system_diagnostics

C = np.array([
    [0., 0., 0.], [12., 0., 0.],
    [0., 16., 0.], [0., 0., 20.],
])
r = np.sqrt([196., 244., 260., 116.])
opts = dict(
    rank_tolerance=1e-12,
    absolute_tolerance=1e-11,
    relative_tolerance=1e-12,
    reference_scale=20.0,
)
base = sphere_system_diagnostics(C, r, **opts)
order = [2, 0, 3, 1]
permuted = sphere_system_diagnostics(C[order], r[order], **opts)
np.testing.assert_allclose(permuted.anchor, base.anchor)

Q = np.array([[0.,-1.,0.], [1.,0.,0.], [0.,0.,1.]])
t = np.array([30., -10., 7.])
moved = sphere_system_diagnostics(
    C @ Q.T + t, r,
    rank_tolerance=1e-12,
    absolute_tolerance=1e-11,
    relative_tolerance=1e-12,
    reference_scale=60.0,
)
np.testing.assert_allclose(moved.anchor, Q @ base.anchor + t)

c = 100.0
scaled = sphere_system_diagnostics(
    c*C, c*r,
    rank_tolerance=1e-12,
    absolute_tolerance=c*1e-11,
    relative_tolerance=1e-12,
    reference_scale=c*20.0,
)
np.testing.assert_allclose(scaled.anchor, c*base.anchor)
assert scaled.rank == base.rank
np.testing.assert_allclose(
    scaled.condition_number, base.condition_number
)

Kaydedilen çıktı

1. Genel küre sınıflarının ve ölçek değişmezliğinin sınanması

2. Doğru ve düzlem kesitlerinin artıklarla sınanması

3. İki kürenin yedi konumunun sınanması

4. Permütasyon, rijit hareket ve birim dönüşümü

Ç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_20_kure_sistemleri.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_20_kure_sistemleri.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.