// Eskiz → 2B segment dönüşümü (fiko/sketch/eskiz_segment.hpp) regresyonları. // // REGRESYON (07-21): GSD'nin KOPYA segmentleyicisi çemberin yarıçapını nokta[0] // mesafesinden hesaplıyordu. `daireEkle` ile kurulan çemberde nokta[0] merkezle // çakışık olduğundan r≈0 çıkıyor, HİÇ segment üretilmiyor ve yüzey feature'ları // "Geçerli bir sketch profili gerekli" diyordu — yay/dikdörtgen çalışırken ÇEMBER // reddediliyordu. Kopya kaldırıldı, tek merkezi utility yarıçapı eskizin KENDİ // parametresinden (px(ir)) okuyor. Bu testler o davranışı kilitler. #include #include "fiko/sketch/eskiz_segment.hpp" #include "fiko_test.hpp" using namespace fiko; using namespace fiko::eskiz; namespace { // Segment zincirinin merkeze uzaklık aralığı (yarıçap doğrulaması). void yaricapAraligi(const std::vector& seg, f64 cx, f64 cy, f64& enAz, f64& enCok) { enAz = 1e300; enCok = -1e300; for (const Seg2B& s : seg) { for (const fiko::Vec2d& p : {s.a, s.b}) { const f64 r = std::hypot(p.x - cx, p.y - cy); enAz = std::min(enAz, r); enCok = std::max(enCok, r); } } } // Bir geometri kimliğini eskizden bulup segmentle. std::vector segmentle(EskizVeri& ev, u32 geoKimlik) { std::vector cikti; for (const Geometri& g : ev.geometriler()) if (g.kimlik == geoKimlik) geoSegmentle(ev, g, cikti); return cikti; } } // namespace FIKO_TEST(segment_cember_yaricapi_dogru) { EskizVeri ev; const u32 c = ev.daireEkle(3.0, -4.0, 7.5); const auto seg = segmentle(ev, c); FIKO_KONTROL(!seg.empty()); // eski hata: HİÇ segment üretilmiyordu FIKO_KONTROL(seg.size() == 48); // tam tur, sabit bölüntü f64 enAz = 0, enCok = 0; yaricapAraligi(seg, 3.0, -4.0, enAz, enCok); FIKO_YAKIN(enAz, 7.5, 1e-6); // yarıçap nokta[0]'dan DEĞİL, px(ir)'den FIKO_YAKIN(enCok, 7.5, 1e-6); // Kapalı: ilk segmentin başı ile son segmentin sonu çakışık. FIKO_YAKIN(seg.front().a.x, seg.back().b.x, 1e-9); FIKO_YAKIN(seg.front().a.y, seg.back().b.y, 1e-9); } FIKO_TEST(segment_cember_merkezde_nokta_olsa_da_calisir) { // Kök nedenin doğrudan kilidi: nokta[0] merkezle ÇAKIŞIK olsa bile yarıçap doğru. EskizVeri ev; const u32 c = ev.daireEkle(0.0, 0.0, 5.0); const auto seg = segmentle(ev, c); FIKO_KONTROL(seg.size() == 48); f64 enAz = 0, enCok = 0; yaricapAraligi(seg, 0.0, 0.0, enAz, enCok); FIKO_KONTROL(enAz > 4.99 && enCok < 5.01); // r≈0 DEĞİL } FIKO_TEST(segment_cizgi_uclari_korunur) { EskizVeri ev; const u32 l = ev.cizgiEkle(-2.0, 1.0, 6.0, 4.0); const auto seg = segmentle(ev, l); FIKO_KONTROL(seg.size() == 1); FIKO_YAKIN(seg[0].a.x, -2.0, 1e-9); FIKO_YAKIN(seg[0].a.y, 1.0, 1e-9); FIKO_YAKIN(seg[0].b.x, 6.0, 1e-9); FIKO_YAKIN(seg[0].b.y, 4.0, 1e-9); } FIKO_TEST(segment_yay_araligi_kapali_degil) { EskizVeri ev; const f64 pi = 3.14159265358979323846; const u32 y = ev.yayEkle(0.0, 0.0, 10.0, 0.0, pi); // yarım tur const auto seg = segmentle(ev, y); FIKO_KONTROL(!seg.empty()); f64 enAz = 0, enCok = 0; yaricapAraligi(seg, 0.0, 0.0, enAz, enCok); FIKO_YAKIN(enAz, 10.0, 1e-6); FIKO_YAKIN(enCok, 10.0, 1e-6); // Yarım tur: uçlar ÇAKIŞMAZ (kapalı değil) — (10,0) → (-10,0) FIKO_KONTROL(std::hypot(seg.front().a.x - seg.back().b.x, seg.front().a.y - seg.back().b.y) > 1.0); } FIKO_TEST(segment_elips_iki_yaricap) { EskizVeri ev; const u32 e = ev.elipsEkle(1.0, 2.0, 8.0, 3.0, 0.0); // a=8, b=3, dönme yok const auto seg = segmentle(ev, e); FIKO_KONTROL(seg.size() == 48); // GSD ikizi elipsi HİÇ desteklemiyordu f64 enAz = 0, enCok = 0; yaricapAraligi(seg, 1.0, 2.0, enAz, enCok); FIKO_YAKIN(enCok, 8.0, 1e-6); // büyük eksen FIKO_YAKIN(enAz, 3.0, 1e-6); // küçük eksen } FIKO_TEST(segment_dejenere_ve_nokta_bos_doner) { EskizVeri ev; const u32 n = ev.noktaEkle(1.0, 1.0); FIKO_KONTROL(segmentle(ev, n).empty()); // nokta → segment yok const u32 c0 = ev.daireEkle(0.0, 0.0, 0.0); // sıfır yarıçap → dejenere FIKO_KONTROL(segmentle(ev, c0).empty()); } // Spline: SALT GORSEL Catmull-Rom orneklemesi — GECIS noktalarindan TAM gecer // (t=0/1'de p1/p2), uc sadakati komsu segment zinciri icin sart. BREP karari // egriKonturWire Interpolate'te; buradaki mikro egri farki kabul (gorsel). FIKO_TEST(segment_spline_gecis_noktalari) { EskizVeri ev; const u32 s = ev.splineEkle({{0.0, 0.0}, {5.0, 4.0}, {10.0, 0.0}}); const std::vector seg = segmentle(ev, s); FIKO_KONTROL(seg.size() == 32); // 2 aralik x 16 ornek // Uclar birebir. FIKO_YAKIN(seg.front().a.x, 0.0, 1e-12); FIKO_YAKIN(seg.front().a.y, 0.0, 1e-12); FIKO_YAKIN(seg.back().b.x, 10.0, 1e-12); FIKO_YAKIN(seg.back().b.y, 0.0, 1e-12); // Orta gecis noktasi (5,4) tam olarak 16. segmentin ucunda (araliklar arasi bag). FIKO_YAKIN(seg[15].b.x, 5.0, 1e-9); FIKO_YAKIN(seg[15].b.y, 4.0, 1e-9); // Zincir kopuksuz: her segmentin b'si sonrakinin a'si. for (std::size_t i = 0; i + 1 < seg.size(); ++i) { FIKO_YAKIN(seg[i].b.x, seg[i + 1].a.x, 1e-12); FIKO_YAKIN(seg[i].b.y, seg[i + 1].a.y, 1e-12); } }