Aha! Yes, your function seems much more useful. I would call yours a
"tesselation_hinge" since it tessellates the child object. I can think more
about how to make yours a little more general.
One more comment: I don't think it is a good idea to crop the shape to
constrain it to a rectangle [length, width]. The bounding boxes of shape1
of my code overlaps each other along a row.
If you ar talking about the cropping of my hinge to the outline of the
circle: While I obviously misunderstood what you were asking for, that is
one reason I thought (what I thought was) your proposal was a little odd.
However, I found that while the hinges at the edges do get cut off, causing
edge effects, this can be fixed by increasing the "hinges_across_length".
If for some reason this makes the hinge too rigid, then "d" can be
decreased.
On Fri, Aug 26, 2016 at 11:22 AM, Ronaldo Persiano rcmpersiano@gmail.com
wrote:
One more comment: I don't think it is a good idea to crop the shape to
constrain it to a rectangle [length, width]. The bounding boxes of shape1
of my code overlaps each other along a row.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
I meant it is not a good idea to crop the children inside the hinge module.
It would be users responsibility to define cutting shapes that produce
sensible results.
2016-08-26 12:35 GMT-03:00 Ari Diacou ari.diacou@gmail.com:
If you ar talking about the cropping of my hinge to the outline of the
circle: While I obviously misunderstood what you were asking for, that is
one reason I thought (what I thought was) your proposal was a little odd.
However, I found that while the hinges at the edges do get cut off, causing
edge effects, this can be fixed by increasing the "hinges_across_length".
If for some reason this makes the hinge too rigid, then "d" can be
decreased.
You guys might want to look at a technology called “Industrial Origami”
Just my $0.02,
Jean-Paul
N1JPL
On Aug 26, 2016, at 12:51 PM, Ronaldo Persiano rcmpersiano@gmail.com wrote:
I meant it is not a good idea to crop the children inside the hinge module. It would be users responsibility to define cutting shapes that produce sensible results.
2016-08-26 12:35 GMT-03:00 Ari Diacou ari.diacou@gmail.com:
If you ar talking about the cropping of my hinge to the outline of the circle: While I obviously misunderstood what you were asking for, that is one reason I thought (what I thought was) your proposal was a little odd. However, I found that while the hinges at the edges do get cut off, causing edge effects, this can be fixed by increasing the "hinges_across_length". If for some reason this makes the hinge too rigid, then "d" can be decreased.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Okay, last one ( I think). I have implemented Ronaldo's suggestion to have
a tessellation module that acts on a child object. It can be found at
http://www.thingiverse.com/thing:1745322 or below:
//Living Hinge
//Ari M Diacou
//Metis Industries
//August 2016
//Thanks to Ronaldo Persiano for the inspiration for add_hinge() and
tesselation_hinge()
////Uncomment lines to see Examples (all flat for DXF exporting)
///////////////////////////// Hinge()
///////////////////////////////////////
//hinge();
//hinge(d=6);
//hinge(length=20,
size[0]=39,d=6,hinge_length=2.5,hinges_across_length=2,minimum_thinness=3);
//hinge(length=30,
size[0]=20,d=2,hinge_length=2.5,hinges_across_length=2,minimum_thinness=3,center=true);
//hinge(length=20,
size[0]=40,d=3,hinge_length=4,hinges_across_length=0,minimum_thinness=1);
//linear_extrude(height=5) hinge(length=20,
size[0]=40,d=6,hinge_length=2.5,hinges_across_length=2,minimum_thinness=3);
//////////////////////////// Add_Hinge()
////////////////////////////////////
//add_hinge(size[0]=20,length=size[1],center=true)
square([3*size[1],size[1]-1],center=true);
//add_hinge(size[0]=20,length=90) translate([5,0]) circle(d=90);
//add_hinge(size[0]=30,length=90,hinges_across_length=3) circle(d=90);
//add_hinge(size[0]=30,length=90,hinges_across_length=3,center=false)
circle(d=90);
//add_hinge(size[0]=30,length=90,hinges_across_length=3,minimum_thinness=.1)
circle(d=90);
//////////////////////////// Tesselate()
////////////////////////////////////
//tesselate(num=[3,6], size=[3,2],padding=[.1,.1],type="hex") rotate(30)
circle($fn=6);
//tesselate(num=[3,6], size=[2,1],padding=[.4,.1],type="tri")
translate([-.1,-.1]) text("T",valign="center",halign="center");
//tesselate(num=[6,6], size=[2,.7071],padding=[0.01,.01],type="tri")
translate([0,.25]) rotate(30) circle($fn=3);
//tesselate(num=[8,6], size=[2,1],padding=[.6,.1],type="tri")
translate([-.1,-.1]) rotate(25) text("y",valign="center",halign="center");
//tesselate(num=[6,8], size=[1.5,1],padding=[.6,.1],type="hex")
translate([-.1,-.1]) text("+",valign="center",halign="center");
//////////////////////// Tesselation_Hinge()
////////////////////////////////
tesselation_hinge(num=[6,8], size=[9,6],padding=[.6,.1],type="hex")
translate([-.1,-.1]) text("+",valign="center",halign="center");
//tesselation_hinge(size=[4,5],num=[3,6],padding=[.1,.4],type="hex")
translate([-.8,-.5])square(); //running bond bricks
//tesselation_hinge(size=[4,5],num=[4,5],padding=[.1,.1],type="tri")
translate([0,.28])rotate(30) circle($fn=3);
//tesselation_hinge(size=[4,5],num=[4,5],padding=[.7,.1],type="tri")
translate([-.1,-.1]) rotate(5) text("t",valign="center",halign="center");
//tesselation_hinge(num=[3,6], size=[3,6],padding=[.4,.1],type="tri")
translate([-.1,-.1]) text("T",valign="center",halign="center");
//tesselation_hinge(size=[6,6],num=[6,6],padding=[.2,.2],type="hex")
rotate(30) circle($fn=6);
/////////////////////////////// Functions
/////////////////////////////////////
module
hinge(size=[20,30],d=3,minimum_thinness=3,hinge_length=3,hinges_across_length=2,center=false){
//size[1] = the y dimension of the hinge, parallel to the laser cuts
//size[0] = the x dimension of the hinge, transverse to laser cuts
//d=the distance between parallel laser cuts
//What is the minimum distance that two parallel lines can be apart
before the laser does something catastrophic? E.g. setting uncontrollable
fire to the work piece. This is "minimum_thinness"
//hinge_length=the distance between 2 colinear laser cuts
//hinges_across_length=the number of hinges across the size[1] of the
hinge
//center is a boolean value, if true, place the center of the rectangle
at the origin, if false, put the bottom left corner at the origin (just
like square() and cube())
ep=.00101;//epsilon, a small number,=1.01 micron, a hack (for OpenSCAD
2015.03) used to make square()'s which look like lines (which OpenSCAD
doesn't support). Hopefully, your laser has a function which says something
like "ignore cuts less than THRESHOLD apart", set that to anything greater
than ep.
adjust=center?-[size[0],size[1]]/2:[0,0];//a vector for adjusting the
center position
th=d/2<minimum_thinness?ep:d/2;//If the distance between lines is less
than the minimum thickness, just make linear cuts, specifically, set the
size[0]=th=thickness of the squares to ep, which is just above 1 micron
(for 1=1mm slicers)
n=floor(size[0]/d);
m=floor(abs(hinges_across_length)); echo(str("Number of hinges
(m)=",m)); //input cleaning, ensures m ϵ {non-negative integers}
echo(str("Suggested filename: Living
Hinge-",size[1],"x",size[0],"mm-h=",m,"x",hinge_length,"-th=",th));
echo(str("The distance between parallel laser cuts (d) is: ",d," mm."));
//the size[1] of the short lines
short=(size[1]-mhinge_length)/(m+1);
//the size[1] of the long lines
long=(size[1]-(m+1)hinge_length)/(m);
echo(str("There should be n=",n," links in the hinge."));
translate(adjust) difference(){
square([size[0],size[1]],center=false);
if(m==0)
//In the special case where |hinges_across_length|<1, the hinge
should look like:
// | --------------------------------------|
// |-------------------------------------- |
// | --------------------------------------|
// |-------------------------------------- |
for(i=[0:n])
translate([id,(pow(-1,i))hinge_length]) //
(-1)^i,{iϵZ} = {-1,+1,-1,+1,...}
square([th,size[1]]);
else
//A hinge with hinges_across_length=2 should look like:
// |------------ ------------ ------------|
// | ----------------- ----------------- |
// |------------ ------------ ------------|
// | ----------------- ----------------- |
for(i=[0:n]){ //Iterating across x
translate([id1,0]){ //Do the x translation seperate from
the y translations
if(i%2==1) //For odd columns
for(j=[0:m-1]){
translate([0,hinge_length+j*(long+hinge_length)])
square([th,long]);
}
if(i%2==0) //For even columns
for(j=[0:m]){
translate([0,j*(short+hinge_length)])
square([th,short]);
}
}
}
}
}
module
add_hinge(size=[20,30],d=3,minimum_thinness=3,hinge_length=3,hinges_across_length=2,center=true){
//add_hinge() modifies another 2D object, by adding a hinge which is
centered on the origin (by default, this can be changed to false, so that
the bottom left corner of the hinge is at the origin. It uses the same
parameters as hinge().
//First, difference() a rectangle the size of the hinge from the child
object (makes a hole for the hinge
//Second, union() a hinge with First (puts the hinge in the hole)
//Third, intersection() the child object with Second (cuts off any
extra hinge that sticks out past the child object)
intersection(){
children();
union(){
hinge(size=size,d=d,minimum_thinness=minimum_thinness,hinge_length=hinge_length,hinges_across_length=hinges_across_length,center=center);
difference(){
children();
square([size[0],size[1]],center=center);
}
}
}
}
module tesselate(num=[1,1],size=[1,1],padding=[0,0],type="square"){
//Tesselate acts on a child object, and tesselates it, in a sqaure,
triagular or hexagonal array.
//num is [the number of objects in x, the number of objects in y]
//size is [the size of each "cell" in x, the size of each "cell" in y]
//padding is how much should be subtracted from the "cell" size to get
the object size. This is absolute, not proportional, i.e. padding of .1
means each object is 0.1mm smaller than the cell, not 10% or 90% the size
of the cell.
//type is the type of array. There are exactly 3 types of regular
polyhedron tesselations, square (normal graph paper), hexagonal (hex tiles,
e.g. Civilization 5, or bricks in "running bond"), and triangular (this
particular code uses a 180 degree rotation in z instead of a reflection in
the xz-plane
index =
(type=="h"||type=="hex"||type=="hexagon"||type=="hexagonal") ? 1 :
(type=="t"||type=="tri"||type=="triangle"||type=="triangular") ? 2 :
0;//index converts the text of type into a numbered index. I didn't want to
slow down computation time by having if statements or conditionals, so I
calculate transforamtions for all 3, make an array of them, and then use
index to pick the appropriate one.
sq=[[1,0],[0,1]]; hex=[[1,0],[.5,.75]]; tri=[[.5,0],[0,1]]; //These are
the unit vectors for each of the array types.
Map=[sq,hex,tri][index];
for(j=[0:num[1]-1]) //Iterate in y
for(i=[0:num[0]-1]){ //Iterate in x
translation=[(i+.5)*Map[0]*size[0]+(j+.5)*Map[1]size[1],[(i+.5)(size[0]Map[0][0])+Map[1][0]size[0](j%2),(j+.5)(size[1]*Map[1][1])],(i+.5)*Map[0]*size[0]+(j+.5)*Map[1]size[1]][index];
//What is the vector that describes the position of each object in the
array?
rot=[0,0,180((i+j)%2)][index]; //Only triangular arrays need a
rotation
translate(translation)
rotate(rot)
resize(size-padding)
children();
}
}
module tesselation_hinge(num=[1,1],size=[1,1],padding=[0,0],type="square"){
//Tesselation hinge takes the difference of a square(size) and a
tesselate().
//size as used in this function is the size of the hinge, not the size
of each object (like in tesselate()) the size of the objects are
dynamically adjusted based on num and padding, and of course, the size of
the hinge.
//num, padding and type have all the same meanings as they do in
tesselate().
index =
(type=="h"||type=="hex"||type=="hexagon"||type=="hexagonal") ? 1 :
(type=="t"||type=="tri"||type=="triangle"||type=="triangular") ? 2 : 0;
sq=[[1,0],[0,1]]; hex=[[1,0],[.5,.75]]; tri=[[.5,0],[0,1]];
Map=[sq,hex,tri][index];
//These parameters need to be re-declared because when calling
tesselate(), the size of each object needs to be recalculated based on the
size of each cell. These parameters must be the same in both functions.
difference(){
square(size);
tesselate(num=num,size=[size[0]/num[0]/Map[0][0],size[1]/num[1]/Map[1][1]],padding=padding,type=type)
children();
}
}
On Fri, Aug 26, 2016 at 12:51 PM, Ronaldo Persiano rcmpersiano@gmail.com
wrote:
I meant it is not a good idea to crop the children inside the hinge
module. It would be users responsibility to define cutting shapes that
produce sensible results.
2016-08-26 12:35 GMT-03:00 Ari Diacou ari.diacou@gmail.com:
If you ar talking about the cropping of my hinge to the outline of the
circle: While I obviously misunderstood what you were asking for, that is
one reason I thought (what I thought was) your proposal was a little odd.
However, I found that while the hinges at the edges do get cut off, causing
edge effects, this can be fixed by increasing the "hinges_across_length".
If for some reason this makes the hinge too rigid, then "d" can be
decreased.
Nice work, Ari! And very well documented.
I have been caught by your hinge question. So, I could not wait your
solution and have written mine own. Comparing it with yours I realized that
we have used different tiling (or tesselation) approaches.
http://forum.openscad.org/file/n18295/Hinge_tiling.png
That is my code where I included the above patterns, four of them I found at
ponoko site and two I designed myself. Hope you like it:
living_hinges2.scad
http://forum.openscad.org/file/n18295/living_hinges2.scad
As you can see, I don't make any change to the patterns (children()) except
translation to the tilling position and flipping. The tile dimensions,
arguments of hinge module, may be different from the pattern dimensions so
they are able to overlap like in the "diamonds" above.
I think that the standard hinge pattern (the one you use in your hinge
module) is probably the more adequate to the function. Other patterns may
have some value, like diamonds and bowling pins. The others have more
decorative appeal but they seem to be either fragile or less flexible for a
living hinge. I don't have a laser cutting service nearby to try them.
Any way, it was fun to play with them.
--
View this message in context: http://forum.openscad.org/Living-Hinges-tp18217p18295.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Has this been tried with printed plastic?
Admin - PM me if you need anything, or if I've done something stupid...
Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.
View this message in context: http://forum.openscad.org/Living-Hinges-tp18217p18301.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
On 09-01-2016 11:29 PM, MichaelAtOz wrote:
Has this been tried with printed plastic?
What, living hinges? Yes, I print them in polypropylene. They work
just as well as commercial ones.
- Michele
nice work. I found one hinge design that flexes in both directions. Only
example I found.
its here:
http://lab.kofaktor.hr/en/portfolio/super-flexible-laser-cut-plywood/
--
View this message in context: http://forum.openscad.org/Living-Hinges-tp18217p18303.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Great design, Neon22! I was looking for something like that. Thank you.
At a first look of that design, I saw lots of interlocked swastikas. After
that it reminded me the Hilbert curve.
I coded the pattern for the design and found the hinge() parameters to
reproduce it:
http://forum.openscad.org/file/n18313/koFACTORlab_flex.png
module koFACTORlab_flex(a=20,b,kerf=0.5) {
c = b==undef ? a : b/2;
p = [[-1,2],[-1,4],[1,4],[1,0],[-3,0],
[-3,-4],[1,-4],[1,-2],[-1,-2]
][[a,0],[0,c]]/5;
q = [[0,3],[0,1],[-2,1],[-2,5],[2,5],
[2,9],[-2,9],[-2,7],[0,7]
][[a,0],[0,c]]/5;
for(i=[1:len(p)-1]) line(p[i-1],p[i],kerf);
for(i=[1:len(q)-1]) line(q[i-1],q[i],kerf);
}
size = 20; // each square size
kerf = 0.5;
hinge(horRepeat=5, vertRepeat=3, patWidth=size, patHeight=2*size,
border=20, align=size)
translate([size/8,0]) koFACTORlab_flex(a=size,kerf=kerf);
--
View this message in context: http://forum.openscad.org/Living-Hinges-tp18217p18313.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
This looking very good. Consider this pattern also if you like
http://www.thingiverse.com/thing:304177
--
View this message in context: http://forum.openscad.org/Living-Hinges-tp18217p18333.html
Sent from the OpenSCAD mailing list archive at Nabble.com.