# -*- coding: utf-8 -*- u"""出一张 **1:1 测量底板**:把真主板放上去描轮廓 + 从每个定位孔戳一个点, 拍张照回来,`pcb2_measure_read.py` 就能把轮廓和孔位反算成 mm。 /c/Python314/python .claude/pcb2_measure_sheet.py # 出 PDF /c/Python314/python .claude/pcb2_measure_sheet.py --copies 2 # 出 2 页 ## 为什么要专门做一张 2026-09-06:用户徒手画的草图(44 × 66、10 个定位孔)比例和他写的尺寸对不上 ——「④ 距左边 12 mm」在图上量出来是 16.9,「⑦ 距下边 28」量出来 23.4。 ⇒ 草图只能定**拓扑**(几个孔、大致在哪),定不了坐标。 而原来那张 `PCB2-carrier-1to1.pdf` 第 2 页上印着**旧的 7 个孔**,描完轮廓分不清 哪个点是戳的、哪个是印的,所以底板必须干净。 ## 基准点(FID) 四个**实心黑圆 Φ6**,圆心构成一个精确的 %d × %d mm 矩形。 反算时按质心定位 + 单应变换,纸拍歪了也能纠正,精度 ~±0.3 mm。 **四个圆必须全在照片里**,缺一个就没法解。 """ import os import sys sys.stdout.reconfigure(encoding='utf-8') HERE = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, HERE) import fitz from pcb2_pdf import Sheet, scalebar, PT, FONT # 复用 1:1 图那一套画布 OUT = os.path.join(os.path.dirname(HERE), 'shots', 'PCB2-measure-sheet.pdf') PW_MM, PH_MM = 210.0, 297.0 FID_W, FID_H = 160.0, 110.0 # 四个基准点圆心构成的矩形 FID_D = 6.0 # 基准点直径 FID = [(-FID_W / 2, -FID_H / 2), (FID_W / 2, -FID_H / 2), (FID_W / 2, FID_H / 2), (-FID_W / 2, FID_H / 2)] CX, CY = PW_MM / 2, 150.0 # 工作区中心(纸面坐标) BW_GUIDE, BH_GUIDE = 44.0, 66.0 # 主板标称:44 宽 × 66 高,接口边朝左 __doc__ = __doc__ % (FID_W, FID_H) def disc(s, x, y, d): u"""实心圆:Shape.draw_circle + finish(fill=...)。""" s.sh.draw_circle(s.p(x, y), d / 2.0 * PT) s.sh.finish(width=0.2, color=(0, 0, 0), fill=(0, 0, 0)) def page(doc, idx, copies): s = Sheet(doc, PW_MM, PH_MM, CX, CY) # 原点 = 工作区中心 for fx, fy in FID: # 四个基准点 + 编号 disc(s, fx, fy, FID_D) s.text(FID[0][0], FID[0][1] - 6.0, u'FID1', 6, (0.4, 0.4, 0.4)) s.text(FID[1][0], FID[1][1] - 6.0, u'FID2', 6, (0.4, 0.4, 0.4), anchor='r') s.text(FID[2][0], FID[2][1] + 4.0, u'FID3', 6, (0.4, 0.4, 0.4), anchor='r') s.text(FID[3][0], FID[3][1] + 4.0, u'FID4', 6, (0.4, 0.4, 0.4)) # 基准矩形的边长写在图上,反算时可以自检,你也能拿尺量 s.text(0, -FID_H / 2 - 6.0, u'FID 圆心间距 %.0f × %.0f mm' % (FID_W, FID_H), 6, (0.4, 0.4, 0.4), anchor='c') # 放板参考框(标称 44 × 66,虚线,只是提示位置,不用对齐) hw, hh = BW_GUIDE / 2, BH_GUIDE / 2 s.rect(-hw, -hh, hw, hh, 0.3, (0.62, 0.62, 0.62), dash='[2 2] 0') s.line(-hw, -hh, -hw, hh, 0.9, (0.62, 0.62, 0.62)) # 接口边加粗那一条 s.text(-hw - 2.0, 0, u'接口边', 7, (0.45, 0.45, 0.45), anchor='r') s.text(-hw - 2.0, -4.5, u'J600 / J1401', 6, (0.45, 0.45, 0.45), anchor='r') s.text(0, hh + 3.0, u'虚线 = 标称 44 × 66,只是提示位置;实际板小一点大一点都没关系', 6, (0.55, 0.55, 0.55), anchor='c') # 标题与说明(纸面坐标:换到左上角为原点的一块) s.origin(20.0, 0.0) s.text(0, 275.0, u'小米8 主板 · 1:1 测量底板', 12) y = s.para(0, 268.0, u'目的:把真主板的外形和全部定位孔一次性量准。不用尺,描完拍张照给我,' u'我从四个黑圆点反算坐标(约 ±0.3 mm)。孔到底几个以实物为准 —— ' u'草图上是 7 个,戳孔那张能数出 8 个,这次数清楚。', 7.5, width=170.0) y -= 2.0 for t in [u'1. 先量下面那条 100 mm 标尺。不是 100.0 就是打印被缩放了,别往下做,告诉我。', u'2. 主板放到虚线框里,接口边(J600 电池座 / J1401 尾插那条长边)朝左,' u'触点面朝下(就是装到载板上的朝向)。不用对齐虚线框,大致居中就行。', u'3. ⚠ 放好之后到第 4 步做完为止,板子一步都不能动 —— 上一轮的 4 mm 误差' u'多半就是中途挪了。可以先用两小段胶带把板子粘住。', u'4. 先沿板边描一圈轮廓(笔贴着板边、垂直下笔,别外扩);再把每个定位孔' u'用笔尖从孔里戳一个点到纸上,尽量戳在孔正中心。戳完把板拿开,数一下几个点。', u'5. 拍照:整张纸平铺、光照均匀、四个黑圆点全部入镜、镜头尽量正对纸面。' u'能用扫描仪就更好。']: y = s.para(4.0, y, t, 7.5, width=166.0, lead=4.6) - 1.2 y = 70.0 y = s.para(0, y, u'⚠ 别把纸对折,也别在四个黑圆点上写字或压住它们 —— 那是我唯一的比例基准。', 7.5, (0.8, 0, 0), width=170.0) y = s.para(0, y - 1.0, u'另外用卡尺量一下孔径确认。你说约 Φ1.5(M1.4 类),载板会照这个改 —— ' u'原来是 Φ2.5 / M2.5,尼龙立柱要按最终值采购,量准了再定。', 7.5, width=170.0) scalebar(s, 0, y - 14.0) if copies > 1: s.text(170.0, 12.0, u'第 %d / %d 张(两张一样,画废一张还有备用)' % (idx + 1, copies), 6, (0.5, 0.5, 0.5), anchor='r') s.done() def main(): copies = 2 if '--copies' in sys.argv: copies = int(sys.argv[sys.argv.index('--copies') + 1]) doc = fitz.open() for i in range(copies): page(doc, i, copies) doc.set_metadata({'title': u'小米8 主板 1:1 测量底板', 'subject': u'描轮廓 + 戳定位孔,拍照回传反算坐标'}) doc.subset_fonts() doc.save(OUT, garbage=4, deflate=True) print(u'写出 %s(%d 页)' % (OUT, doc.page_count)) print(u'基准点圆心矩形 %.0f × %.0f mm,实心圆 Φ%.1f' % (FID_W, FID_H, FID_D)) if __name__ == '__main__': main()