【教学类-70-04】20251231小2班幼儿制作折纸方镜(八卦神兽镜)

背景需求:

去年中2班做了圆镜和方形,幼儿裁剪和绘画图案。

【教学类-70-03】20241121中2班幼儿制作"圆镜和方镜"(适配5CM圆镜)通义万相花边图案https://mp.csdn.net/mp_blog/creation/editor/143951841

但是今年我们是小2班,幼儿不适合集体用剪刀,所以我想用手工纸15CM,做一个八边形的镜子。

一、图纸设计

代码过程

第1稿图纸

python 复制代码
'''
折纸镜子(相框样式)正面1.0
Deepseek,豆包,阿夏
20251220
'''

from PIL import Image, ImageDraw

# 创建白色背景图片
image_size = 1500
image = Image.new('RGB', (image_size, image_size), 'white')
draw = ImageDraw.Draw(image)

# 定义菱形的四个顶点(都在四边中点)
points = [
    (image_size // 2, 0),        # 上中点
    (image_size, image_size // 2), # 右中点
    (image_size // 2, image_size),  # 下中点
    (0, image_size // 2)         # 左中点
]

line_width = 10
dash_pattern = [20, 10]  # [实线长度, 间隔长度]
gray_color = (192, 192, 192)  # 灰色

# 绘制菱形的四条虚线边
def draw_dashed_polygon(draw, points, width, pattern):
    """绘制虚线多边形"""
    # 将点列表闭合(添加第一个点到末尾)
    closed_points = points + [points[0]]
    
    for i in range(len(points)):
        start = closed_points[i]
        end = closed_points[i+1]
        
        # 计算线段长度
        dx = end[0] - start[0]
        dy = end[1] - start[1]
        length = ((dx**2 + dy**2) ** 0.5)
        
        if length == 0:
            continue
            
        # 单位向量
        ux = dx / length
        uy = dy / length
        
        # 虚线模式:实线 + 间隔
        dash_on, dash_off = pattern
        dash_length = dash_on + dash_off
        
        # 绘制虚线
        current = 0
        while current < length:
            # 实线段起点
            dash_start_x = start[0] + ux * current
            dash_start_y = start[1] + uy * current
            
            # 实线段终点
            dash_end = min(current + dash_on, length)
            dash_end_x = start[0] + ux * dash_end
            dash_end_y = start[1] + uy * dash_end
            
            # 绘制实线段
            draw.line([(dash_start_x, dash_start_y), 
                      (dash_end_x, dash_end_y)], 
                     fill='black', width=width)
            
            current += dash_length

# 1. 首先绘制原始菱形
draw_dashed_polygon(draw, points, line_width, dash_pattern)

# 2. 计算四条新连接线的端点
# 顶部边线左1/4点:从左上角(0,0)到右上角(image_size,0)的1/4处
top_left_quarter = (image_size * 1 // 4, 0)

# 左侧边线顶1/4点:从左上角(0,0)到左下角(0,image_size)的1/4处
left_top_quarter = (0, image_size * 1 // 4)

# 顶部边线右1/4点:从左上角(0,0)到右上角(image_size,0)的3/4处
top_right_quarter = (image_size * 3 // 4, 0)

# 右侧边线顶1/4点:从右上角(image_size,0)到右下角(image_size,image_size)的1/4处
right_top_quarter = (image_size, image_size * 1 // 4)

# 右侧边线底1/4点:从右上角(image_size,0)到右下角(image_size,image_size)的3/4处
right_bottom_quarter = (image_size, image_size * 3 // 4)

# 底部边线右1/4点:从左下角(0,image_size)到右下角(image_size,image_size)的3/4处
bottom_right_quarter = (image_size * 3 // 4, image_size)

# 底部边线左1/4点:从左下角(0,image_size)到右下角(image_size,image_size)的1/4处
bottom_left_quarter = (image_size * 1 // 4, image_size)

# 左侧边线底1/4点:从左上角(0,0)到左下角(0,image_size)的3/4处
left_bottom_quarter = (0, image_size * 3 // 4)

# 3. 绘制四条新的连接线
new_lines = [
    # 顶部边线左1/4点与左侧边线顶1/4点连接
    (top_left_quarter, left_top_quarter),
    
    # 顶部边线右1/4点与右侧边线顶1/4点连接
    (top_right_quarter, right_top_quarter),
    
    # 右侧边线底1/4点与底部边线右1/4点连接
    (right_bottom_quarter, bottom_right_quarter),
    
    # 底部边线左1/4点与左侧边线底1/4点连接
    (bottom_left_quarter, left_bottom_quarter),
]

# 绘制新的连接线
def draw_dashed_line(draw, start, end, width, pattern):
    """绘制虚线线段"""
    # 计算线段长度
    dx = end[0] - start[0]
    dy = end[1] - start[1]
    length = ((dx**2 + dy**2) ** 0.5)
    
    if length == 0:
        return
        
    # 单位向量
    ux = dx / length
    uy = dy / length
    
    # 虚线模式:实线 + 间隔
    dash_on, dash_off = pattern
    dash_length = dash_on + dash_off
    
    # 绘制虚线
    current = 0
    while current < length:
        # 实线段起点
        dash_start_x = start[0] + ux * current
        dash_start_y = start[1] + uy * current
        
        # 实线段终点
        dash_end = min(current + dash_on, length)
        dash_end_x = start[0] + ux * dash_end
        dash_end_y = start[1] + uy * dash_end
        
        # 绘制实线段
        draw.line([(dash_start_x, dash_start_y), 
                  (dash_end_x, dash_end_y)], 
                 fill='black', width=width)
        
        current += dash_length

# 绘制四条新的连接线
for start, end in new_lines:
    draw_dashed_line(draw, start, end, line_width, dash_pattern)

# 5. 在中间位置画一个小菱形
# 计算小菱形的尺寸:顶点距离顶部大约是1/4的边长的宽度
# 假设小菱形与大菱形相似,且顶点到中心点的距离是大菱形的1/4

# 计算大菱形的中心点(图片中心)
center_x = image_size // 2
center_y = image_size // 2

# 大菱形的顶点到中心的垂直距离(上顶点到中心的距离)
large_vertical_distance = image_size // 2

# 小菱形的顶点到中心的垂直距离:1/4边长宽度
small_vertical_distance = image_size // 4  # 1500/4 = 375

# 小菱形的顶点到中心的水平距离(保持菱形形状)
small_horizontal_distance = small_vertical_distance

# 计算小菱形的四个顶点
small_diamond_points = [
    (center_x, center_y - small_vertical_distance),        # 上顶点
    (center_x + small_horizontal_distance, center_y),      # 右顶点
    (center_x, center_y + small_vertical_distance),        # 下顶点
    (center_x - small_horizontal_distance, center_y)       # 左顶点
]

# 先填充小菱形为灰色
draw.polygon(small_diamond_points, fill=gray_color, outline=None)

# 绘制小菱形边框(同样使用虚线)
draw_dashed_polygon(draw, small_diamond_points, line_width, dash_pattern)

# 6. 在小菱形内部绘制点点点(黑色圆点)
# 设置点点的参数
dot_radius = 3  # 点点的半径
dot_spacing = 10  # 点与点之间的间距

# 计算小菱形的边界
small_diamond_left = center_x - small_horizontal_distance
small_diamond_right = center_x + small_horizontal_distance
small_diamond_top = center_y - small_vertical_distance
small_diamond_bottom = center_y + small_vertical_distance

# 创建判断点是否在菱形内的函数
def is_point_in_diamond(x, y, center_x, center_y, h_dist, v_dist):
    """判断点(x,y)是否在菱形内"""
    # 菱形的数学方程:|x - center_x|/h_dist + |y - center_y|/v_dist <= 1
    return (abs(x - center_x) / h_dist + abs(y - center_y) / v_dist) <= 1

# 在菱形内均匀绘制点点
for x in range(int(small_diamond_left), int(small_diamond_right), dot_spacing):
    for y in range(int(small_diamond_top), int(small_diamond_bottom), dot_spacing):
        # 检查点是否在菱形内
        if is_point_in_diamond(x, y, center_x, center_y, small_horizontal_distance, small_vertical_distance):
            # 计算圆点的边界框
            dot_left = x - dot_radius
            dot_top = y - dot_radius
            dot_right = x + dot_radius
            dot_bottom = y + dot_radius
            
            # 绘制黑色圆点
            draw.ellipse([dot_left, dot_top, dot_right, dot_bottom], fill='black', outline=None)

# 7. 在画布中心位置画一个20磅的黑色圆点(在点点的上面)
center_dot_radius = 10  # 中心圆点的半径
# 计算圆点的边界框
left = center_x - center_dot_radius
top = center_y - center_dot_radius
right = center_x + center_dot_radius
bottom = center_y + center_dot_radius

# 绘制黑色实心圆点(在最上层)
draw.ellipse([left, top, right, bottom], fill='black', outline=None)

print(f"中心圆点信息:")
print(f"  中心坐标: ({center_x}, {center_y})")
print(f"  圆点直径: {center_dot_radius * 2}像素")

print(f"\n小菱形信息:")
print(f"  中心点: ({center_x}, {center_y})")
print(f"  填充颜色: RGB{gray_color}")
print(f"  顶点到中心垂直距离: {small_vertical_distance}像素")
print(f"  顶点到中心水平距离: {small_horizontal_distance}像素")
print(f"  点点参数: 半径{dot_radius}像素, 间距{dot_spacing}像素")
print(f"  上顶点坐标: {small_diamond_points[0]}")
print(f"  右顶点坐标: {small_diamond_points[1]}")
print(f"  下顶点坐标: {small_diamond_points[2]}")
print(f"  左顶点坐标: {small_diamond_points[3]}")

# 保存图片
output_path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20251215 手工纸镜子\正面1.0.png'
image.save(output_path)

print(f"\n已创建图片: {output_path}")
print(f"图片尺寸: {image_size} x {image_size}")
print(f"菱形线宽: {line_width}像素")
print(f"中心圆点直径: {center_dot_radius * 2}像素")
print(f"虚线模式: 实线{dash_pattern[0]}像素 + 间隔{dash_pattern[1]}像素")
print(f"小菱形点点: 半径{dot_radius}像素, 间距{dot_spacing}像素")

# 显示图片
image.show()

正面1.0

问题:大菱形每条边需要一个中间的点,便于纸张四个角对位折小小三角形。

python 复制代码
'''
折纸镜子(相框样式)反面1.0
Deepseek,豆包,阿夏
20251220
'''
from PIL import Image, ImageDraw
import math

# ===================== 基础配置(颜色变量仅定义一次) =====================
image_size = 1500  # 画布尺寸
line_width = 10    # 线宽
dash_pattern = [20, 10]  # 虚线样式:[实线长度, 间隔长度]
main_line_color = (0, 0, 0)  # 灰色(RGB)
small_diamond_color = 'white'      # 小菱形边框颜色(白色)
output_path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20251215 手工纸镜子\反面1.0.png'

# ===================== 创建画布 =====================
image = Image.new('RGB', (image_size, image_size), 'white')
draw = ImageDraw.Draw(image)

# 大菱形顶点(四边中点)
big_diamond_points = [
    (image_size // 2, 0),        # 上中点
    (image_size, image_size // 2), # 右中点
    (image_size // 2, image_size),  # 下中点
    (0, image_size // 2)         # 左中点
]

# ===================== 工具函数 =====================
def draw_dashed_polygon(draw, points, width, pattern, color):
    """绘制虚线多边形(闭合)"""
    closed_points = points + [points[0]]
    for i in range(len(points)):
        start = closed_points[i]
        end = closed_points[i+1]
        dx = end[0] - start[0]
        dy = end[1] - start[1]
        length = math.hypot(dx, dy)
        if length == 0:
            continue
        ux = dx / length
        uy = dy / length
        dash_on, dash_off = pattern
        dash_length = dash_on + dash_off
        current = 0
        while current < length:
            dash_start = (start[0] + ux * current, start[1] + uy * current)
            dash_end = min(current + dash_on, length)
            dash_end_pos = (start[0] + ux * dash_end, start[1] + uy * dash_end)
            draw.line([dash_start, dash_end_pos], fill=color, width=width)
            current += dash_length

def draw_dashed_line(draw, start, end, width, pattern, color):
    """绘制任意角度虚线(必须传color参数)"""
    dx = end[0] - start[0]
    dy = end[1] - start[1]
    length = math.hypot(dx, dy)
    if length == 0:
        return
    ux = dx / length
    uy = dy / length
    dash_on, dash_off = pattern
    dash_length = dash_on + dash_off
    current = 0
    while current < length:
        dash_start = (start[0] + ux * current, start[1] + uy * current)
        dash_end = min(current + dash_on, length)
        dash_end_pos = (start[0] + ux * dash_end, start[1] + uy * dash_end)
        draw.line([dash_start, dash_end_pos], fill=color, width=width)
        current += dash_length

def find_line_diamond_intersection(line_start, line_end, diamond_points):
    """求线段与菱形的交点(返回最近的有效交点)"""
    x1, y1 = line_start
    x2, y2 = line_end
    diamond_edges = [
        (diamond_points[0], diamond_points[1]),
        (diamond_points[1], diamond_points[2]),
        (diamond_points[2], diamond_points[3]),
        (diamond_points[3], diamond_points[0]),
    ]
    intersections = []
    for edge_start, edge_end in diamond_edges:
        x3, y3 = edge_start
        x4, y4 = edge_end
        denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
        if denom == 0:
            continue
        ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom
        ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom
        if 0 <= ua <= 1 and 0 <= ub <= 1:
            x = x1 + ua * (x2 - x1)
            y = y1 + ua * (y2 - y1)
            intersections.append((x, y))
    if intersections:
        distances = [math.hypot(ix - x1, iy - y1) for ix, iy in intersections]
        return intersections[distances.index(min(distances))]
    return None

def line_intersection(line1, line2):
    """求两条线段的交点(无交点返回None)"""
    x1, y1 = line1[0]
    x2, y2 = line1[1]
    x3, y3 = line2[0]
    x4, y4 = line2[1]
    denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
    if denom == 0:
        return None
    ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom
    ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom
    if 0 <= ua <= 1 and 0 <= ub <= 1:
        x = x1 + ua * (x2 - x1)
        y = y1 + ua * (y2 - y1)
        return (x, y)
    return None

# ===================== 绘制大菱形(RGB灰色) =====================
draw_dashed_polygon(draw, big_diamond_points, line_width, dash_pattern, main_line_color)

# ===================== 绘制1/4点连接线(RGB灰色) =====================
# 计算1/4点坐标
top_left_quarter = (image_size * 1 // 4, 0)
left_top_quarter = (0, image_size * 1 // 4)
top_right_quarter = (image_size * 3 // 4, 0)
right_top_quarter = (image_size, image_size * 1 // 4)
right_bottom_quarter = (image_size, image_size * 3 // 4)
bottom_right_quarter = (image_size * 3 // 4, image_size)
bottom_left_quarter = (image_size * 1 // 4, image_size)
left_bottom_quarter = (0, image_size * 3 // 4)

# 定义1/4点连接线
quarter_lines = [
    (top_left_quarter, left_top_quarter),
    (top_right_quarter, right_top_quarter),
    (right_bottom_quarter, bottom_right_quarter),
    (bottom_left_quarter, left_bottom_quarter),
]

# 绘制1/4点连接线(RGB灰色)
for start, end in quarter_lines:
    draw_dashed_line(draw, start, end, line_width, dash_pattern, main_line_color)

# ===================== 绘制3/8点延伸线(RGB灰色) =====================
# 计算3/8点坐标
top_left_3_8 = (image_size * 3 // 8, 0)
top_right_3_8 = (image_size * 5 // 8, 0)
right_top_3_8 = (image_size, image_size * 3 // 8)
right_bottom_3_8 = (image_size, image_size * 5 // 8)
bottom_right_3_8 = (image_size * 5 // 8, image_size)
bottom_left_3_8 = (image_size * 3 // 8, image_size)
left_bottom_3_8 = (0, image_size * 5 // 8)
left_top_3_8 = (0, image_size * 3 // 8)

# 绘制8条3/8点延伸线(RGB灰色)
draw_dashed_line(
    draw, top_left_3_8,
    find_line_diamond_intersection(top_left_3_8, (top_left_3_8[0], image_size), big_diamond_points),
    line_width, dash_pattern, main_line_color
)
draw_dashed_line(
    draw, top_right_3_8,
    find_line_diamond_intersection(top_right_3_8, (top_right_3_8[0], image_size), big_diamond_points),
    line_width, dash_pattern, main_line_color
)
draw_dashed_line(
    draw, right_top_3_8,
    find_line_diamond_intersection(right_top_3_8, (0, right_top_3_8[1]), big_diamond_points),
    line_width, dash_pattern, main_line_color
)
draw_dashed_line(
    draw, right_bottom_3_8,
    find_line_diamond_intersection(right_bottom_3_8, (0, right_bottom_3_8[1]), big_diamond_points),
    line_width, dash_pattern, main_line_color
)
draw_dashed_line(
    draw, bottom_right_3_8,
    find_line_diamond_intersection(bottom_right_3_8, (bottom_right_3_8[0], 0), big_diamond_points),
    line_width, dash_pattern, main_line_color
)
draw_dashed_line(
    draw, bottom_left_3_8,
    find_line_diamond_intersection(bottom_left_3_8, (bottom_left_3_8[0], 0), big_diamond_points),
    line_width, dash_pattern, main_line_color
)
draw_dashed_line(
    draw, left_bottom_3_8,
    find_line_diamond_intersection(left_bottom_3_8, (image_size, left_bottom_3_8[1]), big_diamond_points),
    line_width, dash_pattern, main_line_color
)
draw_dashed_line(
    draw, left_top_3_8,
    find_line_diamond_intersection(left_top_3_8, (image_size, left_top_3_8[1]), big_diamond_points),
    line_width, dash_pattern, main_line_color
)

# ===================== 绘制小菱形(白色) + 延长线(RGB灰色) =====================
# 小菱形顶点计算
center_x = image_size // 2
center_y = image_size // 2
small_vertical_distance = image_size // 4
small_diamond_points = [
    (center_x, center_y - small_vertical_distance),  # 上顶点
    (center_x + small_vertical_distance, center_y),  # 右顶点
    (center_x, center_y + small_vertical_distance),  # 下顶点
    (center_x - small_vertical_distance, center_y)   # 左顶点
]

# 绘制小菱形边框(白色)
draw_dashed_polygon(draw, small_diamond_points, line_width, dash_pattern, small_diamond_color)

# 绘制小菱形边的延长线(RGB灰色)
for i in range(4):
    # 小菱形当前边的起点、终点
    p_start = small_diamond_points[i]
    p_end = small_diamond_points[(i+1)%4]
    # 边的方向向量(单位化)
    dx = p_end[0] - p_start[0]
    dy = p_end[1] - p_start[1]
    length = math.hypot(dx, dy)
    ux = dx / length
    uy = dy / length

    # 方向1:从p_start向反方向延长
    for j in range(4):
        big_edge = (big_diamond_points[j], big_diamond_points[(j+1)%4])
        t_max = image_size  # 足够大的延长长度
        ext_line = (p_start, (p_start[0] - ux * t_max, p_start[1] - uy * t_max))
        intersect = line_intersection(ext_line, big_edge)
        if intersect:
            draw_dashed_line(draw, p_start, intersect, line_width, dash_pattern, main_line_color)
            break

    # 方向2:从p_end向正方向延长
    for j in range(4):
        big_edge = (big_diamond_points[j], big_diamond_points[(j+1)%4])
        t_max = image_size
        ext_line = (p_end, (p_end[0] + ux * t_max, p_end[1] + uy * t_max))
        intersect = line_intersection(ext_line, big_edge)
        if intersect:
            draw_dashed_line(draw, p_end, intersect, line_width, dash_pattern, main_line_color)
            break

# ===================== 保存与输出信息(仅显示一次颜色变量) =====================
image.save(output_path)
image.show()

# 打印输出信息(精简颜色显示,仅展示一次)
print(f"\n已创建图片: {output_path}")
print(f"图片尺寸: {image_size} x {image_size}")
print(f"所有线宽: {line_width}像素")
print(f"颜色配置: 主要线条={main_line_color}(灰色),小菱形边框={small_diamond_color}")
print(f"虚线模式: 实线{dash_pattern[0]}像素 + 间隔{dash_pattern[1]}像素")
print(f"小菱形每条边有2条延长线,共8条45度延长线")

问题:反面小三角黏贴的地方没有标注三角灰色点点。

第2稿,增加各类点点

python 复制代码
'''
折纸镜子(相框样式)正面2.0
Deepseek,豆包,阿夏
20251220
'''
from PIL import Image, ImageDraw

# 创建白色背景图片
image_size = 1500
image = Image.new('RGB', (image_size, image_size), 'white')
draw = ImageDraw.Draw(image)

# 定义菱形的四个顶点
points = [
    (image_size // 2, 0),        # 上顶点
    (image_size, image_size // 2), # 右顶点
    (image_size // 2, image_size),  # 下顶点
    (0, image_size // 2)         # 左顶点
]

line_width = 10
dash_pattern = [20, 10]  # [实线长度, 间隔长度]
gray_color = (192, 192, 192)  # 灰色

# 绘制菱形的四条虚线边
def draw_dashed_polygon(draw, points, width, pattern):
    """绘制虚线多边形"""
    # 将点列表闭合(添加第一个点到末尾)
    closed_points = points + [points[0]]
    
    for i in range(len(points)):
        start = closed_points[i]
        end = closed_points[i+1]
        
        # 计算线段长度
        dx = end[0] - start[0]
        dy = end[1] - start[1]
        length = ((dx**2 + dy**2) ** 0.5)
        
        if length == 0:
            continue
            
        # 单位向量
        ux = dx / length
        uy = dy / length
        
        # 虚线模式:实线 + 间隔
        dash_on, dash_off = pattern
        dash_length = dash_on + dash_off
        
        # 绘制虚线
        current = 0
        while current < length:
            # 实线段起点
            dash_start_x = start[0] + ux * current
            dash_start_y = start[1] + uy * current
            
            # 实线段终点
            dash_end = min(current + dash_on, length)
            dash_end_x = start[0] + ux * dash_end
            dash_end_y = start[1] + uy * dash_end
            
            # 绘制实线段
            draw.line([(dash_start_x, dash_start_y), 
                      (dash_end_x, dash_end_y)], 
                     fill='black', width=width)
            
            current += dash_length

# 1. 首先绘制原始菱形
draw_dashed_polygon(draw, points, line_width, dash_pattern)

# 2. 在大菱形的四条边的中点上画10磅的黑点
midpoint_dot_radius = 10  # 增大半径到15像素,使圆点更明显

# 计算大菱形四条边的中点
# 菱形的四个顶点:
top = (image_size // 2, 0)          # 上顶点
right = (image_size, image_size // 2) # 右顶点
bottom = (image_size // 2, image_size) # 下顶点
left = (0, image_size // 2)        # 左顶点

# 计算每条边的中点(连接两个相邻顶点)
# 上边(上顶点到右顶点)的中点
top_to_right_mid = (
    (top[0] + right[0]) // 2,
    (top[1] + right[1]) // 2
)

# 右边(右顶点到下顶点)的中点
right_to_bottom_mid = (
    (right[0] + bottom[0]) // 2,
    (right[1] + bottom[1]) // 2
)

# 下边(下顶点到左顶点)的中点
bottom_to_left_mid = (
    (bottom[0] + left[0]) // 2,
    (bottom[1] + left[1]) // 2
)

# 左边(左顶点到上顶点)的中点
left_to_top_mid = (
    (left[0] + top[0]) // 2,
    (left[1] + top[1]) // 2
)

# 四个边的中点
midpoints = [
    top_to_right_mid,     # 上边中点
    right_to_bottom_mid,  # 右边中点
    bottom_to_left_mid,   # 下边中点
    left_to_top_mid       # 左边中点
]

# 绘制四个边中点的黑点
for x, y in midpoints:
    # 计算圆点的边界框
    left_bound = x - midpoint_dot_radius
    top_bound = y - midpoint_dot_radius
    right_bound = x + midpoint_dot_radius
    bottom_bound = y + midpoint_dot_radius
    
    # 绘制黑色实心圆点
    draw.ellipse([left_bound, top_bound, right_bound, bottom_bound], fill='black', outline=None)

print("已在大菱形的四条边的中点上添加了黑色圆点:")
print(f"  菱形顶点:")
print(f"    上顶点: {top}")
print(f"    右顶点: {right}")
print(f"    下顶点: {bottom}")
print(f"    左顶点: {left}")
print(f"\n  计算得到的边中点:")
for i, (x, y) in enumerate(midpoints):
    if i == 0:
        position = "上边中点(上顶点到右顶点的中点)"
        vertex1 = top
        vertex2 = right
    elif i == 1:
        position = "右边中点(右顶点到下顶点的中点)"
        vertex1 = right
        vertex2 = bottom
    elif i == 2:
        position = "下边中点(下顶点到左顶点的中点)"
        vertex1 = bottom
        vertex2 = left
    else:
        position = "左边中点(左顶点到上顶点的中点)"
        vertex1 = left
        vertex2 = top
    
    print(f"    {position}: ({x}, {y}), 直径: {midpoint_dot_radius * 2}像素")
    print(f"      连接: {vertex1} ←→ {vertex2}")

# 3. 计算四条新连接线的端点
# 顶部边线左1/4点:从左上角(0,0)到右上角(image_size,0)的1/4处
top_left_quarter = (image_size * 1 // 4, 0)

# 左侧边线顶1/4点:从左上角(0,0)到左下角(0,image_size)的1/4处
left_top_quarter = (0, image_size * 1 // 4)

# 顶部边线右1/4点:从左上角(0,0)到右上角(image_size,0)的3/4处
top_right_quarter = (image_size * 3 // 4, 0)

# 右侧边线顶1/4点:从右上角(image_size,0)到右下角(image_size,image_size)的1/4处
right_top_quarter = (image_size, image_size * 1 // 4)

# 右侧边线底1/4点:从右上角(image_size,0)到右下角(image_size,image_size)的3/4处
right_bottom_quarter = (image_size, image_size * 3 // 4)

# 底部边线右1/4点:从左下角(0,image_size)到右下角(image_size,image_size)的3/4处
bottom_right_quarter = (image_size * 3 // 4, image_size)

# 底部边线左1/4点:从左下角(0,image_size)到右下角(image_size,image_size)的1/4处
bottom_left_quarter = (image_size * 1 // 4, image_size)

# 左侧边线底1/4点:从左上角(0,0)到左下角(0,image_size)的3/4处
left_bottom_quarter = (0, image_size * 3 // 4)

# 4. 绘制四条新的连接线
new_lines = [
    # 顶部边线左1/4点与左侧边线顶1/4点连接
    (top_left_quarter, left_top_quarter),
    
    # 顶部边线右1/4点与右侧边线顶1/4点连接
    (top_right_quarter, right_top_quarter),
    
    # 右侧边线底1/4点与底部边线右1/4点连接
    (right_bottom_quarter, bottom_right_quarter),
    
    # 底部边线左1/4点与左侧边线底1/4点连接
    (bottom_left_quarter, left_bottom_quarter),
]

# 绘制虚线线段函数
def draw_dashed_line(draw, start, end, width, pattern):
    """绘制虚线线段"""
    # 计算线段长度
    dx = end[0] - start[0]
    dy = end[1] - start[1]
    length = ((dx**2 + dy**2) ** 0.5)
    
    if length == 0:
        return
        
    # 单位向量
    ux = dx / length
    uy = dy / length
    
    # 虚线模式:实线 + 间隔
    dash_on, dash_off = pattern
    dash_length = dash_on + dash_off
    
    # 绘制虚线
    current = 0
    while current < length:
        # 实线段起点
        dash_start_x = start[0] + ux * current
        dash_start_y = start[1] + uy * current
        
        # 实线段终点
        dash_end = min(current + dash_on, length)
        dash_end_x = start[0] + ux * dash_end
        dash_end_y = start[1] + uy * dash_end
        
        # 绘制实线段
        draw.line([(dash_start_x, dash_start_y), 
                  (dash_end_x, dash_end_y)], 
                 fill='black', width=width)
        
        current += dash_length

# 绘制四条新的连接线
for start, end in new_lines:
    draw_dashed_line(draw, start, end, line_width, dash_pattern)

# 5. 在中间位置画一个小菱形
# 计算小菱形的尺寸:顶点距离顶部大约是1/4的边长的宽度

# 计算大菱形的中心点(图片中心)
center_x = image_size // 2
center_y = image_size // 2

# 大菱形的顶点到中心的垂直距离(上顶点到中心的距离)
large_vertical_distance = image_size // 2

# 小菱形的顶点到中心的垂直距离:1/4边长宽度
small_vertical_distance = image_size // 4  # 1500/4 = 375

# 小菱形的顶点到中心的水平距离(保持菱形形状)
small_horizontal_distance = small_vertical_distance

# 计算小菱形的四个顶点
small_diamond_points = [
    (center_x, center_y - small_vertical_distance),        # 上顶点
    (center_x + small_horizontal_distance, center_y),      # 右顶点
    (center_x, center_y + small_vertical_distance),        # 下顶点
    (center_x - small_horizontal_distance, center_y)       # 左顶点
]

# 先填充小菱形为灰色
draw.polygon(small_diamond_points, fill=gray_color, outline=None)

# 绘制小菱形边框(同样使用虚线)
draw_dashed_polygon(draw, small_diamond_points, line_width, dash_pattern)

# 6. 在小菱形内部绘制点点点(黑色圆点)
# 设置点点的参数
dot_radius = 3  # 点点的半径
dot_spacing = 10  # 点与点之间的间距

# 计算小菱形的边界
small_diamond_left = center_x - small_horizontal_distance
small_diamond_right = center_x + small_horizontal_distance
small_diamond_top = center_y - small_vertical_distance
small_diamond_bottom = center_y + small_vertical_distance

# 创建判断点是否在菱形内的函数
def is_point_in_diamond(x, y, center_x, center_y, h_dist, v_dist):
    """判断点(x,y)是否在菱形内"""
    # 菱形的数学方程:|x - center_x|/h_dist + |y - center_y|/v_dist <= 1
    return (abs(x - center_x) / h_dist + abs(y - center_y) / v_dist) <= 1

# 在菱形内均匀绘制点点
for x in range(int(small_diamond_left), int(small_diamond_right), dot_spacing):
    for y in range(int(small_diamond_top), int(small_diamond_bottom), dot_spacing):
        # 检查点是否在菱形内
        if is_point_in_diamond(x, y, center_x, center_y, small_horizontal_distance, small_vertical_distance):
            # 计算圆点的边界框
            dot_left = x - dot_radius
            dot_top = y - dot_radius
            dot_right = x + dot_radius
            dot_bottom = y + dot_radius
            
            # 绘制黑色圆点
            draw.ellipse([dot_left, dot_top, dot_right, dot_bottom], fill='black', outline=None)

# 7. 在画布中心位置画一个20磅的黑色圆点(在点点的上面)
center_dot_radius = 10  # 中心圆点的半径
# 计算圆点的边界框
left_bound = center_x - center_dot_radius
top_bound = center_y - center_dot_radius
right_bound = center_x + center_dot_radius
bottom_bound = center_y + center_dot_radius

# 绘制黑色实心圆点(在最上层)
draw.ellipse([left_bound, top_bound, right_bound, bottom_bound], fill='black', outline=None)

print(f"\n中心圆点信息:")
print(f"  中心坐标: ({center_x}, {center_y})")
print(f"  圆点直径: {center_dot_radius * 2}像素")

print(f"\n小菱形信息:")
print(f"  中心点: ({center_x}, {center_y})")
print(f"  填充颜色: RGB{gray_color}")
print(f"  顶点到中心垂直距离: {small_vertical_distance}像素")
print(f"  顶点到中心水平距离: {small_horizontal_distance}像素")
print(f"  点点参数: 半径{dot_radius}像素, 间距{dot_spacing}像素")
print(f"  上顶点坐标: {small_diamond_points[0]}")
print(f"  右顶点坐标: {small_diamond_points[1]}")
print(f"  下顶点坐标: {small_diamond_points[2]}")
print(f"  左顶点坐标: {small_diamond_points[3]}")

# 保存图片
output_path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20251215 手工纸镜子\正面2.0.png'
image.save(output_path)

print(f"\n已创建图片: {output_path}")
print(f"图片尺寸: {image_size} x {image_size}")
print(f"菱形线宽: {line_width}像素")
print(f"边中点圆点直径: {midpoint_dot_radius * 2}像素")
print(f"中心圆点直径: {center_dot_radius * 2}像素")
print(f"虚线模式: 实线{dash_pattern[0]}像素 + 间隔{dash_pattern[1]}像素")
print(f"小菱形点点: 半径{dot_radius}像素, 间距{dot_spacing}像素")

# 显示图片
image.show()

中间有点,便于四个角与中心点对位

大菱形四边中点有点,便于四个角与中点对位,折小三角形

python 复制代码
'''
折纸镜子(相框样式)反面2.0
Deepseek,豆包,阿夏
20251220
'''
from PIL import Image, ImageDraw
import math

# ===================== 基础配置 =====================
image_size = 1500  # 画布尺寸
line_width = 10    # 线宽
dash_pattern = [20, 10]  # 虚线样式
main_line_color = (0, 0, 0)  # 黑色
small_diamond_color = 'white'  # 小菱形边框
triangle_fill_color = (150, 150, 150)  # 灰色150
dot_color = (192, 192, 192)  # 灰点子颜色
dot_radius = 5  # 点子半径(5磅,约3.5像素)
dot_spacing = 10  # 点子间距(10像素,5磅间距+5磅空白)
output_path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20251215 手工纸镜子\反面2.0.png'

# ===================== 创建画布 =====================
image = Image.new('RGB', (image_size, image_size), 'white')
draw = ImageDraw.Draw(image)

# 大菱形顶点
big_diamond_points = [
    (image_size // 2, 0),        # 上中点
    (image_size, image_size // 2), # 右中点
    (image_size // 2, image_size),  # 下中点
    (0, image_size // 2)         # 左中点
]

# ===================== 工具函数(不变) =====================
def draw_dashed_polygon(draw, points, width, pattern, color):
    closed_points = points + [points[0]]
    for i in range(len(points)):
        start = closed_points[i]
        end = closed_points[i+1]
        dx = end[0] - start[0]
        dy = end[1] - start[1]
        length = math.hypot(dx, dy)
        if length == 0:
            continue
        ux = dx / length
        uy = dy / length
        dash_on, dash_off = pattern
        dash_length = dash_on + dash_off
        current = 0
        while current < length:
            dash_start = (start[0] + ux * current, start[1] + uy * current)
            dash_end = min(current + dash_on, length)
            dash_end_pos = (start[0] + ux * dash_end, start[1] + uy * dash_end)
            draw.line([dash_start, dash_end_pos], fill=color, width=width)
            current += dash_length

def draw_dashed_line(draw, start, end, width, pattern, color):
    dx = end[0] - start[0]
    dy = end[1] - start[1]
    length = math.hypot(dx, dy)
    if length == 0:
        return
    ux = dx / length
    uy = dy / length
    dash_on, dash_off = pattern
    dash_length = dash_on + dash_off
    current = 0
    while current < length:
        dash_start = (start[0] + ux * current, start[1] + uy * current)
        dash_end = min(current + dash_on, length)
        dash_end_pos = (start[0] + ux * dash_end, start[1] + uy * dash_end)
        draw.line([dash_start, dash_end_pos], fill=color, width=width)
        current += dash_length

def find_line_diamond_intersection(line_start, line_end, diamond_points):
    x1, y1 = line_start
    x2, y2 = line_end
    diamond_edges = [
        (diamond_points[0], diamond_points[1]),
        (diamond_points[1], diamond_points[2]),
        (diamond_points[2], diamond_points[3]),
        (diamond_points[3], diamond_points[0]),
    ]
    intersections = []
    for edge_start, edge_end in diamond_edges:
        x3, y3 = edge_start
        x4, y4 = edge_end
        denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
        if denom == 0:
            continue
        ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom
        ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom
        if 0 <= ua <= 1 and 0 <= ub <= 1:
            x = x1 + ua * (x2 - x1)
            y = y1 + ua * (y2 - y1)
            intersections.append((x, y))
    if intersections:
        distances = [math.hypot(ix - x1, iy - y1) for ix, iy in intersections]
        return intersections[distances.index(min(distances))]
    return None

def line_intersection(line1, line2):
    x1, y1 = line1[0]
    x2, y2 = line1[1]
    x3, y3 = line2[0]
    x4, y4 = line2[1]
    denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
    if denom == 0:
        return None
    ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom
    ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom
    if 0 <= ua <= 1 and 0 <= ub <= 1:
        x = x1 + ua * (x2 - x1)
        y = y1 + ua * (y2 - y1)
        return (x, y)
    return None

def draw_dots_in_triangle(draw, triangle_points):
    """在三角形内部绘制均匀分布的小圆点"""
    # 找到三角形的边界
    x_coords = [p[0] for p in triangle_points]
    y_coords = [p[1] for p in triangle_points]
    min_x, max_x = min(x_coords), max(x_coords)
    min_y, max_y = min(y_coords), max(y_coords)
    
    # 生成网格点
    x = min_x + dot_spacing
    while x <= max_x - dot_spacing:
        y = min_y + dot_spacing
        while y <= max_y - dot_spacing:
            # 检查点是否在三角形内部
            if point_in_triangle((x, y), triangle_points):
                # 绘制小圆点
                draw.ellipse(
                    [x - dot_radius, y - dot_radius, 
                     x + dot_radius, y + dot_radius],
                    fill=dot_color
                )
            y += dot_spacing
        x += dot_spacing

def point_in_triangle(point, triangle):
    """检查点是否在三角形内部(使用重心坐标法)"""
    x, y = point
    (x1, y1), (x2, y2), (x3, y3) = triangle
    
    # 计算重心坐标
    denom = ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3))
    if denom == 0:
        return False
        
    a = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) / denom
    b = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) / denom
    c = 1 - a - b
    
    # 如果所有重心坐标都在0和1之间,点在三角形内部
    return 0 <= a <= 1 and 0 <= b <= 1 and 0 <= c <= 1

# ===================== 绘制原有图形(不变) =====================
# 大菱形
draw_dashed_polygon(draw, big_diamond_points, line_width, dash_pattern, main_line_color)

# 1/4点连接线
top_left_quarter = (image_size * 1 // 4, 0)
left_top_quarter = (0, image_size * 1 // 4)
top_right_quarter = (image_size * 3 // 4, 0)
right_top_quarter = (image_size, image_size * 1 // 4)
right_bottom_quarter = (image_size, image_size * 3 // 4)
bottom_right_quarter = (image_size * 3 // 4, image_size)
bottom_left_quarter = (image_size * 1 // 4, image_size)
left_bottom_quarter = (0, image_size * 3 // 4)
quarter_lines = [
    (top_left_quarter, left_top_quarter),
    (top_right_quarter, right_top_quarter),
    (right_bottom_quarter, bottom_right_quarter),
    (bottom_left_quarter, left_bottom_quarter),
]
for start, end in quarter_lines:
    draw_dashed_line(draw, start, end, line_width, dash_pattern, main_line_color)

# 3/8点延伸线
top_left_3_8 = (image_size * 3 // 8, 0)
top_right_3_8 = (image_size * 5 // 8, 0)
right_top_3_8 = (image_size, image_size * 3 // 8)
right_bottom_3_8 = (image_size, image_size * 5 // 8)
bottom_right_3_8 = (image_size * 5 // 8, image_size)
bottom_left_3_8 = (image_size * 3 // 8, image_size)
left_bottom_3_8 = (0, image_size * 5 // 8)
left_top_3_8 = (0, image_size * 3 // 8)
draw_dashed_line(draw, top_left_3_8, find_line_diamond_intersection(top_left_3_8, (top_left_3_8[0], image_size), big_diamond_points), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, top_right_3_8, find_line_diamond_intersection(top_right_3_8, (top_right_3_8[0], image_size), big_diamond_points), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, right_top_3_8, find_line_diamond_intersection(right_top_3_8, (0, right_top_3_8[1]), big_diamond_points), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, right_bottom_3_8, find_line_diamond_intersection(right_bottom_3_8, (0, right_bottom_3_8[1]), big_diamond_points), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, bottom_right_3_8, find_line_diamond_intersection(bottom_right_3_8, (bottom_right_3_8[0], 0), big_diamond_points), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, bottom_left_3_8, find_line_diamond_intersection(bottom_left_3_8, (bottom_left_3_8[0], 0), big_diamond_points), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, left_bottom_3_8, find_line_diamond_intersection(left_bottom_3_8, (image_size, left_bottom_3_8[1]), big_diamond_points), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, left_top_3_8, find_line_diamond_intersection(left_top_3_8, (image_size, left_top_3_8[1]), big_diamond_points), line_width, dash_pattern, main_line_color)

# 小菱形+延长线
center_x = image_size // 2
center_y = image_size // 2
small_vertical_distance = image_size // 4
small_diamond_points = [
    (center_x, center_y - small_vertical_distance),
    (center_x + small_vertical_distance, center_y),
    (center_x, center_y + small_vertical_distance),
    (center_x - small_vertical_distance, center_y)
]
draw_dashed_polygon(draw, small_diamond_points, line_width, dash_pattern, small_diamond_color)
for i in range(4):
    p_start = small_diamond_points[i]
    p_end = small_diamond_points[(i+1)%4]
    dx = p_end[0] - p_start[0]
    dy = p_end[1] - p_start[1]
    length = math.hypot(dx, dy)
    ux = dx / length
    uy = dy / length
    # 反方向延长
    for j in range(4):
        big_edge = (big_diamond_points[j], big_diamond_points[(j+1)%4])
        ext_line = (p_start, (p_start[0] - ux * image_size, p_start[1] - uy * image_size))
        intersect = line_intersection(ext_line, big_edge)
        if intersect:
            draw_dashed_line(draw, p_start, intersect, line_width, dash_pattern, main_line_color)
            break
    # 正方向延长
    for j in range(4):
        big_edge = (big_diamond_points[j], big_diamond_points[(j+1)%4])
        ext_line = (p_end, (p_end[0] + ux * image_size, p_end[1] + uy * image_size))
        intersect = line_intersection(ext_line, big_edge)
        if intersect:
            draw_dashed_line(draw, p_end, intersect, line_width, dash_pattern, main_line_color)
            break

# ===================== 绘制向外扩展的灰色三角形(核心调整) =====================
# 计算网格基础单位(1/8画布尺寸)
unit = image_size // 8  # 1500//8 = 187.5

# 定义4个向外扩展的三角形顶点坐标
# 1. 上方三角形(向画布顶部外扩)
top_triangle = [
    (center_x - 1*unit, center_y - 3*unit),  # 左顶点(更上+更左)
    (center_x + 1*unit, center_y - 3*unit),  # 右顶点(更上+更右)
    (center_x, center_y - 2*unit)            # 下顶点(直角顶点,向外移)
]

# 2. 左方三角形(向画布左侧外扩)
left_triangle = [
    (center_x - 3*unit, center_y - 1*unit),  # 上顶点(更左+更上)
    (center_x - 3*unit, center_y + 1*unit),  # 下顶点(更左+更下)
    (center_x - 2*unit, center_y)            # 右顶点(直角顶点,向外移)
]

# 3. 右方三角形(向画布右侧外扩)
right_triangle = [
    (center_x + 3*unit, center_y - 1*unit),  # 上顶点(更右+更上)
    (center_x + 3*unit, center_y + 1*unit),  # 下顶点(更右+更下)
    (center_x + 2*unit, center_y)            # 左顶点(直角顶点,向外移)
]

# 4. 下方三角形(向画布底部外扩)
bottom_triangle = [
    (center_x - 1*unit, center_y + 3*unit),  # 左顶点(更下+更左)
    (center_x + 1*unit, center_y + 3*unit),  # 右顶点(更下+更右)
    (center_x, center_y + 2*unit)            # 上顶点(直角顶点,向外移)
]

# 批量绘制4个向外扩展的灰色三角形
triangles = [top_triangle, left_triangle, right_triangle, bottom_triangle]
for triangle in triangles:
    draw.polygon(triangle, fill=triangle_fill_color)
    # 在每个三角形内部绘制小圆点
    draw_dots_in_triangle(draw, triangle)

# ===================== 保存与输出 =====================
image.save(output_path)
image.show()

# 打印坐标验证信息
print(f"\n已创建图片: {output_path}")
print(f"图片尺寸: {image_size} x {image_size}")
print(f"点子半径: {dot_radius}像素")
print(f"点子间距: {dot_spacing}像素")
print(f"三角形填充色: RGB{triangle_fill_color}")
print(f"点子颜色: RGB{dot_color}")
print(f"\n向外扩展的三角形坐标:")
print(f"上方三角: {top_triangle}")
print(f"左方三角: {left_triangle}")
print(f"右方三角: {right_triangle}")
print(f"下方三角: {bottom_triangle}")

有灰色的三角形

灰度点子的灰色与正面的镜子贴面的灰度点子灰色相同

三、图案黏贴

把小三角贴到镜面,背面贴神兽图

这个图纸好难做啊

正面(考虑有0.7的预留白边,打印机有0,7白边没法打印到)

python 复制代码
'''
折纸镜子(相框样式)正面3.0
Deepseek,豆包,阿夏
20251220
'''
from PIL import Image, ImageDraw

# 新的颜色和尺寸参数定义
image_size = 1500  # 画布尺寸
line_width = 10    # 线宽
dash_pattern = [20, 10]  # 虚线样式
main_line_color = (0, 0, 0)  # 黑色
small_diamond_color = 'white'  # 小菱形边框
triangle_fill_color = (150, 150, 150)  # 灰色150
dot_color = (192, 192, 192)  # 灰点子颜色
dot_radius = 5  # 点子半径(5磅,约3.5像素)
dot_spacing = 10  # 点子间距(10像素,5磅间距+5磅空白)
output_path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20251215 手工纸镜子\正面3.0.png'

# 创建白色背景图片
image = Image.new('RGB', (image_size, image_size), 'white')
draw = ImageDraw.Draw(image)

# 定义菱形的四个顶点
points = [
    (image_size // 2, 0),        # 上顶点
    (image_size, image_size // 2), # 右顶点
    (image_size // 2, image_size),  # 下顶点
    (0, image_size // 2)         # 左顶点
]

# 绘制菱形的四条虚线边
def draw_dashed_polygon(draw, points, width, pattern):
    """绘制虚线多边形"""
    # 将点列表闭合(添加第一个点到末尾)
    closed_points = points + [points[0]]
    
    for i in range(len(points)):
        start = closed_points[i]
        end = closed_points[i+1]
        
        # 计算线段长度
        dx = end[0] - start[0]
        dy = end[1] - start[1]
        length = ((dx**2 + dy**2) ** 0.5)
        
        if length == 0:
            continue
            
        # 单位向量
        ux = dx / length
        uy = dy / length
        
        # 虚线模式:实线 + 间隔
        dash_on, dash_off = pattern
        dash_length = dash_on + dash_off
        
        # 绘制虚线
        current = 0
        while current < length:
            # 实线段起点
            dash_start_x = start[0] + ux * current
            dash_start_y = start[1] + uy * current
            
            # 实线段终点
            dash_end = min(current + dash_on, length)
            dash_end_x = start[0] + ux * dash_end
            dash_end_y = start[1] + uy * dash_end
            
            # 绘制实线段(使用新定义的主线条颜色)
            draw.line([(dash_start_x, dash_start_y), 
                      (dash_end_x, dash_end_y)], 
                     fill=main_line_color, width=width)
            
            current += dash_length

# 1. 首先绘制原始菱形
draw_dashed_polygon(draw, points, line_width, dash_pattern)

# 2. 在大菱形的四条边的中点上画10磅的黑点
midpoint_dot_radius = 10  # 增大半径到15像素,使圆点更明显

# 计算大菱形四条边的中点
# 菱形的四个顶点:
top = (image_size // 2, 0)          # 上顶点
right = (image_size, image_size // 2) # 右顶点
bottom = (image_size // 2, image_size) # 下顶点
left = (0, image_size // 2)        # 左顶点

# 计算每条边的中点(连接两个相邻顶点)
# 上边(上顶点到右顶点)的中点
top_to_right_mid = (
    (top[0] + right[0]) // 2,
    (top[1] + right[1]) // 2
)

# 右边(右顶点到下顶点)的中点
right_to_bottom_mid = (
    (right[0] + bottom[0]) // 2,
    (right[1] + bottom[1]) // 2
)

# 下边(下顶点到左顶点)的中点
bottom_to_left_mid = (
    (bottom[0] + left[0]) // 2,
    (bottom[1] + left[1]) // 2
)

# 左边(左顶点到上顶点)的中点
left_to_top_mid = (
    (left[0] + top[0]) // 2,
    (left[1] + top[1]) // 2
)

# 四个边的中点
midpoints = [
    top_to_right_mid,     # 上边中点
    right_to_bottom_mid,  # 右边中点
    bottom_to_left_mid,   # 下边中点
    left_to_top_mid       # 左边中点
]

# 绘制四个边中点的黑点
for x, y in midpoints:
    # 计算圆点的边界框
    left_bound = x - midpoint_dot_radius
    top_bound = y - midpoint_dot_radius
    right_bound = x + midpoint_dot_radius
    bottom_bound = y + midpoint_dot_radius
    
    # 绘制黑色实心圆点
    draw.ellipse([left_bound, top_bound, right_bound, bottom_bound], fill=main_line_color, outline=None)

print("已在大菱形的四条边的中点上添加了黑色圆点:")
print(f"  菱形顶点:")
print(f"    上顶点: {top}")
print(f"    右顶点: {right}")
print(f"    下顶点: {bottom}")
print(f"    左顶点: {left}")
print(f"\n  计算得到的边中点:")
for i, (x, y) in enumerate(midpoints):
    if i == 0:
        position = "上边中点(上顶点到右顶点的中点)"
        vertex1 = top
        vertex2 = right
    elif i == 1:
        position = "右边中点(右顶点到下顶点的中点)"
        vertex1 = right
        vertex2 = bottom
    elif i == 2:
        position = "下边中点(下顶点到左顶点的中点)"
        vertex1 = bottom
        vertex2 = left
    else:
        position = "左边中点(左顶点到上顶点的中点)"
        vertex1 = left
        vertex2 = top
    
    print(f"    {position}: ({x}, {y}), 直径: {midpoint_dot_radius * 2}像素")
    print(f"      连接: {vertex1} ←→ {vertex2}")

# 3. 计算四条新连接线的端点
# 顶部边线左1/4点:从左上角(0,0)到右上角(image_size,0)的1/4处
top_left_quarter = (image_size * 1 // 4, 0)

# 左侧边线顶1/4点:从左上角(0,0)到左下角(0,image_size)的1/4处
left_top_quarter = (0, image_size * 1 // 4)

# 顶部边线右1/4点:从左上角(0,0)到右上角(image_size,0)的3/4处
top_right_quarter = (image_size * 3 // 4, 0)

# 右侧边线顶1/4点:从右上角(image_size,0)到右下角(image_size,image_size)的1/4处
right_top_quarter = (image_size, image_size * 1 // 4)

# 右侧边线底1/4点:从右上角(image_size,0)到右下角(image_size,image_size)的3/4处
right_bottom_quarter = (image_size, image_size * 3 // 4)

# 底部边线右1/4点:从左下角(0,image_size)到右下角(image_size,image_size)的3/4处
bottom_right_quarter = (image_size * 3 // 4, image_size)

# 底部边线左1/4点:从左下角(0,image_size)到右下角(image_size,image_size)的1/4处
bottom_left_quarter = (image_size * 1 // 4, image_size)

# 左侧边线底1/4点:从左上角(0,0)到左下角(0,image_size)的3/4处
left_bottom_quarter = (0, image_size * 3 // 4)

# 4. 绘制四条新的连接线
new_lines = [
    # 顶部边线左1/4点与左侧边线顶1/4点连接
    (top_left_quarter, left_top_quarter),
    
    # 顶部边线右1/4点与右侧边线顶1/4点连接
    (top_right_quarter, right_top_quarter),
    
    # 右侧边线底1/4点与底部边线右1/4点连接
    (right_bottom_quarter, bottom_right_quarter),
    
    # 底部边线左1/4点与左侧边线底1/4点连接
    (bottom_left_quarter, left_bottom_quarter),
]

# 绘制虚线线段函数
def draw_dashed_line(draw, start, end, width, pattern):
    """绘制虚线线段"""
    # 计算线段长度
    dx = end[0] - start[0]
    dy = end[1] - start[1]
    length = ((dx**2 + dy**2) ** 0.5)
    
    if length == 0:
        return
        
    # 单位向量
    ux = dx / length
    uy = dy / length
    
    # 虚线模式:实线 + 间隔
    dash_on, dash_off = pattern
    dash_length = dash_on + dash_off
    
    # 绘制虚线
    current = 0
    while current < length:
        # 实线段起点
        dash_start_x = start[0] + ux * current
        dash_start_y = start[1] + uy * current
        
        # 实线段终点
        dash_end = min(current + dash_on, length)
        dash_end_x = start[0] + ux * dash_end
        dash_end_y = start[1] + uy * dash_end
        
        # 绘制实线段(使用新定义的主线条颜色)
        draw.line([(dash_start_x, dash_start_y), 
                  (dash_end_x, dash_end_y)], 
                 fill=main_line_color, width=width)
        
        current += dash_length

# 绘制四条新的连接线
for start, end in new_lines:
    draw_dashed_line(draw, start, end, line_width, dash_pattern)

# 5. 在中间位置画一个小菱形
# 计算小菱形的尺寸:顶点距离顶部大约是1/4的边长的宽度

# 计算大菱形的中心点(图片中心)
center_x = image_size // 2
center_y = image_size // 2

# 大菱形的顶点到中心的垂直距离(上顶点到中心的距离)
large_vertical_distance = image_size // 2

# 小菱形的顶点到中心的垂直距离:1/4边长宽度
small_vertical_distance = image_size // 4  # 1500/4 = 375

# 小菱形的顶点到中心的水平距离(保持菱形形状)
small_horizontal_distance = small_vertical_distance

# 计算小菱形的四个顶点
small_diamond_points = [
    (center_x, center_y - small_vertical_distance),        # 上顶点
    (center_x + small_horizontal_distance, center_y),      # 右顶点
    (center_x, center_y + small_vertical_distance),        # 下顶点
    (center_x - small_horizontal_distance, center_y)       # 左顶点
]

# 先填充小菱形为新定义的灰色(triangle_fill_color = 150,150,150)
draw.polygon(small_diamond_points, fill=triangle_fill_color, outline=None)

# 绘制小菱形边框(使用新定义的小菱形边框颜色)
draw_dashed_polygon(draw, small_diamond_points, line_width, dash_pattern)

# 6. 在小菱形内部绘制点点点(使用新定义的灰点子颜色)
# 使用新定义的点子参数
dot_radius_used = dot_radius  # 5像素
dot_spacing_used = dot_spacing  # 10像素

# 计算小菱形的边界
small_diamond_left = center_x - small_horizontal_distance
small_diamond_right = center_x + small_horizontal_distance
small_diamond_top = center_y - small_vertical_distance
small_diamond_bottom = center_y + small_vertical_distance

# 创建判断点是否在菱形内的函数
def is_point_in_diamond(x, y, center_x, center_y, h_dist, v_dist):
    """判断点(x,y)是否在菱形内"""
    # 菱形的数学方程:|x - center_x|/h_dist + |y - center_y|/v_dist <= 1
    return (abs(x - center_x) / h_dist + abs(y - center_y) / v_dist) <= 1

# 在菱形内均匀绘制点点
for x in range(int(small_diamond_left), int(small_diamond_right), dot_spacing_used):
    for y in range(int(small_diamond_top), int(small_diamond_bottom), dot_spacing_used):
        # 检查点是否在菱形内
        if is_point_in_diamond(x, y, center_x, center_y, small_horizontal_distance, small_vertical_distance):
            # 计算圆点的边界框
            dot_left = x - dot_radius_used
            dot_top = y - dot_radius_used
            dot_right = x + dot_radius_used
            dot_bottom = y + dot_radius_used
            
            # 绘制灰点子(使用新定义的dot_color = 192,192,192)
            draw.ellipse([dot_left, dot_top, dot_right, dot_bottom], fill=dot_color, outline=None)

# 7. 在画布中心位置画一个20磅的黑色圆点(在点点的上面)
center_dot_radius = 10  # 中心圆点的半径
# 计算圆点的边界框
left_bound = center_x - center_dot_radius
top_bound = center_y - center_dot_radius
right_bound = center_x + center_dot_radius
bottom_bound = center_y + center_dot_radius

# 绘制黑色实心圆点(在最上层)
draw.ellipse([left_bound, top_bound, right_bound, bottom_bound], fill=main_line_color, outline=None)


# 显示图片
image.show()
# ========== 仅添加这部分:四个白色矩形 ==========
rect_width = 70
# 1. 左侧矩形:(0,0) 70宽 1500高
draw.rectangle([0, 0, rect_width, image_size], fill='white', outline=None)
# 2. 顶部矩形:(0,0) 1500宽 70高
draw.rectangle([0, 0, image_size, rect_width], fill='white', outline=None)
# 3. 右侧矩形:(1500-70,0) 70宽 1500高
draw.rectangle([image_size - rect_width, 0, image_size, image_size], fill='white', outline=None)
# 4. 底部矩形:(0,1500-70) 1500宽 70高
draw.rectangle([0, image_size - rect_width, image_size, image_size], fill='white', outline=None)
# ========== 矩形绘制结束 ==========

print(f"\n中心圆点信息:")
print(f"  中心坐标: ({center_x}, {center_y})")
print(f"  圆点直径: {center_dot_radius * 2}像素")

print(f"\n小菱形信息:")
print(f"  中心点: ({center_x}, {center_y})")
print(f"  填充颜色: RGB{triangle_fill_color} (新定义的灰色)")
print(f"  顶点到中心垂直距离: {small_vertical_distance}像素")
print(f"  顶点到中心水平距离: {small_horizontal_distance}像素")
print(f"  点点参数: 半径{dot_radius_used}像素, 间距{dot_spacing_used}像素")
print(f"  点点颜色: RGB{dot_color} (新定义的灰点子颜色)")
print(f"  上顶点坐标: {small_diamond_points[0]}")
print(f"  右顶点坐标: {small_diamond_points[1]}")
print(f"  下顶点坐标: {small_diamond_points[2]}")
print(f"  左顶点坐标: {small_diamond_points[3]}")

# 保存图片(使用新定义的输出路径)
image.save(output_path)

print(f"\n已创建图片: {output_path}")
print(f"图片尺寸: {image_size} x {image_size}")
print(f"菱形线宽: {line_width}像素")
print(f"边中点圆点直径: {midpoint_dot_radius * 2}像素")
print(f"中心圆点直径: {center_dot_radius * 2}像素")
print(f"虚线模式: 实线{dash_pattern[0]}像素 + 间隔{dash_pattern[1]}像素")
print(f"小菱形点点: 半径{dot_radius_used}像素, 间距{dot_spacing_used}像素")
print(f"小菱形填充色: RGB{triangle_fill_color}")
print(f"点点颜色: RGB{dot_color}")
python 复制代码
'''
折纸镜子(相框样式)反面3.0(八个小三角,背后是8八边形
Deepseek,豆包,阿夏
20251220
'''
from PIL import Image, ImageDraw
import math

# ===================== 基础配置 =====================
image_size = 1500  # 画布尺寸
line_width = 10    # 线宽
dash_pattern = [20, 10]  # 虚线样式
main_line_color = (0, 0, 0)  # 黑色
small_diamond_color = 'white'  # 小菱形边框
triangle_fill_color = (150, 150, 150)  # 灰色150
dot_color = (192, 192, 192)  # 灰点子颜色
dot_radius = 5  # 点子半径
dot_spacing = 10  # 点子间距
output_path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20251215 手工纸镜子\反面3.0.png'

# ===================== 创建画布 =====================
image = Image.new('RGB', (image_size, image_size), 'white')
draw = ImageDraw.Draw(image)

# 大菱形顶点
center_x, center_y = image_size//2, image_size//2
big_diamond = [
    (center_x, 0),        # 上中点(T)
    (image_size, center_y), # 右中点(R)
    (center_x, image_size),  # 下中点(B)
    (0, center_y)         # 左中点(L)
]

# ===================== 工具函数(不变) =====================
def draw_dashed_polygon(draw, points, width, pattern, color):
    closed_points = points + [points[0]]
    for i in range(len(points)):
        start = closed_points[i]
        end = closed_points[i+1]
        dx = end[0] - start[0]
        dy = end[1] - start[1]
        length = math.hypot(dx, dy)
        if length == 0:
            continue
        ux = dx / length
        uy = dy / length
        dash_on, dash_off = pattern
        dash_length = dash_on + dash_off
        current = 0
        while current < length:
            dash_start = (start[0] + ux * current, start[1] + uy * current)
            dash_end = min(current + dash_on, length)
            dash_end_pos = (start[0] + ux * dash_end, start[1] + uy * dash_end)
            draw.line([dash_start, dash_end_pos], fill=color, width=width)
            current += dash_length

def draw_dashed_line(draw, start, end, width, pattern, color):
    dx = end[0] - start[0]
    dy = end[1] - start[1]
    length = math.hypot(dx, dy)
    if length == 0:
        return
    ux = dx / length
    uy = dy / length
    dash_on, dash_off = pattern
    dash_length = dash_on + dash_off
    current = 0
    while current < length:
        dash_start = (start[0] + ux * current, start[1] + uy * current)
        dash_end = min(current + dash_on, length)
        dash_end_pos = (start[0] + ux * dash_end, start[1] + uy * dash_end)
        draw.line([dash_start, dash_end_pos], fill=color, width=width)
        current += dash_length

def find_line_diamond_intersection(line_start, line_end, diamond_points):
    x1, y1 = line_start
    x2, y2 = line_end
    diamond_edges = [
        (diamond_points[0], diamond_points[1]),
        (diamond_points[1], diamond_points[2]),
        (diamond_points[2], diamond_points[3]),
        (diamond_points[3], diamond_points[0]),
    ]
    intersections = []
    for edge_start, edge_end in diamond_edges:
        x3, y3 = edge_start
        x4, y4 = edge_end
        denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
        if denom == 0:
            continue
        ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom
        ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom
        if 0 <= ua <= 1 and 0 <= ub <= 1:
            x = x1 + ua * (x2 - x1)
            y = y1 + ua * (y2 - y1)
            intersections.append((x, y))
    if intersections:
        distances = [math.hypot(ix - x1, iy - y1) for ix, iy in intersections]
        return intersections[distances.index(min(distances))]
    return None

def line_intersection(line1, line2):
    x1, y1 = line1[0]
    x2, y2 = line1[1]
    x3, y3 = line2[0]
    x4, y4 = line2[1]
    denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
    if denom == 0:
        return None
    ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom
    ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom
    if 0 <= ua <= 1 and 0 <= ub <= 1:
        x = x1 + ua * (x2 - x1)
        y = y1 + ua * (y2 - y1)
        return (x, y)
    return None

def draw_dots_in_triangle(draw, triangle_points):
    x_coords = [p[0] for p in triangle_points]
    y_coords = [p[1] for p in triangle_points]
    min_x, max_x = min(x_coords), max(x_coords)
    min_y, max_y = min(y_coords), max(y_coords)
    
    x = min_x + dot_spacing
    while x <= max_x - dot_spacing:
        y = min_y + dot_spacing
        while y <= max_y - dot_spacing:
            if point_in_triangle((x, y), triangle_points):
                draw.ellipse(
                    [x - dot_radius, y - dot_radius, 
                     x + dot_radius, y + dot_radius],
                    fill=dot_color
                )
            y += dot_spacing
        x += dot_spacing

def point_in_triangle(point, triangle):
    x, y = point
    (x1, y1), (x2, y2), (x3, y3) = triangle
    
    denom = ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3))
    if denom == 0:
        return False
        
    a = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) / denom
    b = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) / denom
    c = 1 - a - b
    
    return 0 <= a <= 1 and 0 <= b <= 1 and 0 <= c <= 1

# ===================== 绘制原有图形(不变) =====================
# 大菱形
draw_dashed_polygon(draw, big_diamond, line_width, dash_pattern, main_line_color)

# 1/4点连接线
quarter_lines = [
    ((image_size//4, 0), (0, image_size//4)),
    ((3*image_size//4, 0), (image_size, image_size//4)),
    ((image_size, 3*image_size//4), (3*image_size//4, image_size)),
    ((image_size//4, image_size), (0, 3*image_size//4)),
]
for start, end in quarter_lines:
    draw_dashed_line(draw, start, end, line_width, dash_pattern, main_line_color)

# 3/8点延伸线
draw_dashed_line(draw, (3*image_size//8, 0), find_line_diamond_intersection((3*image_size//8, 0), (3*image_size//8, image_size), big_diamond), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, (5*image_size//8, 0), find_line_diamond_intersection((5*image_size//8, 0), (5*image_size//8, image_size), big_diamond), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, (image_size, 3*image_size//8), find_line_diamond_intersection((image_size, 3*image_size//8), (0, 3*image_size//8), big_diamond), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, (image_size, 5*image_size//8), find_line_diamond_intersection((image_size, 5*image_size//8), (0, 5*image_size//8), big_diamond), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, (5*image_size//8, image_size), find_line_diamond_intersection((5*image_size//8, image_size), (5*image_size//8, 0), big_diamond), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, (3*image_size//8, image_size), find_line_diamond_intersection((3*image_size//8, image_size), (3*image_size//8, 0), big_diamond), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, (0, 5*image_size//8), find_line_diamond_intersection((0, 5*image_size//8), (image_size, 5*image_size//8), big_diamond), line_width, dash_pattern, main_line_color)
draw_dashed_line(draw, (0, 3*image_size//8), find_line_diamond_intersection((0, 3*image_size//8), (image_size, 3*image_size//8), big_diamond), line_width, dash_pattern, main_line_color)

# ===================== 绘制8个边缘红色区域的灰色带点三角形 =====================
unit = image_size // 8  # 基础单位

# 定义8个边缘小三角(每条大菱形边2个)
final_triangles = [
    # 上边2个
    [(center_x - 2*unit, 0), (center_x - 1*unit, 0), (center_x - unit, unit)],  # 上边左红三角
    [(center_x + 1*unit, 0), (center_x + 2*unit, 0), (center_x + unit, unit)],  # 上边右红三角
    # 右边2个
    [(image_size, center_y - 2*unit), (image_size, center_y-  1*unit), (image_size - unit, center_y - unit)],  # 右边上红三角
    [(image_size, center_y + 1*unit), (image_size, center_y + 2*unit), (image_size - unit, center_y + unit)],  # 右边下红三角
    # 下边2个
    [(center_x - 2*unit, image_size), (center_x - 1*unit, image_size), (center_x - unit, image_size - unit)],  # 下边左红三角
    [(center_x + 1*unit, image_size), (center_x + 2*unit, image_size), (center_x + unit, image_size - unit)],  # 下边右红三角
    # 左边2个
    [(0, center_y - 2*unit), (0, center_y - 1*unit), (unit, center_y - unit)],  # 左边上红三角
    [(0, center_y + 1*unit), (0, center_y + 2*unit), (unit, center_y + unit)]   # 左边下红三角
]

# 绘制8个灰色带点三角
for tri in final_triangles:
    draw.polygon(tri, fill=triangle_fill_color)
    draw_dots_in_triangle(draw, tri)

# ===================== 绘制附件图片中红线位置的黑色虚线(精准计算坐标) =====================
# 核心:计算4段虚线的起止坐标(匹配原图红线)
black_dash_color = main_line_color  # 黑色
black_dash_width = line_width       # 与主线条同宽
black_dash_pattern = dash_pattern   # 与主线条同虚线样式

# 计算4段黑色虚线的坐标
dash_lines = [
    # 1. 上边水平虚线:连接上边两个灰色三角的下方顶点
    (final_triangles[0][2], final_triangles[1][2]),
    # 2. 右边垂直虚线:连接右边两个灰色三角的左侧顶点
    (final_triangles[2][2], final_triangles[3][2]),
    # 3. 下边水平虚线:连接下边两个灰色三角的上方顶点
    (final_triangles[4][2], final_triangles[5][2]),
    # 4. 左边垂直虚线:连接左边两个灰色三角的右侧顶点
    (final_triangles[6][2], final_triangles[7][2]),
]

# 绘制4段黑色虚线
for start, end in dash_lines:
    draw_dashed_line(draw, start, end, black_dash_width, black_dash_pattern, black_dash_color)

# ========== 仅添加这部分:四个白色矩形 ==========
rect_width = 70
# 1. 左侧矩形:(0,0) 70宽 1500高
draw.rectangle([0, 0, rect_width, image_size], fill='white', outline=None)
# 2. 顶部矩形:(0,0) 1500宽 70高
draw.rectangle([0, 0, image_size, rect_width], fill='white', outline=None)
# 3. 右侧矩形:(1500-70,0) 70宽 1500高
draw.rectangle([image_size - rect_width, 0, image_size, image_size], fill='white', outline=None)
# 4. 底部矩形:(0,1500-70) 1500宽 70高
draw.rectangle([0, image_size - rect_width, image_size, image_size], fill='white', outline=None)

# ===================== 保存与输出 =====================
image.save(output_path)
image.show()

# 打印验证信息
print(f"\n已创建图片: {output_path}")
print(f"8个边缘红区三角坐标:")
for i, tri in enumerate(final_triangles, 1):
    print(f"三角{i}: {tri}")
print(f"\n4段黑色虚线坐标:")
for i, (start, end) in enumerate(dash_lines, 1):
    print(f"虚线{i}: 起点{start} → 终点{end}")

图片置于文字下方

明天继续贴神兽图+贴八卦图案

再见2025,希望2026年,全家依旧能够平平安安,健康康康

相关推荐
IT·小灰灰2 小时前
大模型API成本优化实战指南:Token管理的艺术与科学
人工智能·python·数据分析
Amelia1111112 小时前
day41
python
@Luminescence2 小时前
conda指令汇总及入门(持续更新ing)
python·conda
秃了也弱了。2 小时前
python实现离线文字转语音:pyttsx3 库
开发语言·python
可触的未来,发芽的智生2 小时前
2025年终总结:智能涌现的思考→放弃冯诺依曼架构范式,拥抱“约束产生智能”
javascript·人工智能·python·神经网络·程序人生
WoY20202 小时前
conda修改镜像源遇到的问题:defaults(默认镜像源)清不干净导致创建环境失败
linux·python·conda
渡我白衣3 小时前
计算机组成原理(11):加法器
python·机器学习·numpy·pandas·matplotlib·计组·数电
龙腾AI白云3 小时前
深度学习—卷积神经网络(3)
人工智能·python
qq_12498707533 小时前
基于spark的西南天气数据的分析与应用(源码+论文+部署+安装)
大数据·分布式·爬虫·python·spark·毕业设计·数据可视化