Skip to content

Instantly share code, notes, and snippets.

@creationix
Last active March 31, 2017 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save creationix/683720cf0b72b88651808c0f37a034dc to your computer and use it in GitHub Desktop.
Save creationix/683720cf0b72b88651808c0f37a034dc to your computer and use it in GitHub Desktop.
Pentacoop
-- Use Euclids algorithm to find gcd
-- m and n need to be positive integers, m must be larger.
local function gcd(m, n)
while n > 0 do
m, n = n, m % n
end
return m
end
local precision = 16
-- Given a length in decimal inches, give length in fractional inches to nearest 16th.
local function imperialize(length)
local whole = math.floor(length)
local parts = math.floor((length - whole)*precision+.5);
if parts == 0 then
return string.format('%s"', whole)
else
local d = gcd(precision, parts)
return string.format('%s %s/%s"', whole, parts/d, precision/d)
end
end
local function convert(data)
for a,b,c in data:gmatch("ECHO: \"board\", ([^,]+), (%d+), (%d+)") do
print(string.format("board: %-10s %s-%s", imperialize(tonumber(a)), b, c))
end
end
convert[[
ECHO: "board", 24.495, 29, 29
ECHO: "board", 52.42, 29, 29
ECHO: "board", 80.345, 29, 29
ECHO: "board", 108.27, 29, 29
ECHO: "board", 136.195, 29, 29
ECHO: "board", 144, 32, 29
ECHO: "board", 142.285, 32, 29
]]
module timber(l=8*12) {
linear_extrude(l)
polygon([
[.5,0],[3,0],
[3.5,1.75],
[3,3.5],[.5,3.5],
[0,1.75]]);
}
module timberr(x,y,z,r,o) {
rotate([0,0,r-90])
translate([x,y+o,z])
rotate([90,0,0])
timber(y * 2);
}
module poler(x,y,z,r,o) {
rotate([0,0,r-90])
translate([x,-y+o,z])
#cube([5.5,y*2,3.5]);
}
rr=6*12+4;
// Walls
for(i=[-1:24]) {
for (j=[0:4]) {
x=rr;
z=i*3.5;
r=j*72;
// base of treated 4x6 boards
if (i < 0) {
y=4*12+10.5;
o=0;
poler(x,y,z,r,o);
}
// Main walls
else if (i > 20 || j > 0) {
y=4*12;
o=((i%2)*2-1)*12;
timberr(x,y,z,r,o);
if (i < 8 || j == 0 && i > 20) {
timberr(x,9,z,r,((i%2)*2-1)*-45);
}
}
// Wall around door
else {
y=(i%2)*3+14.25;
o=(i%2)*3+39.75;
timberr(x,y,z,r,o);
y2=((i+1)%2)*3+14.25;
o2=((i+1)%2)*3+39.75;
timberr(x,y2,z,r,-o2);
}
}
}
// Door
translate([-2*12,-rr-3.5,0]) {
// doorway studs
translate([-1.5,0,0])
cube([1.5,5.5,6*12]);
translate([4*12,0,0])
cube([1.5,5.5,6*12]);
// doorway top
translate([-1.5,0,6*12])
cube([4*12+3,5.5,1.5]);
// door vertical
translate([.25,1.5,.25])
cube([5.5,1.5,6*12-.5]);
translate([4*12-5.5-.25,1.5,.25])
cube([5.5,1.5,6*12-.5]);
for(i=[1:10]) {
translate([i*3.65+2.25,1.5,.25])
#cube([3.5,.75,3*12-2]);
}
// door horizontal
translate([.25,0,.5])
cube([4*12-.5,1.5,5.5]);
translate([.25,0,6*12-5.5-.5])
cube([4*12-.5,1.5,5.5]);
translate([.25,0,3*12-3])
cube([4*12-.5,1.5,5.5]);
// door screen
translate([5.5+.25,1.5,3*12-3])
%cube([3*12+1,.1,3*12+2]);
}
// Roof
angle=35;
// Max board length
maxlength=12*12;
// Calculate the biggest triangle we can fit using max length boards
length=min(maxlength, (maxlength+3/cos(angle))/(sin(angle)*2));
spacing=length/round(length/(24/cos(angle)));
module rafter(y) {
w = sin(angle)*y*2-3/cos(angle);
h = cos(angle)*y;
echo("board", w, angle,angle);
inset=tan(angle)*1.5;
translate([-w/2,-h,0])
linear_extrude(5.5)
polygon([
[0,0],
[inset,1.5],
[w-inset,1.5],
[w,0]]);
}
module rooftri() {
for (i=[spacing:spacing:length]) {
rafter(i);
}
X=sin(angle)*length;
Y=cos(angle)*length;
W=1.5/cos(angle);
X2=sin(angle)*W;
Y2=cos(angle)*W;
echo("board",sqrt(X*X+Y*Y),90-angle*2,angle);
linear_extrude(5.5) polygon([
[0,0],
[X,-Y],
[X - W,-Y],
[-X2,-Y2],
]);
echo("board",sqrt((X-X2)*(X-X2)+(Y-Y2)*(Y-Y2)),,90-angle*2,angle);
linear_extrude(5.5) polygon([
[-X2,-Y2],
[0,-2*Y2],
[-X+W,-Y],
[-X,-Y]
]);
}
translate([0,0,23*3.5+30]) {
for (i=[0:4])
rotate([16,0,i*72])
rooftri(length,angle,spacing);
}
angle=35;
// Max board length
maxlength=12*12;
// Calculate the biggest triangle we can fit using max length boards
length=min(maxlength, (maxlength+3/cos(angle))/(sin(angle)*2));
echo("Length", length);
// Calculate spacing to get close to 24" between slats
spacing=length/round(length/(24/cos(angle)));
echo("spacing", spacing);
module rafter(y) {
w = sin(angle)*y*2-3/cos(angle);
h = cos(angle)*y;
echo("board", w, angle,angle);
inset=tan(angle)*1.5;
translate([-w/2,-h,0])
linear_extrude(5.5)
polygon([
[0,0],
[inset,1.5],
[w-inset,1.5],
[w,0]]);
}
for (i=[spacing:spacing:length]) {
rafter(i);
}
X=sin(angle)*length;
Y=cos(angle)*length;
W=1.5/cos(angle);
X2=sin(angle)*W;
Y2=cos(angle)*W;
echo("board",sqrt(X*X+Y*Y),90-angle*2,angle);
linear_extrude(5.5) polygon([
[0,0],
[X,-Y],
[X - W,-Y],
[-X2,-Y2],
]);
echo("board",sqrt((X-X2)*(X-X2)+(Y-Y2)*(Y-Y2)),,90-angle*2,angle);
linear_extrude(5.5) polygon([
[-X2,-Y2],
[0,-2*Y2],
[-X+W,-Y],
[-X,-Y]
]);
@creationix
Copy link
Author

pentacoop

@creationix
Copy link
Author

creationix commented Mar 31, 2017

Output of rafter calculation script (triangles.scad)

The board lines are total length on long-side, left-side cut angle, right-side cut angle.
The spacing is to know how far to space horizontal studs along side rails.

ECHO: "spacing", 28.8
ECHO: "board", 24.495, 29, 29
ECHO: "board", 52.42, 29, 29
ECHO: "board", 80.345, 29, 29
ECHO: "board", 108.27, 29, 29
ECHO: "board", 136.195, 29, 29
ECHO: "board", 144, 32, 29
ECHO: "board", 142.285, 32, 29

@creationix
Copy link
Author

Output of imperial.lua script. This is cut lengths and angles of roof 2x6 boards.

board: 24 1/2"    29-29
board: 52 7/16"   29-29
board: 80 3/8"    29-29
board: 108 1/4"   29-29
board: 136 3/16"  29-29
board: 144"       32-29
board: 142 5/16"  32-29

@creationix
Copy link
Author

The 108 1/4" and 24 1/2" boards can be cut out of the same 12' board.
Same for 52 7/16" and 80 3/8" boards.

This means we need 5 boards per triangle.

@creationix
Copy link
Author

This is the assembly of the triangle (notice it's now only 5 sections, not the 6 in the 3d design)

screenshot from 2017-03-30 22-17-53

@creationix
Copy link
Author

Updated with final roof design tweak. Fixed angle to work for 5-sided roof with minimal rise.

image

image

@creationix
Copy link
Author

Output from openscad...

ECHO: "Length", 128.721
ECHO: "spacing", 32.1802
ECHO: "board", 33.2533, 35, 35
ECHO: "board", 70.1688, 35, 35
ECHO: "board", 107.084, 35, 35
ECHO: "board", 144, 35, 35
ECHO: "board", 128.721, 20, 35
ECHO: "board", 126.89, 20, 35

And imperialized...

board: 33 1/4"    35-35
board: 70 3/16"   35-35
board: 107 1/16"  35-35
board: 144"       35-35
board: 128 3/4"   20-35
board: 126 7/8"   20-35

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment