利用激光切割的高精度,制作出不锈钢或食品级亚克力的镂空模板(Stencil),让即便是新手,也能一键复刻大师级的拿铁艺术。
以下是完整的项目交付文档:
项目名称:LatteArt-Stencil-Gen (咖啡拉花模板生成器)
一、 实际应用场景描述
场景 A(咖啡馆): 早高峰时段,顾客排队焦急,咖啡师却还在小心翼翼地练习“树叶”拉花,成功率不高,导致出杯慢。
场景 B(家庭): 你在家中想给伴侣做一个爱心拿铁,但手腕抖动,画出来的像“抽象派土豆”。
解决方案:
1. 运行本程序,选择预设图案(如郁金香、天鹅、文字)。
2. 程序生成 SVG矢量模板图纸。
3. 使用激光切割机在 0.4mm 不锈钢片 或 食品级PETG 上切割。
4. 实际使用时,将模板平放在奶泡表面,匀速倒入牛奶,提起模板,完美图案瞬间成型。
二、 引入痛点 (Pain Points)
传统手绘拉花或简易模具存在以下问题:
1. 学习曲线陡峭: 需要掌握奶泡打发、手腕抖动频率、流速控制,至少练习半年。
2. 容错率低: 手一抖,几十块的咖啡豆就浪费了。
3. 图案单一: 网上买的通用模具只有心形,无法满足个性化需求(如公司Logo、特定纪念日文字)。
4. 卫生死角: 3D打印模具难清洗,容易滋生细菌。
本方案的解决思路:
利用 参数化矢量绘图算法,生成完全镂空的路径。激光切割出的模板无接触死角,可直接放入洗碗机清洗,且图案边缘锐利,实现“零失败率”拉花。
三、 核心逻辑讲解 (Algorithm Logic)
我们采用 “矢量路径 + 拓扑简化” 算法:
1. 贝塞尔曲线 (Bezier Curve):
- 咖啡拉花的灵魂线条(如郁金香的茎叶)通常是平滑的曲线。
- 数学原理:
"B(t) = (1-t)²P0 + 2(1-t)tP1 + t²P2"。代码中通过控制点(Control Points)来定义曲线形状。
2. 封闭路径检测:
- 激光切割必须是闭合路径。程序会自动检查路径首尾是否相连。
3. 桥接结构 (Bridge):
- 为了让模板不掉进杯子里,需要在图案中间添加“桥”(连接筋)。
- 算法会自动计算图案的几何中心,并生成最短的连接线段。
四、 代码模块化实现 (Core Code)
以下是核心程序
"latte_stencil_generator.py"。
技术栈: Python 3.x + svgwrite (专注于生成干净的SVG路径)。
"""
latte_stencil_generator.py
功能:生成用于激光切割的咖啡拉花模板SVG文件
日期:2026-04-13
"""
import svgwrite
from svgwrite.path import Path
import math
# =========================
# 模块一:配置参数
# =========================
CONFIG = {
"cup_diameter_mm": 90, # 咖啡杯口径
"template_margin_mm": 10, # 模板边缘留白
"line_thickness_mm": 1.5, # 切割线宽(决定镂空缝隙)
"material_thickness_mm": 0.4 # 不锈钢/塑料厚度
}
# =========================
# 模块二:基础图形算法库
# =========================
class LatteArtShapes:
"""
咖啡拉花常用图形的矢量路径生成器
"""
@staticmethod
def heart(center, size):
"""
生成爱心的贝塞尔曲线路径
参数:
center: (x, y) 中心点
size: 缩放比例
"""
path = Path(fill='none', stroke='black', stroke_width=CONFIG["line_thickness_mm"])
cx, cy = center
# 爱心上半部分的两个控制点
top_point = (cx, cy - size * 0.8)
left_ctrl = (cx - size * 0.7, cy - size * 1.5)
right_ctrl = (cx + size * 0.7, cy - size * 1.5)
# 绘制左半边
path.push(f"M {cx},{cy}") # 起点在底部中心
path.push(f"C {left_ctrl[0]},{left_ctrl[1]} {cx-size*0.5},{top_point[1]} {cx},{top_point[1]}")
# 绘制右半边
path.push(f"C {cx+size*0.5},{top_point[1]} {right_ctrl[0]},{right_ctrl[1]} {cx},{cy}")
return path
@staticmethod
def tulip_stem(start_point, length):
"""
生成郁金香的花茎(直线+轻微曲线)
"""
path = Path(fill='none', stroke='black', stroke_width=CONFIG["line_thickness_mm"])
x, y = start_point
end_y = y - length
# 简单的直线茎
path.push(f"M {x},{y}")
path.push(f"L {x},{end_y}")
return path
# =========================
# 模块三:模板框架生成器
# =========================
class StencilFrame:
"""
生成模板的外圈圆环和手柄
"""
def __init__(self, config):
self.cfg = config
self.radius = self.cfg["cup_diameter_mm"] / 2
def create_frame_path(self):
"""
创建一个带缺口的圆环作为模板主体
"""
dwg = svgwrite.Drawing()
outer_radius = self.radius + self.cfg["template_margin_mm"]
inner_radius = self.radius
# 使用两个圆相减的逻辑 (在SVG中通常用clipPath或直接画两个圆)
# 这里我们直接画一个圆环路径
path_data = f"""
M {outer_radius},0
A {outer_radius},{outer_radius} 0 1,1 {outer_radius*math.cos(2*math.pi)},{outer_radius*math.sin(2*math.pi)}
M {inner_radius},0
A {inner_radius},{inner_radius} 0 1,1 {inner_radius*math.cos(2*math.pi)},{inner_radius*math.sin(2*math.pi)}
"""
# 简化写法:直接返回一个圆环对象
return dwg.circle(center=(outer_radius, outer_radius), r=inner_radius,
fill='none', stroke='black', stroke_width=self.cfg["line_thickness_mm"])
# =========================
# 模块四:主程序入口
# =========================
def main():
# 1. 创建SVG画布
canvas_size = CONFIG["cup_diameter_mm"] + CONFIG["template_margin_mm"] * 2
dwg = svgwrite.Drawing(
'latte_stencil.svg',
size=(canvas_size, canvas_size),
viewBox=f'0 0 {canvas_size} {canvas_size}'
)
# 2. 添加外框
frame = StencilFrame(CONFIG)
# 将坐标系移动到中心
group = dwg.g(transform=f"translate({canvas_size/2}, {canvas_size/2})")
group.add(frame.create_frame_path())
# 3. 添加图案 (以爱心为例)
shapes = LatteArtShapes()
heart_path = shapes.heart(center=(0, 0), size=30)
group.add(heart_path)
# 4. 将组合添加到画布
dwg.add(group)
# 5. 保存文件
dwg.save()
print(f"✅ 拉花模板已生成: {dwg.filename}")
print("建议切割材料:304不锈钢箔片 或 食品级PETG")
if __name__ == "__main__":
main()
五、 README.md 文件
# ☕ LatteArt-Stencil-Gen
> 咖啡师/家用神器:激光切割拉花模板生成器
## 🌟 项目简介
厌倦了失败的拉花尝试?本项目使用Python算法生成高精度的咖啡拉花模板(Stencil)图纸。无论是咖啡馆高峰期还是家庭早餐时刻,助你一键成型大师级拿铁艺术。
## 🛠️ 环境依赖
- Python 3.8+
- svgwrite (pip install svgwrite)
## 🚀 快速开始
1. 运行程序
bash
python latte_stencil_generator.py
2. 输出文件
- `latte_stencil.svg`
## 🎨 内置图案
- Heart (爱心)
- Tulip (郁金香 - 开发中)
- Rosetta (蕨叶 - 开发中)
## ⚙️ 自定义
修改 `CONFIG` 字典以适应你的杯子:
python
CONFIG = {
"cup_diameter_mm": 100, # 大杯拿铁
"line_thickness_mm": 1.2, # 细线条更精致
}
六、 使用说明 (User Guide)
Step 1: 选材 (至关重要)
- 首选: 0.3mm - 0.5mm 厚的 304不锈钢片。耐高温、易清洗、食品级安全。
- 次选: 食品级 PETG 或 PP 塑料板。
- 严禁: 普通亚克力(高温可能释放有害物质)、纸张(遇奶泡变软)。
Step 2: 切割设置
- 导入SVG到激光切割软件。
- 功率/速度: 根据材料调整。不锈钢通常需要较高功率(如60W以上光纤激光),塑料则需注意不要烧焦(低速高风)。
- 模式: 仅需 Cut (切割),无需雕刻。
Step 3: 拉花操作
1. 萃取好 Espresso。
2. 打好细腻的奶泡。
3. 将模板平放在咖啡杯口,镂空图案对准液面。
4. 从高处注入牛奶,直到图案填满。
5. 稳、准、快 地垂直提起模板。
6. Done! 🎉
七、 核心知识点卡片 (Flash Cards)
卡片主题 编程/算法概念 咖啡/工艺关联
贝塞尔曲线
"C (x1,y1, x2,y2, x,y)" 拉花中流畅的“摇摆”线条的数学本质
矢量路径 SVG Path 无限放大不失真,保证激光切割边缘光滑
坐标系变换
"translate()" 将绘图原点移到杯口中心,方便计算
参数化设计
"size" 变量 同一个爱心,大杯小杯随意缩放
食品级材料 物理化学属性 代码不管吃,但管“器”,安全第一
八、 总结
作为全栈工程师,我一直在寻找技术与生活情趣的交叉点。
这个拉花模板项目,展示了算法如何赋能传统手艺:
1. 降维打击: 用精确的数学计算(贝塞尔曲线)替代不稳定的肌肉记忆。
2. 标准化复制: 咖啡馆终于可以像生产零件一样,稳定地产出艺术品。
3. 极简主义: 一张薄薄的金属片,承载了代码的美学与咖啡的香气。
下次当你想喝一杯完美的拿铁时,不必苦练十年,只需敲下
"python latte_stencil_generator.py"。这就是技术的浪漫所在。☕✨
利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!