sousvideTy.frink

View or download 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]
}


View or download 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 17927 days, 19 hours, 56 minutes ago.