Python Turtle多边形间关节连线实现技术求助
Turtle多边形蠕虫关节连线实现方案
需求说明
已实现随机绘制2-5个、3-8条边的随机位置多边形,现在需要给这些多边形添加蠕虫躯体式的关节连线:
- 前一个多边形的每个点,对应连接到后一个多边形的前N个点(N等于前一个多边形的边数)
- 已有
grouped_joints列表,结构示例:
比如上述示例中,三角形的3个点要分别连到七边形的前3个点。[[(0.00,0.00), (100.00,0.00), (50.00,-86.60)], [(112.00,151.00), (12.86,137.91), (-59.19,207.25), (-49.89,306.82), (33.75,361.63), (128.75,330.41), (163.58,236.67)]]
实现思路
不需要改用字典映射,直接基于grouped_joints的顺序结构遍历即可:
- 遍历相邻的两组多边形点列表(第i组和第i+1组)
- 对每一组相邻多边形,取前一组的所有点,和后一组的前M个点(M是前一组的点数)
- 逐个配对点,用Turtle的绘图方法完成连线,注意控制抬笔/落笔状态避免多余线条
修改后的完整代码
import turtle import random from itertools import islice WIN_TITLE = "Summoning Wonderful Polygonal Creature..." SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 BLACK = 1, 0, 0 WHITE = 0, 0, 0 def quick_setup(): new_screen = turtle.Screen() new_screen.bgcolor(WHITE) new_screen.title(WIN_TITLE) new_screen.setup(width=SCREEN_WIDTH, height=SCREEN_HEIGHT) new_pen = turtle.Turtle() return new_screen, new_pen def move_pen(x=random.randint(-350, 350), y=random.randint(-300, 300)): my_pen.goto(x, y) def rotate_pen(): my_pen.right(random.random()*360) def randomize_pen_color(): random_rgb_values = (random.random(), random.random(), random.random()) my_pen.color(random_rgb_values) def draw_polygon(pen, length=100): polygon_count = random.randint(2, 5) all_side_counts = [] body_joints = [] for polygon in range(polygon_count): sides = random.randint(3, 8) all_side_counts.append(sides) exterior_angle = 360.0/sides pen.begin_fill() for side in range(sides): randomize_pen_color() pen.down() body_joints.append(pen.position()) pen.forward(length) pen.right(exterior_angle) pen.up() pen.end_fill() rotate_pen() move_pen() return body_joints, all_side_counts def group_joints(body_joints, all_side_counts): joint_slices = iter(body_joints) grouped_joints = [list(islice(joint_slices, each_polygon)) for each_polygon in all_side_counts] return grouped_joints def connect_joints(grouped_joints): # 遍历每一对相邻的多边形 for i in range(len(grouped_joints) - 1): prev_poly_points = grouped_joints[i] next_poly_points = grouped_joints[i+1] # 取后一个多边形的前N个点,N等于前一个多边形的点数 connect_points = next_poly_points[:len(prev_poly_points)] # 逐个配对连线 for prev_point, next_point in zip(prev_poly_points, connect_points): my_pen.up() my_pen.goto(prev_point) my_pen.down() # 给连线设置固定颜色,避免和多边形颜色混淆 my_pen.color("gray") my_pen.goto(next_point) my_pen.up() # 恢复随机颜色,不影响后续绘制 randomize_pen_color() if __name__ == "__main__": screen, my_pen = quick_setup() my_pen.speed(0) body_joints, all_side_counts = draw_polygon(my_pen) grouped_joints = group_joints(body_joints, all_side_counts) connect_joints(grouped_joints) screen.exitonclick()
关键代码说明
connect_joints函数中,用range(len(grouped_joints)-1)遍历所有相邻多边形对- 用
zip(prev_poly_points, connect_points)实现点的一一配对 - 连线时先抬笔移动到起点,再落笔绘制,完成后抬笔,避免拖动多余线条
- 给连线设置固定灰色(可自行修改),区分于多边形的随机颜色
内容的提问来源于stack exchange,提问作者blawazahaha
相关产品推荐
相关产品推荐

