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

如何在Matplotlib中为六芒星的顶点和交点添加数字标注?

六芒星顶点与交点的数字标注实现

问题解决思路

要完成标注,核心是计算六芒星线条的交点坐标。六芒星由6条连接间隔2个顶点的线段组成,任意两条不平行的线段会相交,通过线段交点公式计算这些交点,再结合顶点坐标一起完成数字标注。

完整代码实现

import matplotlib.pyplot as plt
import math

def get_line_intersection(p1, p2, p3, p4):
    """计算两条线段p1-p2和p3-p4的交点坐标"""
    x1, y1 = p1
    x2, y2 = p2
    x3, y3 = p3
    x4, y4 = p4

    # 计算分母,判断是否平行
    denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)
    if abs(denom) < 1e-6:
        return None  # 平行或重合,无有效交点

    # 计算参数t和u,判断交点是否在线段上
    t_num = (x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)
    t = t_num / denom
    u_num = (x1 - x3) * (y1 - y2) - (y1 - y3) * (x1 - x2)
    u = -u_num / denom

    if 0 <= t <= 1 and 0 <= u <= 1:
        x = x1 + t * (x2 - x1)
        y = y1 + t * (y2 - y1)
        return (round(x, 6), round(y, 6))  # 保留6位小数避免浮点误差
    else:
        return None

def plot_hexagram_with_numbers(side_length):
    # 计算六芒星的6个顶点坐标
    vertices = []
    mu_hexagon = 360 / 6
    for i in range(6):
        angle_rad = math.radians(i * mu_hexagon)
        x = side_length * math.cos(angle_rad)
        y = side_length * math.sin(angle_rad)
        vertices.append((round(x, 6), round(y, 6)))

    # 生成六芒星的所有边(顶点i到i+2)
    edges = [(vertices[i], vertices[(i+2) % 6]) for i in range(6)]

    # 绘制六芒星线条
    for edge in edges:
        x_coords, y_coords = zip(*edge)
        plt.plot(x_coords, y_coords, 'b-', linewidth=2)

    # 计算所有交点坐标并去重
    intersections = []
    for i in range(6):
        for j in range(i + 1, 6):
            intersect = get_line_intersection(*edges[i], *edges[j])
            if intersect is not None:
                # 检查是否已存在该交点(避免重复)
                duplicate = False
                for pt in intersections:
                    if abs(intersect[0] - pt[0]) < 1e-6 and abs(intersect[1] - pt[1]) < 1e-6:
                        duplicate = True
                        break
                if not duplicate:
                    intersections.append(intersect)

    # 合并顶点和交点,准备标注(可自定义数字顺序)
    all_points = vertices + intersections

    # 标注数字
    label_offset = side_length / 15  # 调整标注偏移量
    for idx, (x, y) in enumerate(all_points, 1):
        # 顶点向外偏移,交点向内偏移
        if idx <= 6:
            # 顶点偏移:沿顶点到原点的反方向移动
            offset_x = x * label_offset / side_length
            offset_y = y * label_offset / side_length
            plt.text(x + offset_x, y + offset_y, str(idx), fontsize=12, ha='center', va='center')
        else:
            # 交点偏移:沿交点到原点的方向移动
            offset_x = -x * label_offset / side_length
            offset_y = -y * label_offset / side_length
            plt.text(x + offset_x, y + offset_y, str(idx), fontsize=12, ha='center', va='center')

    # 设置坐标轴等比例,隐藏边框
    plt.axis('equal')
    plt.axis('off')
    plt.show()

# 调用函数生成图示,边长设为2
plot_hexagram_with_numbers(2)

关键部分说明

  1. 线段交点计算:get_line_intersection函数通过参数方程求解两条线段的交点,同时判断交点是否在线段范围内,避免无效交点。
  2. 交点去重:由于每个交点会被两条线段计算两次,通过浮点近似比对来去除重复的交点坐标。
  3. 标注偏移:顶点标注向外偏移,交点标注向内偏移,避免数字与线条重叠,提升可读性。

内容的提问来源于stack exchange,提问作者Reed Jones

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 22:17:23