Download or view sousvideTy.frink in plain text format
// This renders engineering templates for my sous vide cooker.
// All shapes print out at their designated sizes, so making
// engineering diagrams is easy. These templates were printed and
// rubber-cemented onto a steel project box and cut out with a drill
// and a nibble-notch tool, which are actually the other handyman's secret
// weapons.
//
// Now if Frink could only control a computerized milling machine.
// Which, I guess, I'd have to have it build first.
boxwidth = 218 mm
boxdepth = 156 mm
g = new graphics
g.stroke[.2 mm]
// PID controller
cy = 88 mm
cx = boxwidth / 2
g.drawRectCenter[cx, cy, 45 mm, 45 mm]
drawCross[g, cx, cy]
g.font["SansSerif", 3 mm]
g.text["PID Controller", cx, cy + 1 cm]
// Top of box outline
g.drawRectSides[0 mm, 0 mm, boxwidth, boxdepth]
// Switches
cy = 18 mm + 19 mm / 2
drawSwitch[g, cx - 4 cm, cy, "Main", "Switch"]
drawSwitch[g, cx + 0 cm, cy, "Heater", "Engage"]
drawSwitch[g, cx + 4 cm, cy, "Pump", "Engage"]
// Heat sink
cx = 6 cm
cy = -6 cm
g.drawRectCenter[cx, cy, 5 cm, 8 cm]
g.drawRectCenter[cx, cy, 5 cm, 56 mm]
g.text["Heat Sink", cx, cy+.5 cm]
drawCross[g,cx,cy]
drawCross[g, cx, cy - 7/2 cm]
drawCross[g, cx, cy + 7/2 cm]
// Fan (approx 3 cm left of heat sink)
cx = cx - 3 cm - 2.5 cm + 2.5 cm / 2
g.drawRectCenter[cx, cy, 2.5 cm, 6 cm]
drawCross[g,cx,cy]
g.text["Fan", cx, cy+5 mm]
// Fan (drill pattern)
cx = 130 mm
g.drawRectCenter[cx, cy, 6 cm, 6 cm]
g.drawRectCenter[cx, cy, 5.62 cm, 5.62 cm]
drawCircleWithCross[g, cx, cy, 60 mm]
drawCircleWithCross[g, cx-2.5 cm, cy-2.5 cm, 3 mm]
drawCircleWithCross[g, cx+2.5 cm, cy-2.5 cm, 3 mm]
drawCircleWithCross[g, cx-2.5 cm, cy+2.5 cm, 3 mm]
drawCircleWithCross[g, cx+2.5 cm, cy+2.5 cm, 3 mm]
g.text["Fan (drill pattern)", cx, cy+.5 cm]
vertSpace = 1.4 cm // Space between center of bottom holes and base of box
boxBaseY = cy + 2.5 cm + vertSpace
g.line[cx-4 cm, boxBaseY, cx+4 cm, boxBaseY]
g.text["Bottom of box", cx, boxBaseY, "center", "bottom"]
// Outlet
cy = -12 cm
cx = 12.5 cm
g.color[.7, .7, .7]
g.drawRectCenter[cx, cy, 26 mm, 22 mm] // General guide rectangle
g.color[0,0,0]
p = new polygon
top = cy - (22 mm / 2)
p.addPoint[cx - (19 mm / 2), top]
p.addPoint[cx + (19 mm / 2), top]
step1y = top + 5.75 mm // Y-coord of 5.75 mm step
p.addPoint[cx + (19 mm / 2), step1y]
p.addPoint[cx + (26 mm / 2), step1y]
step2y = step1y + 10.6 mm
p.addPoint[cx + (26 mm / 2), step2y]
p.addPoint[cx + (9.1 mm / 2), step2y]
bottom = top + 22 mm
p.addPoint[cx + (9.1 mm / 2), bottom]
p.addPoint[cx - (9.1 mm / 2), bottom]
p.addPoint[cx - (9.1 mm / 2), step2y]
p.addPoint[cx - (26 mm / 2), step2y]
p.addPoint[cx - (26 mm / 2), step1y]
p.addPoint[cx - (19 mm / 2), step1y]
p.addPoint[cx - (19 mm / 2), top]
g.add[p]
g.text["Outlet", cx, cy]
// Inlet
cy = -12 cm
cx = 2.5 cm
drawRoundedRectangle[g, cx, cy, 27.4 mm, 19.8 mm, 5.0 mm]
d = 3.4mm
drawCircleWithCross[g, cx+20 mm, cy, d]
drawCircleWithCross[g, cx-20 mm, cy, d]
g.text["Inlet", cx, cy]
// Circuit breaker
cx = cx + 5 cm
g.color[.7,.7,.7]
g.saveTransform[]
g.rotate[90 degrees, cx,cy]
drawCircleWithCross[g, cx, cy, 16 mm]
g.color[0,0,0]
r = 16 mm / 2
ry = 14 mm / 2
rx = sqrt[r^2 - ry^2]
arclen = 2 arcsin[ry/r]
gp = new GeneralPath
gp.moveTo[cx-rx, cy-ry]
gp.lineTo[cx+rx, cy-ry]
gp.circularArc[cx, cy, -arclen]
gp.lineTo[cx-rx, cy+ry]
gp.circularArc[cx, cy, -arclen]
g.add[gp]
g.restoreTransform[]
g.text["Circuit Breaker", cx, cy + 1 cm]
// 12 V jack
cx = cx + 8 cm
drawCircleWithCross[g, cx, cy, 2.5 mm]
drawCircleWithCross[g, cx + 3.6 mm + 9.6 mm + 2.7 mm, cy, 2.5 mm]
g.drawRectCenter[cx + 15.9 mm / 2, cy, 11.5 mm, 9.0 mm]
g.text["12 V Jack", cx + 15.9 mm / 2, cy + 1 cm]
g.show[]
g.write["sousvide.svg", 8.5 in, 11 in]
//g.write["sousvide.html", 800, 800]
//g.browse["sousvide.html"]
drawSwitch[g is graphics, cx, cy, text1="", text2=""] :=
{
g.drawRectSides[cx-11mm, cy-1.1mm, cx-10.1mm, cy+1.1 mm]
r = 20.2 mm / 2
// drawCircleWithCross[g, cx, cy, 2r]
ry = 19.0 mm / 2
rx = sqrt[r^2 - ry^2]
bigarclen = 2 arcsin[ry/r]
rx2 = 4.2 mm / 2
ry2 = sqrt[r^2 - rx2^2]
smallarclen = 2 arcsin[rx2/r]
gp = new GeneralPath
gp.moveTo[cx + rx, cy - ry]
gp.circularArc[cx, cy, -bigarclen]
gp.lineTo[cx + rx2, cy + ry]
gp.lineTo[cx + rx2, cy + ry2]
gp.circularArc[cx, cy, -smallarclen]
gp.lineTo[cx - rx2, cy + ry]
gp.lineTo[cx - rx, cy + ry]
gp.circularArc[cx, cy, -bigarclen]
gp.lineTo[cx - rx2, cy - ry]
gp.lineTo[cx - rx2, cy - ry2]
gp.circularArc[cx, cy, -smallarclen]
gp.lineTo[cx + rx2, cy - ry]
gp.lineTo[cx + rx, cy - ry]
g.add[gp]
g.text[text1, cx, cy-.5 cm]
g.text[text2, cx, cy+.5 cm]
}
drawCross[g is graphics, cx, cy] :=
{
g.line[cx-2 mm, cy, cx+2mm, cy]
g.line[cx, cy-2mm, cx, cy+2mm]
}
drawCircleWithCross[g is graphics, cx, cy, diameter] :=
{
drawCross[g, cx, cy]
g.drawEllipseCenter[cx, cy, diameter, diameter]
}
drawRoundedRectangle[g is graphics, cx, cy, width, height, r] :=
{
hw = width/2
hh = height/2
cxr = cx+hw-r
cxl = cx-hw+r
cyb = cy+hh-r
cyt = cy-hh+r
left = cx - hw
right = cx + hw
top = cy - hh
bottom = cy + hh
// Draw curved area to cut out in gray
g.color[0.7,0.7,0.7]
gp = new filledGeneralPath
gp.moveTo[cxl, top]
gp.lineTo[cxr, top]
gp.circularArc[cxr,cyt,-90 deg]
gp.lineTo[right, cyb]
gp.circularArc[cxr,cyb,-90 deg]
gp.lineTo[cxl, bottom]
gp.circularArc[cxl, cyb, -90 deg]
gp.lineTo[left,cyt]
gp.circularArc[cxl,cyt,-90 deg]
gp.close[]
g.add[gp]
g.color[0.7,0.7,0.7]
g.drawRectCenter[cx,cy,width,height]
g.color[0,0,0]
g.drawEllipseCenter[cxl,cyt,2r,2r]
drawCross[g,cxl,cyt]
g.drawEllipseCenter[cxr,cyt,2r,2r]
drawCross[g,cxr,cyt]
g.drawEllipseCenter[cxl,cyb,2r,2r]
drawCross[g,cxl,cyb]
g.drawEllipseCenter[cxr,cyb,2r,2r]
drawCross[g,cxr,cyb]
g.line[cxr + r, cyt, cxr + r, cyb]
g.line[cxl - r, cyt, cxl - r, cyb]
g.line[cxl, cyt - r, cxr, cyt - r]
g.line[cxl, cyb + r, cxr, cyb + r]
}
Download or view sousvideTy.frink in plain text format
This is a program written in the programming language Frink.
For more information, view the Frink
Documentation or see More Sample Frink Programs.
Alan Eliasen was born 20218 days, 0 hours, 14 minutes ago.