#include "fiko/pafta/pafta_olcu.hpp" #include #include namespace fiko::pafta { namespace { Vec2d fark(Vec2d a, Vec2d b) { return {a.x - b.x, a.y - b.y}; } f64 uzunluk(Vec2d v) { return std::hypot(v.x, v.y); } Vec2d birim(Vec2d v) { const f64 u = uzunluk(v); return u > 1e-12 ? Vec2d{v.x / u, v.y / u} : Vec2d{1, 0}; } Vec2d dik(Vec2d v) { return {-v.y, v.x}; } Vec2d topla(Vec2d a, Vec2d b) { return {a.x + b.x, a.y + b.y}; } Vec2d olcekle(Vec2d a, f64 k) { return {a.x * k, a.y * k}; } // Ölçünün dayanak doğrultusu (tip'e göre) — ofset bu doğrultuya DİK uygulanır. Vec2d dayanakYonu(const Olcu& o) { switch (o.tip) { case OlcuTip::Yatay: return {1, 0}; case OlcuTip::Dikey: return {0, 1}; default: return birim(fark(o.p2, o.p1)); } } } // namespace f64 olcuDegeri(const Olcu& o, Olcek etkinOlcek) { if (!o.otoDeger) return o.elleDeger; const f64 oran = etkinOlcek.oran() > 0 ? etkinOlcek.oran() : 1.0; const Vec2d d = fark(o.p2, o.p1); switch (o.tip) { case OlcuTip::Yatay: return std::abs(d.x) / oran; case OlcuTip::Dikey: return std::abs(d.y) / oran; case OlcuTip::Aci: { const Vec2d a = fark(o.p1, o.tepe), b = fark(o.p2, o.tepe); if (uzunluk(a) < 1e-12 || uzunluk(b) < 1e-12) return 0.0; const f64 kos = (a.x * b.x + a.y * b.y) / (uzunluk(a) * uzunluk(b)); return std::acos(std::clamp(kos, -1.0, 1.0)) * 180.0 / std::numbers::pi; } default: return uzunluk(d) / oran; // Dogrusal · Capsal · Yaricap } } std::string olcuMetni(const Olcu& o, Olcek etkinOlcek) { const f64 v = olcuDegeri(o, etkinOlcek); const bool aci = o.tip == OlcuTip::Aci; // Hane kuralı merkezî (fiko::birim) — sonek yalnız açıda (teknik resimde mm yazılmaz). std::string s = o.onEk; if (o.onEk.empty()) { if (o.tip == OlcuTip::Capsal) s = "Ø"; else if (o.tip == OlcuTip::Yaricap) s = "R"; } s += birim::bicim(v, aci ? birim::Birim::Aci : birim::Birim::Uzunluk, aci); s += o.sonEk; return s; } OlcuCizim olcuGeometrisi(const Olcu& o) { OlcuCizim c; if (o.tip == OlcuTip::Aci) { // Açı: iki dayanak çizgisi + metin tepe ile açıortay üzerinde (yay UI tarafında). c.cizgiler.push_back({o.tepe, o.p1}); c.cizgiler.push_back({o.tepe, o.p2}); const Vec2d ortay = birim(topla(birim(fark(o.p1, o.tepe)), birim(fark(o.p2, o.tepe)))); c.okA = o.p1; c.okB = o.p2; c.okYon = ortay; c.metinCipa = topla(o.tepe, olcekle(ortay, std::abs(o.ofset))); c.gecerli = uzunluk(fark(o.p1, o.tepe)) > 1e-9 && uzunluk(fark(o.p2, o.tepe)) > 1e-9; return c; } if (o.tip == OlcuTip::Yaricap || o.tip == OlcuTip::Capsal) { // Yarıçap/çap: ölçü çizgisi doğrudan tutunma noktaları arasında (ofset yok). c.cizgiler.push_back({o.p1, o.p2}); c.okA = o.p1; c.okB = o.p2; c.okYon = birim(fark(o.p2, o.p1)); c.metinCipa = olcekle(topla(o.p1, o.p2), 0.5); c.metinAci = std::atan2(c.okYon.y, c.okYon.x); c.gecerli = uzunluk(fark(o.p2, o.p1)) > 1e-9; return c; } // Doğrusal/yatay/dikey: dayanak doğrultusuna DİK ofsetlenmiş ölçü çizgisi + // tutunma noktalarından uzanan uzantı çizgileri. const Vec2d yon = dayanakYonu(o); const Vec2d n = dik(yon); const Vec2d kaydir = olcekle(n, o.ofset); // Ölçü çizgisinin uçları: tutunma noktalarının dayanak eksenine izdüşümü. const auto izdusur = [&](Vec2d p) { const Vec2d rel = fark(p, o.p1); const f64 t = rel.x * yon.x + rel.y * yon.y; return topla(topla(o.p1, olcekle(yon, t)), kaydir); }; const Vec2d a = izdusur(o.p1); const Vec2d b = izdusur(o.p2); c.cizgiler.push_back({o.p1, a}); // uzantı 1 c.cizgiler.push_back({o.p2, b}); // uzantı 2 c.cizgiler.push_back({a, b}); // ölçü çizgisi c.okA = a; c.okB = b; c.okYon = birim(fark(b, a)); c.metinCipa = olcekle(topla(a, b), 0.5); c.metinAci = std::atan2(c.okYon.y, c.okYon.x); // Baş aşağı yazı olmasın: metin daima soldan sağa okunur (ISO 129) → açıyı // ±90° aralığına ÇEVİR (ekleme değil: 180°'de +π 2π'ye taşardı, baş aşağı kalırdı). if (c.metinAci > std::numbers::pi / 2) c.metinAci -= std::numbers::pi; else if (c.metinAci < -std::numbers::pi / 2) c.metinAci += std::numbers::pi; c.gecerli = uzunluk(fark(b, a)) > 1e-9; return c; } } // namespace fiko::pafta