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 kodu
"""Bölüm 10 laboratuvarı: dairesel CAD güvenlik bölgesi geometrisi.
Model iki boyutlu ve deterministiktir; koordinatlar milimetredir. Bilinen bir
çember ile üç sonsuz takım yolu arasındaki kesen, teğet ve ayrık ilişkileri
hesaplanır. Sonuç; takım yarıçapı, hareket zamanı, üretim toleransı, parça
deformasyonu veya gerçek bir çarpışma güvenlik kararı içermez.
"""
from __future__ import annotations
import numpy as np
from agbook import (
canonical_array_sha256,
circle_line_intersections,
general_circle_diagnostics,
polar_line_of_point,
rotation_matrix_2d,
tangent_points_from_point,
)
ABSOLUTE_TOLERANCE_MM = 1e-9
RELATIVE_TOLERANCE = 1e-12
def transform_line(line: np.ndarray, rotation: np.ndarray, translation: np.ndarray) -> np.ndarray:
"""``x' = Qx+b`` altında genel doğru katsayılarını taşır."""
moved_normal = rotation @ line[:2]
moved_offset = line[2] - float(np.dot(moved_normal, translation))
return np.r_[moved_normal, moved_offset]
def main() -> None:
center_mm = np.array([120.0, 80.0])
radius_mm = 45.0
reference_scale_mm = 200.0
general_coefficients = np.array(
[
1.0,
-2.0 * center_mm[0],
-2.0 * center_mm[1],
float(np.dot(center_mm, center_mm) - radius_mm**2),
]
)
general = general_circle_diagnostics(general_coefficients)
paths = {
"kesen": np.array([0.0, 1.0, -100.0]),
"teget": np.array([1.0, 0.0, -165.0]),
"ayrik": np.array([0.0, 1.0, -135.0]),
}
diagnostics = {
name: circle_line_intersections(
center_mm,
radius_mm,
line,
absolute_tolerance=ABSOLUTE_TOLERANCE_MM,
relative_tolerance=RELATIVE_TOLERANCE,
reference_scale=reference_scale_mm,
)
for name, line in paths.items()
}
inspection_point_mm = np.array([200.0, 140.0])
contacts = tangent_points_from_point(
center_mm,
radius_mm,
inspection_point_mm,
absolute_tolerance=ABSOLUTE_TOLERANCE_MM,
relative_tolerance=RELATIVE_TOLERANCE,
reference_scale=reference_scale_mm,
)
polar = polar_line_of_point(center_mm, radius_mm, inspection_point_mm)
polar_contact_residuals = contacts.points @ polar[:2] + polar[2]
rotation = rotation_matrix_2d(np.deg2rad(27.0))
translation_mm = np.array([400.0, -150.0])
moved_center_mm = rotation @ center_mm + translation_mm
moved_paths = {
name: transform_line(line, rotation, translation_mm)
for name, line in paths.items()
}
moved_diagnostics = {
name: circle_line_intersections(
moved_center_mm,
radius_mm,
line,
absolute_tolerance=ABSOLUTE_TOLERANCE_MM,
relative_tolerance=RELATIVE_TOLERANCE,
reference_scale=reference_scale_mm,
)
for name, line in moved_paths.items()
}
chord_differences = [
abs(
(moved_diagnostics[name].chord_length or 0.0)
- (diagnostics[name].chord_length or 0.0)
)
for name in paths
]
distance_differences = [
abs(moved_diagnostics[name].center_distance - diagnostics[name].center_distance)
for name in paths
]
print("birim: mm")
print("model: sentetik_iki_boyutlu_cad_geometrisi")
print("tam_carpisma_modeli_mi: False")
print("cember_turu:", general.locus_type)
print("merkez_mm:", np.round(general.center, 9))
print("yaricap_mm:", f"{general.radius:.9f}")
for name, result in diagnostics.items():
print(
f"yol_{name}:",
result.relation,
"merkez_uzakligi_mm=" + f"{result.center_distance:.9f}",
"kiris_uzunlugu_mm="
+ ("yok" if result.chord_length is None else f"{result.chord_length:.9f}"),
)
print(f"yol_{name}_kesisimler_mm:", np.round(result.points, 9))
print("dis_nokta_sinifi:", contacts.relation)
print("teget_uzunlugu_mm:", f"{contacts.tangent_length:.9f}")
print("temas_noktalari_mm:", np.round(contacts.points, 9))
print("kutupsal_kanonik:", np.round(polar, 12))
print("en_buyuk_kutupsal_artigi_mm:", f"{np.max(np.abs(polar_contact_residuals)):.3e}")
print("rijit_siniflar_korundu_mu:", all(
diagnostics[name].relation == moved_diagnostics[name].relation for name in paths
))
print("en_buyuk_rijit_uzaklik_farki_mm:", f"{max(distance_differences):.3e}")
print("en_buyuk_rijit_kiris_farki_mm:", f"{max(chord_differences):.3e}")
signature_values = np.concatenate(
[
center_mm,
np.array([radius_mm, reference_scale_mm, ABSOLUTE_TOLERANCE_MM, RELATIVE_TOLERANCE]),
general_coefficients,
*(line for line in paths.values()),
inspection_point_mm,
rotation.ravel(),
translation_mm,
]
)
print("bilimsel_imza:", canonical_array_sha256(signature_values))
if __name__ == "__main__":
main()
Doğrulama çalıştırmasının çıktısı
birim: mm
model: sentetik_iki_boyutlu_cad_geometrisi
tam_carpisma_modeli_mi: False
cember_turu: circle
merkez_mm: [120. 80.]
yaricap_mm: 45.000000000
yol_kesen: secant merkez_uzakligi_mm=20.000000000 kiris_uzunlugu_mm=80.622577483
yol_kesen_kesisimler_mm: [[160.31128874 100. ]
[ 79.68871126 100. ]]
yol_teget: tangent merkez_uzakligi_mm=45.000000000 kiris_uzunlugu_mm=0.000000000
yol_teget_kesisimler_mm: [[165. 80.]]
yol_ayrik: disjoint merkez_uzakligi_mm=55.000000000 kiris_uzunlugu_mm=yok
yol_ayrik_kesisimler_mm: []
dis_nokta_sinifi: outside
teget_uzunlugu_mm: 89.302855497
temas_noktalari_mm: [[160.31177098 60.00097202]
[112.08822902 124.29902798]]
kutupsal_kanonik: [ 0.8 0.6 -164.25]
en_buyuk_kutupsal_artigi_mm: 0.000e+00
rijit_siniflar_korundu_mu: True
en_buyuk_rijit_uzaklik_farki_mm: 5.684e-14
en_buyuk_rijit_kiris_farki_mm: 2.842e-14
bilimsel_imza: f197d76233595fdea9ed0f49ec7a3a5814f173bbd9e3b6ca083309afa47a0075
Metindeki Python kodları
# Kitaptaki kod blokları; bu dosya içinde sırayla çalıştırılır.
# --- 1. Bölüm 10: doğru--çember ve kutupsal tanısı ---
import numpy as np
from agbook import (
circle_line_intersections,
polar_line_of_point,
tangent_points_from_point,
)
C = np.array([120.0, 80.0]) # mm
r = 45.0 # mm
paths = {
"kesen": [0.0, 1.0, -100.0],
"teget": [1.0, 0.0, -165.0],
"ayrik": [0.0, 1.0, -135.0],
}
tol = dict(
absolute_tolerance=1e-9,
relative_tolerance=1e-12,
reference_scale=200.0,
)
for name, line in paths.items():
out = circle_line_intersections(C, r, line, **tol)
print(name, out.relation, out.center_distance,
out.chord_length)
A = np.array([200.0, 140.0]) # mm
contacts = tangent_points_from_point(C, r, A, **tol)
polar = polar_line_of_point(C, r, A)
print(contacts.relation, contacts.tangent_length)
print(polar)
Kaydedilen çıktı
1. Bölüm 10: doğru--çember ve kutupsal tanısı
kesen secant 20.0 80.62257748298549
teget tangent 45.0 0.0
ayrik disjoint 55.0 None
outside 89.30285549745876
[ 0.8 0.6 -164.25]
Çözümlerdeki Python kodları
# Kitaptaki kod blokları; bu dosya içinde sırayla çalıştırılır.
# --- 1. Genel çember sınıfları ve ölçek değişmezliği ---
import numpy as np
from agbook import general_circle_diagnostics
cases = [
[1., -4., 2., -4.], # r^2=9
[1., -4., 2., 5.], # r^2=0
[1., -4., 2., 7.], # r^2=-2
]
for coefficients in cases:
first = general_circle_diagnostics(coefficients)
second = general_circle_diagnostics(
-7.0 * np.array(coefficients)
)
print(first.locus_type, first.center,
first.radius_squared)
print(np.max(np.abs(first.center-second.center)),
first.radius_squared-second.radius_squared)
# --- 2. Ayrık, teğet ve kesen doğrular ---
from agbook import circle_line_intersections
tol = dict(
absolute_tolerance=1e-12,
relative_tolerance=1e-12,
reference_scale=10.0,
)
for line in ([0, 1, -8], [0, 1, -7], [1, 0, -1]):
out = circle_line_intersections(
[1, 2], 5, line, **tol
)
print(out.relation, out.points.shape,
out.chord_length)
print(out.line_residuals, out.radial_residuals)
# --- 3. Temas, diklik ve kutupsal artıkları ---
import numpy as np
from agbook import (
polar_line_of_point,
tangent_points_from_point,
)
tol = dict(
absolute_tolerance=1e-12,
relative_tolerance=1e-12,
reference_scale=20.0,
)
C, r, A = np.zeros(2), 5.0, np.array([13., 0.])
out = tangent_points_from_point(C, r, A, **tol)
polar = polar_line_of_point(C, r, A)
print(out.relation, out.points)
print(out.radial_residuals)
print(out.orthogonality_residuals)
print(out.points @ polar[:2] + polar[2])
inside = tangent_points_from_point(
C, r, [1., 0.], **tol
)
print(inside.relation, inside.points.shape)
# --- 4. Rijit çerçevede kesişim değişmezliği ---
import numpy as np
from agbook import (
circle_line_intersections,
rotation_matrix_2d,
)
tol = dict(
absolute_tolerance=1e-12,
relative_tolerance=1e-12,
reference_scale=10.0,
)
C = np.array([1., 2.])
line = np.array([0., 1., -4.])
before = circle_line_intersections(C, 5., line, **tol)
Q = rotation_matrix_2d(np.deg2rad(37.0))
b = np.array([8., -3.])
Cm = Q @ C + b
nm = Q @ line[:2]
linem = np.r_[nm, line[2] - nm @ b]
after = circle_line_intersections(Cm, 5., linem, **tol)
expected = before.points @ Q.T + b
print(before.relation, after.relation)
print(before.center_distance, after.center_distance)
print(before.chord_length, after.chord_length)
print(expected)
print(after.points)
Kaydedilen çıktı
1. Genel çember sınıfları ve ölçek değişmezliği
circle [ 2. -1.] 9.0
0.0 0.0
point [ 2. -1.] 0.0
0.0 0.0
empty [ 2. -1.] -2.0
0.0 0.0
2. Ayrık, teğet ve kesen doğrular
disjoint (0, 2) None
[] []
tangent (1, 2) 0.0
[0.] [0.]
secant (2, 2) 10.0
[0. 0.] [0. 0.]
3. Temas, diklik ve kutupsal artıkları
outside [[ 1.92307692 -4.61538462]
[ 1.92307692 4.61538462]]
[0. 0.]
[3.55271368e-15 3.55271368e-15]
[0. 0.]
inside (0, 2)
4. Rijit çerçevede kesişim değişmezliği
secant secant
2.0 2.0
9.16515138991168 9.16515138991168
[[10.05118309 3.55421996]
[ 2.73156774 -1.96150583]]
[[ 2.73156774 -1.96150583]
[10.05118309 3.55421996]]
Ç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_10_cember_kiris_teget.py
python -m pytestWindows 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_10_cember_kiris_teget.py
.venv\Scripts\python.exe -m pytest