DeepSeek辅助Python编写直角多边形拟合圆轮廓并画图

编程达人挑战赛·第5期 10w+人浏览 417人参与

为了测试多边形之间的包含关系,实现了用户设置圆半径和单位长度,程序自动确定圆心位置。

import math
import turtle

def generate_polygon_circle(radius, unit_length):
    """
    生成近似圆的多边形轮廓顶点坐标
    
    参数:
        radius: 半径
        unit_length: 单位长度(多边形的步长)
    
    返回:
        list: 多边形顶点坐标列表,按顺时针顺序
    """
    if radius <= 0 or unit_length <= 0:
        return []
    
    vertices = []
    
    # 圆心设为(r, r)以便所有坐标为正
    center_x = radius
    center_y = radius
    
    # 计算总步数(每90度圆弧的步数)
    steps_per_quadrant = max(1, int(radius / unit_length))
    
    # 存储第一象限的点(不含起点)
    first_quadrant_points = []
    
    # 计算第一象限的点(从(0, r)开始,顺时针到(r, 0))
    for i in range(steps_per_quadrant + 1):
        x = i * unit_length
        if x > radius:  # 防止x大于半径
            x = radius
        y_sq = max(0, radius**2 - x**2)
        y = math.sqrt(y_sq)
        first_quadrant_points.append((x, y))
    
    # 起点:正上方 (r, 2r)
    start_x = center_x
    start_y = center_y + radius
    vertices.append((start_x, start_y))
    
    # 第一象限:右上1/4圆弧(从顶部到右侧)
    # 从第一个点(接近顶部)开始
    for i in range(len(first_quadrant_points) - 1, -1, -1):
        x_offset, y_offset = first_quadrant_points[i]
        x = center_x + x_offset
        y = center_y + y_offset
        
        if vertices:
            last_x, last_y = vertices[-1]
            # 插入直角顶点
            if last_x != x and last_y != y:
                vertices.append((last_x, y))
        
        vertices.append((x, y))
    
    # 第二象限:右下1/4圆弧(从右侧到底部)
    for i in range(len(first_quadrant_points)):
        x_offset, y_offset = first_quadrant_points[i]
        x = center_x + y_offset  # 注意:这里x和y交换,因为是对称的
        y = center_y - x_offset
        
        last_x, last_y = vertices[-1]
        if last_x != x and last_y != y:
            vertices.append((last_x, y))
        
        vertices.append((x, y))
    
    # 第三象限:左下1/4圆弧(从底部到左侧)
    for i in range(len(first_quadrant_points) - 1, -1, -1):
        x_offset, y_offset = first_quadrant_points[i]
        x = center_x - x_offset
        y = center_y - y_offset
        
        last_x, last_y = vertices[-1]
        if last_x != x and last_y != y:
            vertices.append((last_x, y))
        
        vertices.append((x, y))
    
    # 第四象限:左上1/4圆弧(从左侧到顶部)
    for i in range(len(first_quadrant_points)):
        x_offset, y_offset = first_quadrant_points[i]
        x = center_x - y_offset  # 注意:这里x和y交换,因为是对称的
        y = center_y + x_offset
        
        last_x, last_y = vertices[-1]
        if last_x != x and last_y != y:
            vertices.append((last_x, y))
        
        vertices.append((x, y))
    
    # 闭合多边形(回到起点)
    vertices.append(vertices[0])
    
    # 对坐标进行单位长度的整数倍调整

    adjusted_vertices = []
    for x, y in vertices:
        if unit_length >= 2:
            adj_x = round(x / unit_length) * unit_length
            adj_y = round(y / unit_length) * unit_length
        else:
            adj_x = round(x)
            adj_y = round(y)
        adjusted_vertices.append((adj_x, adj_y))


    return adjusted_vertices


def draw_polygon_with_turtle(vertices, radius):
    """使用turtle绘制多边形"""
    # 设置画布
    screen = turtle.Screen()
    screen.title("近似圆的多边形")
    screen.setup(width=800, height=800)
    
    # 计算顶点坐标的范围
    all_x = [x for x, _ in vertices]
    all_y = [y for _, y in vertices]
    min_x, max_x = min(all_x), max(all_x)
    min_y, max_y = min(all_y), max(all_y)
    
    # 计算缩放比例,使图形占据画布的70%
    width = max_x - min_x
    height = max_y - min_y
    screen_width = 800
    screen_height = 800
    
    # 计算缩放比例
    scale_x = (screen_width * 0.7) / max(width, 1)
    scale_y = (screen_height * 0.7) / max(height, 1)
    scale = min(scale_x, scale_y)
    
    # 计算偏移量使图形居中
    offset_x = (screen_width - width * scale) / 2 - min_x * scale
    offset_y = (screen_height - height * scale) / 2 - min_y * scale
    
    # 创建画笔
    pen = turtle.Turtle()
    pen.speed(0)  # 最快速度
    pen.width(2)
    
    # 移动到第一个点
    pen.penup()
    if vertices:
        first_x, first_y = vertices[0]
        scaled_x = first_x * scale + offset_x - screen_width / 2
        scaled_y = first_y * scale + offset_y - screen_height / 2
        pen.goto(scaled_x, scaled_y)
    
    # 绘制多边形
    pen.pendown()
    pen.color("blue")
    
    for x, y in vertices:
        scaled_x = x * scale + offset_x - screen_width / 2
        scaled_y = y * scale + offset_y - screen_height / 2
        pen.goto(scaled_x, scaled_y)
    
    # 绘制参考圆
    pen.penup()
    center_x = (min_x + max_x) / 2 * scale + offset_x - screen_width / 2
    center_y = (min_y + max_y) / 2 * scale + offset_y - screen_height / 2
    pen.goto(center_x, center_y - radius * scale)  # 圆的底部
    pen.pendown()
    pen.color("red")
    pen.circle(radius * scale)
    
    # 标记顶点(只标记部分顶点,避免太密集)
    pen.penup()
    pen.color("green")
    for i, (x, y) in enumerate(vertices):
        if i % max(1, len(vertices) // 20) == 0:  # 只标记约20个点
            scaled_x = x * scale + offset_x - screen_width / 2
            scaled_y = y * scale + offset_y - screen_height / 2
            pen.goto(scaled_x, scaled_y - 10)
            pen.write(f"{i}", align="center", font=("Arial", 8, "normal"))
    
    pen.hideturtle()
    screen.mainloop()

# 测试函数
def test_circle_polygon():
    """测试生成近似圆的多边形"""
    print("测试1: 半径10,单位长度1")
    radius1 = 10
    unit1 = 1
    vertices1 = generate_polygon_circle(radius1, unit1)
    #draw_polygon_with_turtle(vertices1, radius1)
    print("顶点坐标:")
    for i, (x, y) in enumerate(vertices1):
        print(f"{x:.0f},{y:.0f}")
    
    print(f"\n共 {len(vertices1)} 个顶点")
    
    print("\n" + "="*50)
    print("测试2: 半径10,单位长度2")
    radius2 = 10
    unit2 = 2
    vertices2 = generate_polygon_circle(radius2, unit2)
    #draw_polygon_with_turtle(vertices2, radius2)
    print("顶点坐标:")
    for i, (x, y) in enumerate(vertices2):
        print(f"{x:.0f},{y:.0f}")
    
    print(f"\n共 {len(vertices2)} 个顶点")
    
    print("\n" + "="*50)
    print("测试3: 半径21,单位长度3")
    radius3 = 21
    unit3 = 3
    vertices3 = generate_polygon_circle(radius3, unit3)
    draw_polygon_with_turtle(vertices3, radius3)
    print("顶点坐标:")
    for i, (x, y) in enumerate(vertices3):
        print(f"{x:.0f},{y:.0f}")
    
    print(f"\n共 {len(vertices3)} 个顶点")
    
    # 使用turtle绘制验证
    #draw_option = input("\n是否使用turtle绘制验证图形?(y/n): ")
    #if draw_option.lower() == 'y':
    #    draw_polygon_with_turtle(vertices1, radius1)

# 主程序
if __name__ == "__main__":
    test_circle_polygon()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值