Python绘图:多边形各边中点上方绘制文本的偏移计算方法
问题解决思路
你之前用角度区间硬编码单轴偏移的方案问题很明显:角度边界容易出现位置跳变,斜线段仅偏移单轴无法保证文本始终垂直于线段向外偏移,角度越倾斜错位越严重。
最优方案不需要拆分角度区间判断,直接用向量法计算垂直于线段的偏移方向,一套逻辑覆盖所有线段角度,自动满足垂直线靠右、其余线段靠上的规则:
- 第一步:计算线段中点坐标,逻辑和之前的实现一致,两点坐标取平均值即可,不要提前加固定偏移。
- 第二步:计算线段的方向向量,再推导垂直于线段的法向量,通过方向判断自动对齐偏移规则:
- 屏幕坐标系默认Y轴向下为正,「线段上方」即Y值更小的方向,「垂直线右侧」即X值更大的方向
- 线段方向向量为
(dx, dy) = (x2 - x1, y2 - y1),初始法向量取(dy, -dx),这个向量天然和方向向量垂直 - 对法向量做方向校正:如果法向量的Y分量大于0(指向屏幕下方),直接将法向量整体取反;如果法向量Y分量等于0(即线段是垂直线),保证法向量X分量为正(指向屏幕右侧)
- 将法向量归一化为单位向量,乘以预设的偏移距离(比如之前用的35像素),得到最终的X、Y轴偏移量
- 第三步:将偏移量叠加到中点坐标上,把文本的对齐方式设为水平、垂直都居中,直接在偏移后的坐标绘制文本即可,不会和线段重叠。
实现代码
直接替换原来的角度判断和中点计算逻辑即可:
import math def get_text_position(line, offset_distance=35): (x1, y1), (x2, y2) = line[0], line[1] # 计算线段中点 mid_x = (x1 + x2) / 2 mid_y = (y1 + y2) / 2 # 计算方向向量 dx = x2 - x1 dy = y2 - y1 # 处理两点重合的异常情况 line_len = math.hypot(dx, dy) if line_len < 1e-6: return Point(mid_x, mid_y, 0) # 计算初始法向量 nx = dy ny = -dx # 校正法向量方向 if ny > 1e-6: # 法向量朝下,反转到朝上 nx = -nx ny = -ny elif abs(ny) < 1e-6: # 垂直线,保证法向量朝右 if nx < 0: nx = -nx ny = -ny # 归一化后乘以偏移距离 nx = nx / line_len * offset_distance ny = ny / line_len * offset_distance # 得到最终文本位置 return Point(mid_x + nx, mid_y + ny, 0) # 调用示例 m_point = get_text_position(line) # 注意绘制文本时要设置中心对齐,锚点为文本中心 draw_text(m_point, "text", align="center")
方案优势
- 没有硬编码角度区间,不存在临界角度跳变的问题
- 偏移方向始终垂直于线段,不管线段角度多大,文本都正好在中垂线上,不会错位
- 自动适配垂直线靠右的规则,不需要单独写判断分支
- 偏移距离可以统一调整,不需要针对不同角度改偏移值
如果是闭合多边形需要文本始终显示在外侧,只需要调整法向量方向和多边形环绕方向匹配即可,核心计算逻辑不需要改动。
内容的提问来源于stack exchange,提问作者Uncle Bob
相关产品推荐
相关产品推荐

