You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 02:46:12