# -*- coding: utf-8 -*-
"""항번 풍선 끝점 주변에서 '판 두께(PL)만큼 떨어진 평행선 한 쌍'을 실측한다.
   한 쌍이 잡히면 그 뷰에서 그 판은 옆모습(edge-on)이고,
   - 쌍의 중앙선 위치 = 판 중심의 두께방향 좌표
   - 쌍이 덮는 길이 = 그 뷰 평면 안에서의 판 크기
   판정 근거를 그대로 남긴다(추론 아님, 실측)."""
import json, math
import numpy as np

SCR = r'C:\Users\user\AppData\Local\Temp\claude\E-----Claude--20260728-claude-code-2-1-219\8defc145-8ae5-48d0-9058-355f3d9ae8ed\scratchpad'
PL = {1: 30, 2: 30, 3: 25, 4: 25, 5: 20, 6: 20, 7: 20, 8: 30, 9: 30,
      10: 6, 11: 6, 12: 14, 13: None, 14: 12, 15: 6}


def main():
    d2 = json.load(open(SCR + r'\index2.json', encoding='utf-8'))
    L = np.array([l[:4] for l in d2['lines']], dtype=float)
    balls = json.load(open(SCR + r'\asm31_balloons.json'))
    res = []
    for b in balls:
        if not b['tip'] or PL.get(b['item']) is None:
            continue
        t = PL[b['item']]
        p = np.array(b['tip'])
        d0 = np.hypot(L[:, 0] - p[0], L[:, 1] - p[1])
        d1 = np.hypot(L[:, 2] - p[0], L[:, 3] - p[1])
        S = L[(d0 < 90) | (d1 < 90)]
        best = None
        for i in range(len(S)):
            for j in range(i + 1, len(S)):
                a, c = S[i], S[j]
                v1 = np.array([a[2] - a[0], a[3] - a[1]])
                v2 = np.array([c[2] - c[0], c[3] - c[1]])
                n1, n2 = np.linalg.norm(v1), np.linalg.norm(v2)
                if n1 < 10 or n2 < 10:
                    continue
                u1, u2 = v1 / n1, v2 / n2
                if abs(abs(u1 @ u2) - 1) > 0.02:
                    continue
                nrm = np.array([-u1[1], u1[0]])
                dd = float(np.array([c[0] - a[0], c[1] - a[1]]) @ nrm)
                if abs(abs(dd) - t) > 0.8:
                    continue
                span = max(n1, n2)
                if best is None or span > best['span']:
                    mid = (np.array([a[0], a[1]]) + np.array([c[0], c[1]])) / 2 \
                        + nrm * 0  # 중앙선 통과점
                    midpt = (np.array([a[0] + a[2], a[1] + a[3]]) / 2 +
                             np.array([c[0] + c[2], c[1] + c[3]]) / 2) / 2
                    best = {'span': round(span, 1),
                            'ang': round(math.degrees(math.atan2(u1[1], u1[0])) % 180, 1),
                            'gap': round(abs(dd), 2),
                            'mid': [round(float(midpt[0]), 2), round(float(midpt[1]), 2)],
                            'seg_lo': [round(float(min(a[0], a[2], c[0], c[2])), 2),
                                       round(float(min(a[1], a[3], c[1], c[3])), 2)],
                            'seg_hi': [round(float(max(a[0], a[2], c[0], c[2])), 2),
                                       round(float(max(a[1], a[3], c[1], c[3])), 2)]}
        res.append({'item': b['item'], 'view': b.get('view'), 'tip': b['tip'],
                    'PL': t, 'pair': best})
    json.dump(res, open(SCR + r'\asm31_pairs.json', 'w'), indent=1)
    for r in res:
        print(r['item'], r['view'], 'PL%g' % r['PL'], r['pair'])


if __name__ == '__main__':
    main()
