为了测试多边形之间的包含关系,实现了用户设置圆半径和单位长度,程序自动确定圆心位置。
importmathimportturtledefgenerate_polygon_circle(radius,unit_length):""" 生成近似圆的多边形轮廓顶点坐标 参数: radius: 半径 unit_length: 单位长度(多边形的步长) 返回: list: 多边形顶点坐标列表,按顺时针顺序 """ifradius<=0orunit_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))foriinrange(steps_per_quadrant+1):x=i*unit_lengthifx>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圆弧(从顶部到右侧)# 从第一个点(接近顶部)开始foriinrange(len(first_quadrant_points)-1,-1,-1):x_offset,y_offset=first_quadrant_points[i]x=center_x+x_offset y=center_y+y_offsetifvertices:last_x,last_y=vertices[-1]# 插入直角顶点iflast_x!=xandlast_y!=y:vertices.append((last_x,y))vertices.append((x,y))# 第二象限:右下1/4圆弧(从右侧到底部)foriinrange(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]iflast_x!=xandlast_y!=y:vertices.append((last_x,y))vertices.append((x,y))# 第三象限:左下1/4圆弧(从底部到左侧)foriinrange(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]iflast_x!=xandlast_y!=y:vertices.append((last_x,y))vertices.append((x,y))# 第四象限:左上1/4圆弧(从左侧到顶部)foriinrange(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]iflast_x!=xandlast_y!=y:vertices.append((last_x,y))vertices.append((x,y))# 闭合多边形(回到起点)vertices.append(vertices[0])# 对坐标进行单位长度的整数倍调整adjusted_vertices=[]forx,yinvertices:ifunit_length>=2:adj_x=round(x/unit_length)*unit_length adj_y=round(y/unit_length)*unit_lengthelse:adj_x=round(x)adj_y=round(y)adjusted_vertices.append((adj_x,adj_y))returnadjusted_verticesdefdraw_polygon_with_turtle(vertices,radius):"""使用turtle绘制多边形"""# 设置画布screen=turtle.Screen()screen.title("近似圆的多边形")screen.setup(width=800,height=800)# 计算顶点坐标的范围all_x=[xforx,_invertices]all_y=[yfor_,yinvertices]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=800screen_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()ifvertices:first_x,first_y=vertices[0]scaled_x=first_x*scale+offset_x-screen_width/2scaled_y=first_y*scale+offset_y-screen_height/2pen.goto(scaled_x,scaled_y)# 绘制多边形pen.pendown()pen.color("blue")forx,yinvertices:scaled_x=x*scale+offset_x-screen_width/2scaled_y=y*scale+offset_y-screen_height/2pen.goto(scaled_x,scaled_y)# 绘制参考圆pen.penup()center_x=(min_x+max_x)/2*scale+offset_x-screen_width/2center_y=(min_y+max_y)/2*scale+offset_y-screen_height/2pen.goto(center_x,center_y-radius*scale)# 圆的底部pen.pendown()pen.color("red")pen.circle(radius*scale)# 标记顶点(只标记部分顶点,避免太密集)pen.penup()pen.color("green")fori,(x,y)inenumerate(vertices):ifi%max(1,len(vertices)//20)==0:# 只标记约20个点scaled_x=x*scale+offset_x-screen_width/2scaled_y=y*scale+offset_y-screen_height/2pen.goto(scaled_x,scaled_y-10)pen.write(f"{i}",align="center",font=("Arial",8,"normal"))pen.hideturtle()screen.mainloop()# 测试函数deftest_circle_polygon():"""测试生成近似圆的多边形"""print("测试1: 半径10,单位长度1")radius1=10unit1=1vertices1=generate_polygon_circle(radius1,unit1)#draw_polygon_with_turtle(vertices1, radius1)print("顶点坐标:")fori,(x,y)inenumerate(vertices1):print(f"{x:.0f},{y:.0f}")print(f"\n共{len(vertices1)}个顶点")print("\n"+"="*50)print("测试2: 半径10,单位长度2")radius2=10unit2=2vertices2=generate_polygon_circle(radius2,unit2)#draw_polygon_with_turtle(vertices2, radius2)print("顶点坐标:")fori,(x,y)inenumerate(vertices2):print(f"{x:.0f},{y:.0f}")print(f"\n共{len(vertices2)}个顶点")print("\n"+"="*50)print("测试3: 半径21,单位长度3")radius3=21unit3=3vertices3=generate_polygon_circle(radius3,unit3)draw_polygon_with_turtle(vertices3,radius3)print("顶点坐标:")fori,(x,y)inenumerate(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()