为了测试多边形之间的包含关系,实现了用户设置圆半径和单位长度,程序自动确定圆心位置。
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()

2272

被折叠的 条评论
为什么被折叠?



