#include "fiko/pafta/pafta_kesit.hpp" #include #include "fiko_test.hpp" using namespace fiko; using namespace fiko::pafta; namespace { f64 nokta3(Vec3d a, Vec3d b) { return a.x * b.x + a.y * b.y + a.z * b.z; } } // namespace FIKO_TEST(pafta_kesit_yerelden_dunyaya_tersi) { const geometri::BrepGovde k = geometri::kutu(40, 30, 20); const Olcek bir{1, 1}; const GorunumCizim on = gorunumUret(k, geometri::Gorunum::On, bir); FIKO_KONTROL(on.gecerli); // Yerel (0,0) = görünümün merkezi = kutunun merkezi (izdüşümde). const Vec3d m = yereldenDunyaya(on, geometri::Gorunum::On, bir, {0, 0}); const geometri::GorunumEksen e = geometri::gorunumEksenleri(geometri::Gorunum::On); // Ön görünümde bakış -Y: merkez noktanın X/Z'si kutu merkeziyle örtüşür (Y serbest). FIKO_KONTROL(std::abs(nokta3(m, e.xEks) - on.hamMerkez.x) < 1e-6); FIKO_KONTROL(std::abs(nokta3(m, e.yEks) - on.hamMerkez.y) < 1e-6); // Ölçek uygulanınca yerel mesafe gerçek mesafeye AÇILIR (1:2 → yerel 10 = gerçek 20). const GorunumCizim yari = gorunumUret(k, geometri::Gorunum::On, Olcek{1, 2}); const Vec3d p0 = yereldenDunyaya(yari, geometri::Gorunum::On, Olcek{1, 2}, {0, 0}); const Vec3d p1 = yereldenDunyaya(yari, geometri::Gorunum::On, Olcek{1, 2}, {10, 0}); const Vec3d d{p1.x - p0.x, p1.y - p0.y, p1.z - p0.z}; FIKO_KONTROL(std::abs(std::sqrt(nokta3(d, d)) - 20.0) < 1e-6); } FIKO_TEST(pafta_kesit_duzlemi_normali) { const geometri::BrepGovde k = geometri::kutu(40, 30, 20); const Olcek bir{1, 1}; const GorunumCizim on = gorunumUret(k, geometri::Gorunum::On, bir); const geometri::GorunumEksen e = geometri::gorunumEksenleri(geometri::Gorunum::On); // DİKEY kesit çizgisi → normal görünümün X ekseni doğrultusunda (düzlem dikey). const KesitDuzlem d1 = kesitDuzlemi(on, geometri::Gorunum::On, bir, {0, -20}, {0, 20}); FIKO_KONTROL(d1.gecerli); FIKO_KONTROL(std::abs(std::abs(nokta3(d1.normal, e.xEks)) - 1.0) < 1e-9); FIKO_KONTROL(std::abs(nokta3(d1.normal, e.bakis)) < 1e-9); // bakış yönüne dik DEĞİL: içinde // YATAY çizgi → normal Y ekseni doğrultusunda. const KesitDuzlem d2 = kesitDuzlemi(on, geometri::Gorunum::On, bir, {-20, 0}, {20, 0}); FIKO_KONTROL(std::abs(std::abs(nokta3(d2.normal, e.yEks)) - 1.0) < 1e-9); // Dejenere çizgi → geçersiz (çökme yok). FIKO_KONTROL(!kesitDuzlemi(on, geometri::Gorunum::On, bir, {5, 5}, {5, 5}).gecerli); } FIKO_TEST(pafta_kesit_gorunum_yonu) { using G = geometri::Gorunum; FIKO_KONTROL(kesitGorunumYonu(G::On, {-10, 0}, {10, 0}) == G::Ust); // yatay çizgi FIKO_KONTROL(kesitGorunumYonu(G::On, {0, -10}, {0, 10}) == G::Sol); // dikey çizgi FIKO_KONTROL(kesitGorunumYonu(G::Ust, {-10, 0}, {10, 0}) == G::On); FIKO_KONTROL(kesitGorunumYonu(G::Sol, {0, -10}, {0, 10}) == G::On); } FIKO_TEST(pafta_kesit_harf_ve_etiket) { Pafta p; FIKO_KONTROL(sonrakiKesitHarfi(p) == 'A'); Gorunum g; g.kesitMi = true; g.kesitHarf = 'A'; p.gorunumEkle(g); FIKO_KONTROL(sonrakiKesitHarfi(p) == 'B'); g.kesitHarf = 'B'; p.gorunumEkle(g); FIKO_KONTROL(sonrakiKesitHarfi(p) == 'C'); FIKO_KONTROL(kesitEtiketi('C') == "C-C"); // Kesit olmayan görünümler harfi tüketmez. Pafta q; Gorunum n; q.gorunumEkle(n); FIKO_KONTROL(sonrakiKesitHarfi(q) == 'A'); } FIKO_TEST(pafta_tarama_kare_icini_doldurur) { const std::vector> kare = {{{0, 0}, {20, 0}, {20, 20}, {0, 20}}}; const auto t = taramaUret(kare, 45.0, 4.0); FIKO_KONTROL(!t.empty()); // Tüm parçalar karenin İÇİNDE (küçük tolerans) ve 45° eğimli. for (const auto& [a, b] : t) { FIKO_KONTROL(a.x >= -1e-6 && a.x <= 20 + 1e-6 && a.y >= -1e-6 && a.y <= 20 + 1e-6); FIKO_KONTROL(b.x >= -1e-6 && b.x <= 20 + 1e-6 && b.y >= -1e-6 && b.y <= 20 + 1e-6); const f64 dx = b.x - a.x, dy = b.y - a.y; FIKO_KONTROL(std::abs(std::abs(dx) - std::abs(dy)) < 1e-6); // 45° eğim } // Aralık küçüldükçe çizgi sayısı artar. FIKO_KONTROL(taramaUret(kare, 45.0, 2.0).size() > t.size()); // Geçersiz girdi → boş (çökme yok). FIKO_KONTROL(taramaUret({}, 45.0, 4.0).empty()); FIKO_KONTROL(taramaUret(kare, 45.0, 0.0).empty()); FIKO_KONTROL(taramaUret({{{0, 0}, {1, 1}}}, 45.0, 1.0).empty()); // kontur değil (2 nokta) } FIKO_TEST(pafta_tarama_delikli_konturu_atlar) { // Dış kare + içteki delik: delik taranmaz (tek-çift kuralı). const std::vector> konturlar = { {{0, 0}, {20, 0}, {20, 20}, {0, 20}}, {{8, 8}, {12, 8}, {12, 12}, {8, 12}}}; const auto t = taramaUret(konturlar, 0.0, 1.0); FIKO_KONTROL(!t.empty()); // y=10 taramasında delik boşluğu bırakılmalı → o satırda iki ayrı parça olur. int satirParca = 0; for (const auto& [a, b] : t) if (std::abs(a.y - 10.0) < 1e-9) { ++satirParca; FIKO_KONTROL(!(a.x > 8.0 + 1e-9 && b.x < 12.0 - 1e-9)); // delik içinde parça YOK } FIKO_KONTROL(satirParca == 2); } FIKO_TEST(pafta_kesit_gorunum_uret_kontur_verir) { // Kutuyu ortasından dikey düzlemle kes: kesme yüzü konturu ÇIKMALI (tarama kaynağı). const geometri::BrepGovde k = geometri::kutu(40, 30, 20); const Olcek bir{1, 1}; const GorunumCizim on = gorunumUret(k, geometri::Gorunum::On, bir); FIKO_KONTROL(on.gecerli); const KesitDuzlem kd = kesitDuzlemi(on, geometri::Gorunum::On, bir, {0, -20}, {0, 20}); FIKO_KONTROL(kd.gecerli); const GorunumCizim kes = kesitGorunumUret(k, geometri::Gorunum::Sol, bir, kd.nokta, kd.normal); FIKO_KONTROL(kes.gecerli); FIKO_KONTROL(!kes.kesitKonturlari.empty()); for (const auto& kont : kes.kesitKonturlari) FIKO_KONTROL(kont.size() >= 3); // kapalı // Konturlardan tarama üretilebiliyor (uçtan uca zincir). FIKO_KONTROL(!taramaUret(kes.kesitKonturlari, 45.0, 3.0).empty()); // Kesit görünümünün sıradan görünümden farkı: kontur listesi dolu. FIKO_KONTROL(gorunumUret(k, geometri::Gorunum::Sol, bir).kesitKonturlari.empty()); } FIKO_TEST(pafta_detay_kirp_ve_buyut) { // Yatay çizgi (-20..20, y=0), daire merkez (0,0) r=5, büyütme 2× (ana 1:1 → detay 2:1). GorunumCizim ana; ana.gecerli = true; ana.gorunur = {{{-20, 0}, {20, 0}}}; const GorunumCizim d = detayCizimUret(ana, Olcek{1, 1}, {0, 0}, 5.0, Olcek{2, 1}); FIKO_KONTROL(d.gecerli); FIKO_KONTROL(d.gorunur.size() == 1); // Kırpılan parça [-5,5] → büyütülünce [-10,10]. FIKO_KONTROL(std::abs(d.gorunur[0].front().x + 10.0) < 1e-9); FIKO_KONTROL(std::abs(d.gorunur[0].back().x - 10.0) < 1e-9); FIKO_KONTROL(std::abs(d.boyut.x - 20.0) < 1e-9); // çap × büyütme // Daire dışında kalan çizgi tamamen elenir. GorunumCizim uzak; uzak.gecerli = true; uzak.gorunur = {{{-20, 30}, {20, 30}}}; FIKO_KONTROL(!detayCizimUret(uzak, Olcek{1, 1}, {0, 0}, 5.0, Olcek{2, 1}).gecerli); // Dejenere yarıçap → geçersiz. FIKO_KONTROL(!detayCizimUret(ana, Olcek{1, 1}, {0, 0}, 0.0, Olcek{2, 1}).gecerli); } FIKO_TEST(pafta_detay_daireyi_disaridan_kesen) { // Çizgi daireye dışarıdan girip çıkıyor (uçlar dışarıda, orta içeride). GorunumCizim ana; ana.gecerli = true; ana.gorunur = {{{-20, 2}, {20, 2}}}; // y=2, r=5 → x=±sqrt(21) const GorunumCizim d = detayCizimUret(ana, Olcek{1, 1}, {0, 0}, 5.0, Olcek{1, 1}); FIKO_KONTROL(d.gecerli && d.gorunur.size() == 1); const f64 beklenen = std::sqrt(25.0 - 4.0); FIKO_KONTROL(std::abs(d.gorunur[0].front().x + beklenen) < 1e-6); FIKO_KONTROL(std::abs(d.gorunur[0].back().x - beklenen) < 1e-6); FIKO_KONTROL(std::abs(d.gorunur[0].front().y - 2.0) < 1e-9); // merkeze göre yerel (merkez 0,0) } FIKO_TEST(pafta_detay_harfi_kesitten_bagimsiz) { Pafta p; Gorunum kes; kes.kesitMi = true; kes.kesitHarf = 'A'; p.gorunumEkle(kes); FIKO_KONTROL(sonrakiDetayHarfi(p) == 'A'); // kesit A'sı detay alfabesini tüketmez Gorunum det; det.detayMi = true; det.detayHarf = 'A'; p.gorunumEkle(det); FIKO_KONTROL(sonrakiDetayHarfi(p) == 'B'); FIKO_KONTROL(sonrakiKesitHarfi(p) == 'B'); }