discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

looking for symmetry shortcuts

ED
Ethan Dicks
Mon, Mar 9, 2015 8:15 PM

Hi, All,

I've been working with OpenSCAD for a few years, and as such, I can
get blinded to better ways to do things because I already have some
way to do them.

Case in point.  I want to make a square cover plate and put holes in
each of the corners.  There's a brute force way to just difference()
the plate and the four holes, but is there a "pretty" way to do this?

(crude) code example:

difference() {
cube([100,100,1], center=true);
translate([45, 45, -1])cylinder(r=2, h=2);
translate([45, -45, -1])cylinder(r=2, h=2);
translate([-45, 45, -1])cylinder(r=2, h=2);
translate([-45, -45, -1])cylinder(r=2, h=2);
}

What I'm after is some sort of more elegant structure to replace 4
nearly identical lines of code making one hole each.  For this sort of
thing, it's not hard to do it, but perhaps each "hole" is more
elaborate, requiring more than a simple "cylinder()" call
(counter-sunk, threaded, etc) so I'd rather find a nice way to
describe a hole and iterate over some structure that results in ([X,
Y], [-X, Y], [X, -Y], [-X, -Y]) somehow.

I can think of several ways to tackle this.  What I'm asking for is,
is this a solved problem and is there a "best" way to do this in the
existing framework?

Thanks!

-ethan

Hi, All, I've been working with OpenSCAD for a few years, and as such, I can get blinded to better ways to do things because I already have _some_ way to do them. Case in point. I want to make a square cover plate and put holes in each of the corners. There's a brute force way to just difference() the plate and the four holes, but is there a "pretty" way to do this? (crude) code example: difference() { cube([100,100,1], center=true); translate([45, 45, -1])cylinder(r=2, h=2); translate([45, -45, -1])cylinder(r=2, h=2); translate([-45, 45, -1])cylinder(r=2, h=2); translate([-45, -45, -1])cylinder(r=2, h=2); } What I'm after is some sort of more elegant structure to replace 4 nearly identical lines of code making one hole each. For this sort of thing, it's not hard to do it, but perhaps each "hole" is more elaborate, requiring more than a simple "cylinder()" call (counter-sunk, threaded, etc) so I'd rather find a nice way to describe a hole and iterate over some structure that results in ([X, Y], [-X, Y], [X, -Y], [-X, -Y]) somehow. I can think of several ways to tackle this. What I'm asking for is, is this a solved problem and is there a "best" way to do this in the existing framework? Thanks! -ethan
W
whosawhatsis
Mon, Mar 9, 2015 8:19 PM

for(x = [45, -45], y = [45, -45]) translate([x, y, -1]) cylinder(r=2, h=2);

I also often do it like this, to make it a bit easier to adjust the values symmetrically later:

for(x = [1, -1], y = [1, -1]) translate([x * 45, y * 45, -1]) cylinder(r=2, h=2);

On Monday, March 9, 2015 at 13:15, Ethan Dicks wrote:

Hi, All,

I've been working with OpenSCAD for a few years, and as such, I can
get blinded to better ways to do things because I already have some
way to do them.

Case in point. I want to make a square cover plate and put holes in
each of the corners. There's a brute force way to just difference()
the plate and the four holes, but is there a "pretty" way to do this?

(crude) code example:

difference() {
cube([100,100,1], center=true);
translate([45, 45, -1])cylinder(r=2, h=2);
translate([45, -45, -1])cylinder(r=2, h=2);
translate([-45, 45, -1])cylinder(r=2, h=2);
translate([-45, -45, -1])cylinder(r=2, h=2);
}

What I'm after is some sort of more elegant structure to replace 4
nearly identical lines of code making one hole each. For this sort of
thing, it's not hard to do it, but perhaps each "hole" is more
elaborate, requiring more than a simple "cylinder()" call
(counter-sunk, threaded, etc) so I'd rather find a nice way to
describe a hole and iterate over some structure that results in ([X,
Y], [-X, Y], [X, -Y], [-X, -Y]) somehow.

I can think of several ways to tackle this. What I'm asking for is,
is this a solved problem and is there a "best" way to do this in the
existing framework?

Thanks!

-ethan


OpenSCAD mailing list
Discuss@lists.openscad.org (mailto:Discuss@lists.openscad.org)
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

for(x = [45, -45], y = [45, -45]) translate([x, y, -1]) cylinder(r=2, h=2); I also often do it like this, to make it a bit easier to adjust the values symmetrically later: for(x = [1, -1], y = [1, -1]) translate([x * 45, y * 45, -1]) cylinder(r=2, h=2); On Monday, March 9, 2015 at 13:15, Ethan Dicks wrote: > Hi, All, > > I've been working with OpenSCAD for a few years, and as such, I can > get blinded to better ways to do things because I already have _some_ > way to do them. > > Case in point. I want to make a square cover plate and put holes in > each of the corners. There's a brute force way to just difference() > the plate and the four holes, but is there a "pretty" way to do this? > > (crude) code example: > > difference() { > cube([100,100,1], center=true); > translate([45, 45, -1])cylinder(r=2, h=2); > translate([45, -45, -1])cylinder(r=2, h=2); > translate([-45, 45, -1])cylinder(r=2, h=2); > translate([-45, -45, -1])cylinder(r=2, h=2); > } > > What I'm after is some sort of more elegant structure to replace 4 > nearly identical lines of code making one hole each. For this sort of > thing, it's not hard to do it, but perhaps each "hole" is more > elaborate, requiring more than a simple "cylinder()" call > (counter-sunk, threaded, etc) so I'd rather find a nice way to > describe a hole and iterate over some structure that results in ([X, > Y], [-X, Y], [X, -Y], [-X, -Y]) somehow. > > I can think of several ways to tackle this. What I'm asking for is, > is this a solved problem and is there a "best" way to do this in the > existing framework? > > Thanks! > > -ethan > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org (mailto:Discuss@lists.openscad.org) > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
AP
Andrew Plumb
Mon, Mar 9, 2015 8:21 PM

Assuming symmetry about the origin, mirror() should do the trick:

http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#mirror http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#mirror

difference() {
cube([100,100,1], center=true);
for(mx=[0:1],my=[0:1]) mirror([mx,my,0]) translate([45, 45, -1]) cylinder(r=2, h=2);
}

Andrew.

On Mar 9, 2015, at 4:15 PM, Ethan Dicks ethan.dicks@gmail.com wrote:

Hi, All,

I've been working with OpenSCAD for a few years, and as such, I can
get blinded to better ways to do things because I already have some
way to do them.

Case in point.  I want to make a square cover plate and put holes in
each of the corners.  There's a brute force way to just difference()
the plate and the four holes, but is there a "pretty" way to do this?

(crude) code example:

difference() {
cube([100,100,1], center=true);
translate([45, 45, -1])cylinder(r=2, h=2);
translate([45, -45, -1])cylinder(r=2, h=2);
translate([-45, 45, -1])cylinder(r=2, h=2);
translate([-45, -45, -1])cylinder(r=2, h=2);
}

What I'm after is some sort of more elegant structure to replace 4
nearly identical lines of code making one hole each.  For this sort of
thing, it's not hard to do it, but perhaps each "hole" is more
elaborate, requiring more than a simple "cylinder()" call
(counter-sunk, threaded, etc) so I'd rather find a nice way to
describe a hole and iterate over some structure that results in ([X,
Y], [-X, Y], [X, -Y], [-X, -Y]) somehow.

I can think of several ways to tackle this.  What I'm asking for is,
is this a solved problem and is there a "best" way to do this in the
existing framework?

Thanks!

-ethan


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Assuming symmetry about the origin, mirror() should do the trick: http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#mirror <http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#mirror> difference() { cube([100,100,1], center=true); for(mx=[0:1],my=[0:1]) mirror([mx,my,0]) translate([45, 45, -1]) cylinder(r=2, h=2); } Andrew. > On Mar 9, 2015, at 4:15 PM, Ethan Dicks <ethan.dicks@gmail.com> wrote: > > Hi, All, > > I've been working with OpenSCAD for a few years, and as such, I can > get blinded to better ways to do things because I already have _some_ > way to do them. > > Case in point. I want to make a square cover plate and put holes in > each of the corners. There's a brute force way to just difference() > the plate and the four holes, but is there a "pretty" way to do this? > > (crude) code example: > > difference() { > cube([100,100,1], center=true); > translate([45, 45, -1])cylinder(r=2, h=2); > translate([45, -45, -1])cylinder(r=2, h=2); > translate([-45, 45, -1])cylinder(r=2, h=2); > translate([-45, -45, -1])cylinder(r=2, h=2); > } > > What I'm after is some sort of more elegant structure to replace 4 > nearly identical lines of code making one hole each. For this sort of > thing, it's not hard to do it, but perhaps each "hole" is more > elaborate, requiring more than a simple "cylinder()" call > (counter-sunk, threaded, etc) so I'd rather find a nice way to > describe a hole and iterate over some structure that results in ([X, > Y], [-X, Y], [X, -Y], [-X, -Y]) somehow. > > I can think of several ways to tackle this. What I'm asking for is, > is this a solved problem and is there a "best" way to do this in the > existing framework? > > Thanks! > > -ethan > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
AP
Andrew Plumb
Mon, Mar 9, 2015 8:25 PM

…and of course it goes (almost) without saying that you don’t want to use mirror for threaded structures. :-)

For more complex structures and placements, consider wrapping them in a “child placer” module definition, to decouple the shape from the placement.

Andrew.

On Mar 9, 2015, at 4:21 PM, Andrew Plumb andrew@plumb.org wrote:

Assuming symmetry about the origin, mirror() should do the trick:

http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#mirror http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#mirror

difference() {
cube([100,100,1], center=true);
for(mx=[0:1],my=[0:1]) mirror([mx,my,0]) translate([45, 45, -1]) cylinder(r=2, h=2);
}

Andrew.

On Mar 9, 2015, at 4:15 PM, Ethan Dicks <ethan.dicks@gmail.com mailto:ethan.dicks@gmail.com> wrote:

Hi, All,

I've been working with OpenSCAD for a few years, and as such, I can
get blinded to better ways to do things because I already have some
way to do them.

Case in point.  I want to make a square cover plate and put holes in
each of the corners.  There's a brute force way to just difference()
the plate and the four holes, but is there a "pretty" way to do this?

(crude) code example:

difference() {
cube([100,100,1], center=true);
translate([45, 45, -1])cylinder(r=2, h=2);
translate([45, -45, -1])cylinder(r=2, h=2);
translate([-45, 45, -1])cylinder(r=2, h=2);
translate([-45, -45, -1])cylinder(r=2, h=2);
}

What I'm after is some sort of more elegant structure to replace 4
nearly identical lines of code making one hole each.  For this sort of
thing, it's not hard to do it, but perhaps each "hole" is more
elaborate, requiring more than a simple "cylinder()" call
(counter-sunk, threaded, etc) so I'd rather find a nice way to
describe a hole and iterate over some structure that results in ([X,
Y], [-X, Y], [X, -Y], [-X, -Y]) somehow.

I can think of several ways to tackle this.  What I'm asking for is,
is this a solved problem and is there a "best" way to do this in the
existing framework?

Thanks!

-ethan


OpenSCAD mailing list
Discuss@lists.openscad.org mailto:Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

…and of course it goes (almost) without saying that you don’t want to use mirror for threaded structures. :-) For more complex structures and placements, consider wrapping them in a “child placer” module definition, to decouple the shape from the placement. Andrew. > On Mar 9, 2015, at 4:21 PM, Andrew Plumb <andrew@plumb.org> wrote: > > Assuming symmetry about the origin, mirror() should do the trick: > > http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#mirror <http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#mirror> > > difference() { > cube([100,100,1], center=true); > for(mx=[0:1],my=[0:1]) mirror([mx,my,0]) translate([45, 45, -1]) cylinder(r=2, h=2); > } > > Andrew. > >> On Mar 9, 2015, at 4:15 PM, Ethan Dicks <ethan.dicks@gmail.com <mailto:ethan.dicks@gmail.com>> wrote: >> >> Hi, All, >> >> I've been working with OpenSCAD for a few years, and as such, I can >> get blinded to better ways to do things because I already have _some_ >> way to do them. >> >> Case in point. I want to make a square cover plate and put holes in >> each of the corners. There's a brute force way to just difference() >> the plate and the four holes, but is there a "pretty" way to do this? >> >> (crude) code example: >> >> difference() { >> cube([100,100,1], center=true); >> translate([45, 45, -1])cylinder(r=2, h=2); >> translate([45, -45, -1])cylinder(r=2, h=2); >> translate([-45, 45, -1])cylinder(r=2, h=2); >> translate([-45, -45, -1])cylinder(r=2, h=2); >> } >> >> What I'm after is some sort of more elegant structure to replace 4 >> nearly identical lines of code making one hole each. For this sort of >> thing, it's not hard to do it, but perhaps each "hole" is more >> elaborate, requiring more than a simple "cylinder()" call >> (counter-sunk, threaded, etc) so I'd rather find a nice way to >> describe a hole and iterate over some structure that results in ([X, >> Y], [-X, Y], [X, -Y], [-X, -Y]) somehow. >> >> I can think of several ways to tackle this. What I'm asking for is, >> is this a solved problem and is there a "best" way to do this in the >> existing framework? >> >> Thanks! >> >> -ethan >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org <mailto:Discuss@lists.openscad.org> >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
ED
Ethan Dicks
Mon, Mar 9, 2015 8:49 PM

On Mon, Mar 9, 2015 at 4:19 PM, whosawhatsis whosawhatsis@gmail.com wrote:

for(x = [45, -45], y = [45, -45]) translate([x, y, -1]) cylinder(r=2, h=2);

Now that you shared this, I see it everywhere (including several times
in library code I was already calling!)

I also often do it like this, to make it a bit easier to adjust the values
symmetrically later:

for(x = [1, -1], y = [1, -1]) translate([x * 45, y * 45, -1]) cylinder(r=2,
h=2);

I'm now trying to figure out which form is "more elegant" to me.

The first example puts the complexity in the "for" expression, and the
second example pushes it down a level.

I appreciate all the suggestions.  Once I have the part modeled (for
eventual fabrication and casting in aluminum) and the results are
unveiled to the recipient, I want the code to be pretty enough to
share, so the quality matters to me.

Cheers,

-ethan

On Mon, Mar 9, 2015 at 4:19 PM, whosawhatsis <whosawhatsis@gmail.com> wrote: > for(x = [45, -45], y = [45, -45]) translate([x, y, -1]) cylinder(r=2, h=2); Now that you shared this, I see it everywhere (including several times in library code I was already calling!) > I also often do it like this, to make it a bit easier to adjust the values > symmetrically later: > > for(x = [1, -1], y = [1, -1]) translate([x * 45, y * 45, -1]) cylinder(r=2, > h=2); I'm now trying to figure out which form is "more elegant" to me. The first example puts the complexity in the "for" expression, and the second example pushes it down a level. I appreciate all the suggestions. Once I have the part modeled (for eventual fabrication and casting in aluminum) and the results are unveiled to the recipient, I want the code to be pretty enough to share, so the quality matters to me. Cheers, -ethan
EN
Ed Nisley
Mon, Mar 9, 2015 10:21 PM

On 03/09/2015 04:49 PM, Ethan Dicks wrote:

The first example puts the complexity in the "for" expression,
and the second example pushes it down a level.

Even though it marks me as old school, I generally separate iteration
and calculation:

  • loop constructs use integer operands and simple logic
  • operations in the loop calculate coordinates / rotations

That way, even I can figure out what the loop will do and, when I
inevitably change the coordinates, I don't screw up the loop logic.

Which is why they don't let me use list comprehension... [grin]

--
Ed
softsolder.com

On 03/09/2015 04:49 PM, Ethan Dicks wrote: > The first example puts the complexity in the "for" expression, > and the second example pushes it down a level. Even though it marks me as old school, I generally separate iteration and calculation: - loop constructs use integer operands and simple logic - operations in the loop calculate coordinates / rotations That way, even I can figure out what the loop will do and, when I inevitably change the coordinates, I don't screw up the loop logic. Which is why they don't let me use list comprehension... [grin] -- Ed softsolder.com
H
hagen
Tue, Mar 10, 2015 9:34 PM

the child placer code (without for loop) could be something like:

module corners(o)
{
translate([o, o, -1]) children(0);
translate([o, -o, -1]) children(0);
translate([-o, o, -1]) children(0);
translate([-o, -o, -1]) children(0);
}

difference() {
cube([100,100,1], center=true);
corners(45) cylinder(r=2, h=2);
}

--
View this message in context: http://forum.openscad.org/looking-for-symmetry-shortcuts-tp11950p11960.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

the child placer code (without for loop) could be something like: module corners(o) { translate([o, o, -1]) children(0); translate([o, -o, -1]) children(0); translate([-o, o, -1]) children(0); translate([-o, -o, -1]) children(0); } difference() { cube([100,100,1], center=true); corners(45) cylinder(r=2, h=2); } -- View this message in context: http://forum.openscad.org/looking-for-symmetry-shortcuts-tp11950p11960.html Sent from the OpenSCAD mailing list archive at Nabble.com.
JC
JinHwan Choi
Wed, Mar 11, 2015 9:53 AM

Relativity library provides neat functions wrapping for loop and translations.
below codes do the same thing with relativity.scad included.

difference() {
cube([100,100,1], center=true);
rotated(90*z,[0:3]) translate([45,45,-1]) cylinder(r=2,h=2);
}

difference() {
cube([100,100,1], center=true);
mirrored(x) mirrored(y) translate([45,45,-1]) cylinder(r=2,h=2);
}

More informations here.
https://github.com/davidson16807/relativity.scad

2015-03-11 6:34 GMT+09:00 hagen temp4pieter@hotmail.com:

the child placer code (without for loop) could be something like:

module corners(o)
{
translate([o, o, -1]) children(0);
translate([o, -o, -1]) children(0);
translate([-o, o, -1]) children(0);
translate([-o, -o, -1]) children(0);
}

difference() {
cube([100,100,1], center=true);
corners(45) cylinder(r=2, h=2);
}

--
View this message in context: http://forum.openscad.org/looking-for-symmetry-shortcuts-tp11950p11960.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Relativity library provides neat functions wrapping for loop and translations. below codes do the same thing with relativity.scad included. difference() { cube([100,100,1], center=true); rotated(90*z,[0:3]) translate([45,45,-1]) cylinder(r=2,h=2); } difference() { cube([100,100,1], center=true); mirrored(x) mirrored(y) translate([45,45,-1]) cylinder(r=2,h=2); } More informations here. https://github.com/davidson16807/relativity.scad 2015-03-11 6:34 GMT+09:00 hagen <temp4pieter@hotmail.com>: > the child placer code (without for loop) could be something like: > > module corners(o) > { > translate([o, o, -1]) children(0); > translate([o, -o, -1]) children(0); > translate([-o, o, -1]) children(0); > translate([-o, -o, -1]) children(0); > } > > difference() { > cube([100,100,1], center=true); > corners(45) cylinder(r=2, h=2); > } > > > > -- > View this message in context: http://forum.openscad.org/looking-for-symmetry-shortcuts-tp11950p11960.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org