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

Silindirler, Koniler ve Dönel Yüzeyler

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

Bölüm 21 · 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 21: silindir, koni ve dönel yüzeyler laboratuvarı.

Uygulama, milimetre cinsinden tanımlanmış sentetik ve parçalı doğrusal bir
profilin keyfi bir eksen çevresinde tam tur döndürülmesini inceler. Profil iki
silindirik parça ile aradaki bir konik kesik parçadan oluşur. Hesap yalnız yan
yüzey geometrisidir; kapak, et kalınlığı, yuvarlatma, üretim toleransı ve
yapısal yeterlilik modeli içermez.
"""

from __future__ import annotations

import math

import numpy as np

from agbook import (
    axis_frame_3d,
    canonical_array_sha256,
    circular_cone_diagnostics,
    circular_cylinder_diagnostics,
    piecewise_linear_revolution_diagnostics,
    revolution_surface_point_diagnostics,
    surface_of_revolution_points,
)


def main() -> None:
    length_unit = "mm"
    axis_point_mm = np.array([40.0, -25.0, 15.0])
    axis_direction = np.array([2.0, -1.0, 2.0])
    radial_reference = np.array([1.0, 2.0, 0.0])
    axial_mm = np.array([0.0, 30.0, 60.0, 90.0])
    radial_mm = np.array([18.0, 18.0, 12.0, 12.0])
    angles_rad = np.linspace(0.0, 2.0 * math.pi, 73)
    absolute_tolerance_mm = 1.0e-10

    frame = axis_frame_3d(
        axis_point_mm,
        axis_direction,
        radial_reference=radial_reference,
    )
    profile = piecewise_linear_revolution_diagnostics(axial_mm, radial_mm)
    mesh_mm = surface_of_revolution_points(
        axis_point_mm,
        axis_direction,
        axial_mm,
        radial_mm,
        angles_rad,
        radial_reference=radial_reference,
    )

    first_cylinder_point = mesh_mm[0, 11]
    second_cylinder_point = mesh_mm[-1, 29]
    first_cylinder = circular_cylinder_diagnostics(
        axis_point_mm,
        axis_direction,
        18.0,
        first_cylinder_point,
        axial_bounds=(0.0, 30.0),
        absolute_tolerance=absolute_tolerance_mm,
        reference_scale=90.0,
    )
    second_cylinder = circular_cylinder_diagnostics(
        axis_point_mm,
        axis_direction,
        12.0,
        second_cylinder_point,
        axial_bounds=(60.0, 90.0),
        absolute_tolerance=absolute_tolerance_mm,
        reference_scale=90.0,
    )

    frustum_half_angle = math.atan(0.2)
    virtual_apex_mm = axis_point_mm + 120.0 * frame.unit_axis
    frustum_point = mesh_mm[1, 17]
    frustum_cone = circular_cone_diagnostics(
        virtual_apex_mm,
        -frame.unit_axis,
        frustum_half_angle,
        frustum_point,
        nappe="positive",
        absolute_tolerance=absolute_tolerance_mm,
        reference_scale=120.0,
    )

    cylindrical_regular_point = revolution_surface_point_diagnostics(
        axis_point_mm,
        axis_direction,
        axial_coordinate=15.0,
        radial_coordinate=18.0,
        axial_derivative=1.0,
        radial_derivative=0.0,
        angle=0.7,
        radial_reference=radial_reference,
    )
    frustum_regular_point = revolution_surface_point_diagnostics(
        axis_point_mm,
        axis_direction,
        axial_coordinate=45.0,
        radial_coordinate=15.0,
        axial_derivative=1.0,
        radial_derivative=-0.2,
        angle=1.1,
        radial_reference=radial_reference,
    )
    axis_singularity = revolution_surface_point_diagnostics(
        axis_point_mm,
        axis_direction,
        axial_coordinate=0.0,
        radial_coordinate=0.0,
        axial_derivative=1.0,
        radial_derivative=1.0,
        angle=0.0,
        radial_reference=radial_reference,
    )

    rotation = np.array(
        [
            [0.0, -1.0, 0.0],
            [1.0, 0.0, 0.0],
            [0.0, 0.0, 1.0],
        ]
    )
    translation_mm = np.array([125.0, 60.0, -40.0])
    moved_mesh_mm = surface_of_revolution_points(
        rotation @ axis_point_mm + translation_mm,
        rotation @ axis_direction,
        axial_mm,
        radial_mm,
        angles_rad,
        radial_reference=rotation @ radial_reference,
    )
    expected_moved_mesh_mm = mesh_mm @ rotation.T + translation_mm

    metre_scale = 0.001
    profile_m = piecewise_linear_revolution_diagnostics(
        metre_scale * axial_mm,
        metre_scale * radial_mm,
    )

    expected_slant_lengths_mm = np.array([30.0, 6.0 * math.sqrt(26.0), 30.0])
    expected_areas_mm2 = np.array(
        [
            1080.0 * math.pi,
            180.0 * math.pi * math.sqrt(26.0),
            720.0 * math.pi,
        ]
    )
    expected_total_area_mm2 = 180.0 * math.pi * (10.0 + math.sqrt(26.0))

    assert profile.segment_types == ("cylinder", "frustum", "cylinder")
    np.testing.assert_allclose(profile.slant_lengths, expected_slant_lengths_mm)
    np.testing.assert_allclose(profile.segment_lateral_areas, expected_areas_mm2)
    np.testing.assert_allclose(profile.total_lateral_area, expected_total_area_mm2)
    assert profile.smooth_interior_joins == (False, False)
    assert mesh_mm.shape == (4, 73, 3)
    np.testing.assert_allclose(mesh_mm[:, 0], mesh_mm[:, -1], atol=2.0e-14)
    assert first_cylinder.lateral_surface_member
    assert second_cylinder.lateral_surface_member
    assert frustum_cone.relation == "on_surface"
    assert frustum_cone.allowed_nappe
    assert cylindrical_regular_point.regular
    assert frustum_regular_point.regular
    assert not axis_singularity.regular
    assert axis_singularity.is_axis_point
    np.testing.assert_allclose(moved_mesh_mm, expected_moved_mesh_mm, atol=3.0e-14)
    np.testing.assert_allclose(
        profile_m.total_lateral_area,
        metre_scale**2 * profile.total_lateral_area,
        rtol=3.0e-16,
    )

    signature_values = np.concatenate(
        [
            axis_point_mm,
            axis_direction,
            radial_reference,
            frame.unit_axis,
            frame.radial_u,
            frame.radial_v,
            axial_mm,
            radial_mm,
            angles_rad,
            profile.slant_lengths,
            profile.segment_lateral_areas,
            np.array([profile.total_lateral_area]),
            mesh_mm.ravel(),
            virtual_apex_mm,
            np.array(
                [
                    frustum_half_angle,
                    frustum_cone.implicit_residual,
                    cylindrical_regular_point.area_density,
                    frustum_regular_point.area_density,
                    profile_m.total_lateral_area,
                    absolute_tolerance_mm,
                ]
            ),
        ]
    )

    print("uzunluk_birimi:", length_unit)
    print("model: sentetik_parcali_dogrusal_donel_yan_yuzey")
    print("olculmus_veri_mi: False")
    print("kapak_var_mi: False")
    print("et_kalinligi_var_mi: False")
    print("yuvarlatma_var_mi: False")
    print("uretim_toleransi_modeli_mi: False")
    print("yapisal_yeterlilik_modeli_mi: False")
    print("eksen_noktasi_mm:", axis_point_mm)
    print("eksen_birim_yonu:", frame.unit_axis)
    print("profil_s_mm:", axial_mm)
    print("profil_rho_mm:", radial_mm)
    print("segment_turleri:", profile.segment_types)
    print("egik_uzunluklar_mm:", profile.slant_lengths)
    print("segment_yan_alanlari_mm2:", profile.segment_lateral_areas)
    print("toplam_yan_alan_mm2:", f"{profile.total_lateral_area:.12f}")
    print("ic_birlesimler_duzgun_mu:", profile.smooth_interior_joins)
    print("ilk_silindir_yuzey_uyesi_mi:", first_cylinder.lateral_surface_member)
    print("ikinci_silindir_yuzey_uyesi_mi:", second_cylinder.lateral_surface_member)
    print("konik_kesik_noktasi_koni_uzerinde_mi:", frustum_cone.relation == "on_surface")
    print("rijit_harekette_ag_korundu_mu:", np.allclose(moved_mesh_mm, expected_moved_mesh_mm))
    print(
        "mm2_den_m2_ye_alan_orani:",
        f"{profile_m.total_lateral_area / profile.total_lateral_area:.12e}",
    )
    print("eksen_noktasi_duzenli_mi:", axis_singularity.regular)
    print("sayisal_siniflandirma_esigi_mm:", f"{absolute_tolerance_mm:.12e}")
    print("bilimsel_imza:", canonical_array_sha256(signature_values))


if __name__ == "__main__":
    main()
Doğrulama çalıştırmasının çıktısı
uzunluk_birimi: mm
model: sentetik_parcali_dogrusal_donel_yan_yuzey
olculmus_veri_mi: False
kapak_var_mi: False
et_kalinligi_var_mi: False
yuvarlatma_var_mi: False
uretim_toleransi_modeli_mi: False
yapisal_yeterlilik_modeli_mi: False
eksen_noktasi_mm: [ 40. -25.  15.]
eksen_birim_yonu: [ 0.66666667 -0.33333333  0.66666667]
profil_s_mm: [ 0. 30. 60. 90.]
profil_rho_mm: [18. 18. 12. 12.]
segment_turleri: ('cylinder', 'frustum', 'cylinder')
egik_uzunluklar_mm: [30.         30.59411708 30.        ]
segment_yan_alanlari_mm2: [3392.92006588 2883.42760399 2261.94671058]
toplam_yan_alan_mm2: 8538.294380456164
ic_birlesimler_duzgun_mu: (False, False)
ilk_silindir_yuzey_uyesi_mi: True
ikinci_silindir_yuzey_uyesi_mi: True
konik_kesik_noktasi_koni_uzerinde_mi: True
rijit_harekette_ag_korundu_mu: True
mm2_den_m2_ye_alan_orani: 1.000000000000e-06
eksen_noktasi_duzenli_mi: False
sayisal_siniflandirma_esigi_mm: 1.000000000000e-10
bilimsel_imza: 2a28e63f6dca535eae3668e56fcbdc361ddde3070dae829440f9c563a0a42288
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 21: dönel yüzey profilinin doğrulanması ---
import numpy as np
from agbook import (
    piecewise_linear_revolution_diagnostics,
    surface_of_revolution_points,
)

s = np.array([0.0, 30.0, 60.0, 90.0])
rho = np.array([18.0, 18.0, 12.0, 12.0])
theta = np.linspace(0.0, 2.0*np.pi, 73)

out = piecewise_linear_revolution_diagnostics(s, rho)
mesh = surface_of_revolution_points(
    [40.0, -25.0, 15.0], [2.0, -1.0, 2.0],
    s, rho, theta, radial_reference=[1.0, 2.0, 0.0]
)

assert out.segment_types == ("cylinder", "frustum", "cylinder")
assert out.smooth_interior_joins == (False, False)
np.testing.assert_allclose(mesh[:, 0], mesh[:, -1])
np.testing.assert_allclose(
    out.total_lateral_area,
    180.0*np.pi*(10.0 + np.sqrt(26.0)),
)

Kaydedilen çıktı

1. Bölüm 21: dönel yüzey profilinin doğrulanması
Çözümlerdeki Python kodları

Kod dosyasını indir

# Kitaptaki kod blokları; bu dosya içinde sırayla çalıştırılır.
# --- 1. Eksen çerçevesi değişmezlik sınaması ---
import numpy as np
from agbook import axis_frame_3d

directions = [
    [1,0,0], [0,1,0], [0,0,1],
    [-2,0,0], [1,2,3], [-4,5,-6],
]
for w in directions:
    f = axis_frame_3d([3,-2,7], w)
    B = np.column_stack((f.radial_u, f.radial_v, f.unit_axis))
    np.testing.assert_allclose(B.T @ B, np.eye(3), atol=2e-15)
    np.testing.assert_allclose(np.linalg.det(B), 1.0, atol=2e-15)

base = axis_frame_3d([0,0,0], [1,2,3], radial_reference=[1,0,0])
for c in [0.25, 3.0, 1000.0]:
    out = axis_frame_3d(
        [0,0,0], c*np.array([1.,2.,3.]), radial_reference=[1,0,0]
    )
    np.testing.assert_allclose(out.unit_axis, base.unit_axis)
    np.testing.assert_allclose(out.radial_u, base.radial_u)
    np.testing.assert_allclose(out.radial_v, base.radial_v)

# --- 2. Sonlu silindir üyelik tablosu ---
from agbook import circular_cylinder_diagnostics

cases = [
    ([1,0,2], "inside", "within"),
    ([3,0,2], "outside", "within"),
    ([2,0,2], "on_surface", "within"),
    ([1,0,0], "inside", "lower_boundary"),
    ([1,0,5], "inside", "upper_boundary"),
    ([1,0,6], "inside", "above"),
]
for point, radial, axial in cases:
    out = circular_cylinder_diagnostics(
        [0,0,0], [0,0,1], 2.0, point, axial_bounds=(0.0, 5.0)
    )
    assert out.radial_relation == radial
    assert out.axial_relation == axial
    print(point, radial, axial, out.lateral_surface_member,
          out.cap_member, out.closed_solid_member)

# --- 3. Koni kanatları ve tepe sınaması ---
import numpy as np
from agbook import circular_cone_diagnostics

opts = dict(absolute_tolerance=2e-15, reference_scale=3.0)
cases = [
    ([0,0,0], "double", "apex", "on_surface"),
    ([1,0,1], "double", "positive", "on_surface"),
    ([1,0,-1], "double", "negative", "on_surface"),
    ([0.5,0,1], "double", "positive", "inside"),
    ([2,0,1], "double", "positive", "outside"),
    ([1,0,-1], "positive", "negative", "wrong_nappe"),
]
for point, nappe, side, relation in cases:
    out = circular_cone_diagnostics(
        [0,0,0], [0,0,1], np.pi/4, point, nappe=nappe, **opts
    )
    assert out.side == side
    assert out.relation == relation

# --- 4. Dikiş, rijit hareket ve alan ölçeği ---
import numpy as np
from agbook import (
    piecewise_linear_revolution_diagnostics,
    surface_of_revolution_points,
)

A = np.array([1., -2., 3.])
w = np.array([2., -1., 2.])
s = np.array([0., 2., 5.])
rho = np.array([1., 3., 2.])
theta = np.linspace(0., 2*np.pi, 49)
reference = np.array([1., 0., 0.])
mesh = surface_of_revolution_points(
    A, w, s, rho, theta, radial_reference=reference
)
np.testing.assert_allclose(mesh[:, 0], mesh[:, -1], atol=2e-14)

Q = np.array([[0.,-1.,0.], [1.,0.,0.], [0.,0.,1.]])
t = np.array([8., 4., -5.])
moved = surface_of_revolution_points(
    Q@A+t, Q@w, s, rho, theta, radial_reference=Q@reference
)
np.testing.assert_allclose(moved, mesh@Q.T+t, atol=3e-14)

base = piecewise_linear_revolution_diagnostics(s, rho)
c = 0.001
scaled = piecewise_linear_revolution_diagnostics(c*s, c*rho)
np.testing.assert_allclose(
    scaled.total_lateral_area, c**2*base.total_lateral_area
)

Kaydedilen çıktı

1. Eksen çerçevesi değişmezlik sınaması

2. Sonlu silindir üyelik tablosu
[1, 0, 2] inside within False False True
[3, 0, 2] outside within False False False
[2, 0, 2] on_surface within True False True
[1, 0, 0] inside lower_boundary False True True
[1, 0, 5] inside upper_boundary False True True
[1, 0, 6] inside above False False False

3. Koni kanatları ve tepe sınaması

4. Dikiş, rijit hareket ve alan ölçeği

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