Rotating objects by exactly 180 degrees

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Rotating objects by exactly 180 degrees

Tom Cook
Hi,

I'm fairly new to OpenSCAD, so sorry if this is a well-known effect, but I can't find any reference to it in an admittedly brief googling session.

The rotate() modifier doesn't quite do what I expect in some fairly obvious cases.  The most obvious is that rotate([0, 180, 0]) doesn't produce rotation by exactly 180 degrees.  It's easiest to see in a simple script like this:

difference() {
    cube([100,100,100], center=true);
    cube([100,100,100], center=true);
}

translate([200, 0, 0])
  difference() {
    cube([100,100,100], center=true);
    rotate([0, 180, 0]) cube([100,100,100], center=true);
}

The first difference produces empty space because the two cubes exactly coincide.  The two cubes in the second difference should also coincide exactly and produce empty space, but the rotation is not quite exact and you end up with four polygons, each half of one side of the cube.

I can take a fair guess at why this happens - I suppose there is a conversion to radians going on, and probably the sine and cosine of the angle are being taken, before the angle is passed on to the underlying (OpenGL?) engine, and there is limited precision etc etc.

It is really annoying though.  I want to trim a cube so that it is rotationally symmetric about its centre.  The obvious way of doing this is to write a module that constructs the trim shape, then use code like this:

difference() {
  cube([len, size, size] center=true);
  translate([len/2, 0, 0]) trimShape(size);
  rotate([0, 180, 0]) translate([len/2, 0, 0]) trimShape(size);
}

But that leaves me with stray fragments because the rotation doesn't quite produce a 180 degree rotation.

Is this a known problem?  Is there a known way to work around it?

Thanks,
Tom
Reply | Threaded
Open this post in threaded view
|

Re: Rotating objects by exactly 180 degrees

Peter Falke
Hi,

I always substract something a little larger than my object to avoid problems like this.
I use the parameter e=0.02 for this:

a=100;

e=0.02;


difference(){

cube([a,a,a],true);

translate([0,0,a/2])cube([a+e,a+e,a],true);

}



Hope it helps,

TateItAndRun

On 26 March 2013 13:08, Tom Cook <[hidden email]> wrote:
Hi,

I'm fairly new to OpenSCAD, so sorry if this is a well-known effect, but I can't find any reference to it in an admittedly brief googling session.

The rotate() modifier doesn't quite do what I expect in some fairly obvious cases.  The most obvious is that rotate([0, 180, 0]) doesn't produce rotation by exactly 180 degrees.  It's easiest to see in a simple script like this:

difference() {
    cube([100,100,100], center=true);
    cube([100,100,100], center=true);
}

translate([200, 0, 0])
  difference() {
    cube([100,100,100], center=true);
    rotate([0, 180, 0]) cube([100,100,100], center=true);
}

The first difference produces empty space because the two cubes exactly coincide.  The two cubes in the second difference should also coincide exactly and produce empty space, but the rotation is not quite exact and you end up with four polygons, each half of one side of the cube.

I can take a fair guess at why this happens - I suppose there is a conversion to radians going on, and probably the sine and cosine of the angle are being taken, before the angle is passed on to the underlying (OpenGL?) engine, and there is limited precision etc etc.

It is really annoying though.  I want to trim a cube so that it is rotationally symmetric about its centre.  The obvious way of doing this is to write a module that constructs the trim shape, then use code like this:

difference() {
  cube([len, size, size] center=true);
  translate([len/2, 0, 0]) trimShape(size);
  rotate([0, 180, 0]) translate([len/2, 0, 0]) trimShape(size);
}

But that leaves me with stray fragments because the rotation doesn't quite produce a 180 degree rotation.

Is this a known problem?  Is there a known way to work around it?

Thanks,
Tom

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566



--
[hidden email]

P.S. Falls meine E-Mail kürzer ausfällt als Dir angenehm ist:
Ich probiere gerade aus kurze Antworten statt gar keine Antworten zu schreiben.
Wenn Du gerne mehr lesen möchtest, dann lass es mich bitte wissen.

P.S. In case my e-mail is shorter than you enjoy:
I am currently trying short replies instead of no replies at all.
Please let me know, if you like to read more.

Enjoy!
Reply | Threaded
Open this post in threaded view
|

Re: Rotating objects by exactly 180 degrees

donbright
In reply to this post by Tom Cook
Very interesting. IMHO the issue is inside the geometry engine, not an
OpenGL artifact. Your test code produces four "flat" inner volumes
that can be exported to an OFF file or STL file. I am a bit surprised
it doesn't throw a CGAL error. . . .

-DB


On Tue, Mar 26, 2013 at 7:08 AM, Tom Cook <[hidden email]> wrote:

> Hi,
>
> I'm fairly new to OpenSCAD, so sorry if this is a well-known effect, but I
> can't find any reference to it in an admittedly brief googling session.
>
> The rotate() modifier doesn't quite do what I expect in some fairly obvious
> cases.  The most obvious is that rotate([0, 180, 0]) doesn't produce
> rotation by exactly 180 degrees.  It's easiest to see in a simple script
> like this:
>
> difference() {
>     cube([100,100,100], center=true);
>     cube([100,100,100], center=true);
> }
>
> translate([200, 0, 0])
>   difference() {
>     cube([100,100,100], center=true);
>     rotate([0, 180, 0]) cube([100,100,100], center=true);
> }
>
> The first difference produces empty space because the two cubes exactly
> coincide.  The two cubes in the second difference should also coincide
> exactly and produce empty space, but the rotation is not quite exact and you
> end up with four polygons, each half of one side of the cube.
>
> I can take a fair guess at why this happens - I suppose there is a
> conversion to radians going on, and probably the sine and cosine of the
> angle are being taken, before the angle is passed on to the underlying
> (OpenGL?) engine, and there is limited precision etc etc.
>
> It is really annoying though.  I want to trim a cube so that it is
> rotationally symmetric about its centre.  The obvious way of doing this is
> to write a module that constructs the trim shape, then use code like this:
>
> difference() {
>   cube([len, size, size] center=true);
>   translate([len/2, 0, 0]) trimShape(size);
>   rotate([0, 180, 0]) translate([len/2, 0, 0]) trimShape(size);
> }
>
> But that leaves me with stray fragments because the rotation doesn't quite
> produce a 180 degree rotation.
>
> Is this a known problem?  Is there a known way to work around it?
>
> Thanks,
> Tom
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://rocklinux.net/mailman/listinfo/openscad
> http://openscad.org - https://flattr.com/thing/121566

Reply | Threaded
Open this post in threaded view
|

Re: Rotating objects by exactly 180 degrees

mmccool

Hello,

 

I’m trying to figure out what facilities there are for programmatically generating and manipulating vectors, as opposed to just using literals.  I was expecting to see something like car/cdr/cons (or (first/rest/concat) for assembling and taking apart vectors, or a vector comprehension, or a “pushback” operation, but can’t find anything like that in the manual.  If there is a clever way to get equivalent functionality (i.e. first v = v[0], but what about “cdr/rest” and “cons/concat”?) it would be good to know…

 

In particular, I’m trying to implement a superquadratic primitive shape.  I would like to generate a polygon mesh by generating appropriate vertices and triangles.  I have it working by generating small cylinders as “vertices” and then forming a hull over them, but this approach seems like ridiculous overkill.  I’d also like to implement Bezier curves and patches at some point (although I am aware that some people are trying to get these implemented as built-ins).

 

Also, I probably should just try it, but is recursion supported?

 

Michael McCool

Reply | Threaded
Open this post in threaded view
|

Re: Rotating objects by exactly 180 degrees

mmccool
I just tried it, and recursion seems to work for functions, but not for modules.
Michael

2013/3/27 Michael McCool <[hidden email]>

Hello,

 

I’m trying to figure out what facilities there are for programmatically generating and manipulating vectors, as opposed to just using literals.  I was expecting to see something like car/cdr/cons (or (first/rest/concat) for assembling and taking apart vectors, or a vector comprehension, or a “pushback” operation, but can’t find anything like that in the manual.  If there is a clever way to get equivalent functionality (i.e. first v = v[0], but what about “cdr/rest” and “cons/concat”?) it would be good to know…

 

In particular, I’m trying to implement a superquadratic primitive shape.  I would like to generate a polygon mesh by generating appropriate vertices and triangles.  I have it working by generating small cylinders as “vertices” and then forming a hull over them, but this approach seems like ridiculous overkill.  I’d also like to implement Bezier curves and patches at some point (although I am aware that some people are trying to get these implemented as built-ins).

 

Also, I probably should just try it, but is recursion supported?

 

Michael McCool


Reply | Threaded
Open this post in threaded view
|

Re: Rotating objects by exactly 180 degrees

sclaes
In reply to this post by Peter Falke
I know it's an old thread, but I'm wondering why nobody thought about mirroring the object twice to get a rotation of 180 degrees... I guess it is more accurate and it is probably faster than a rotation.

e.g. instead of
rotate([0,0,180]) {
  // object definition
 }

mirror([1,0,0]) {
  mirror([0,1,0]) {
    // object definition
  }
}

An alternative is a scaling with a factor of -1
scale([-1,1,1]) {
  scale([1,-1,1]) {
    // object definition
  }
}

Regards,
Stefaan

Reply | Threaded
Open this post in threaded view
|

Re: Rotating objects by exactly 180 degrees

PolyVinalDistillate
sclaes wrote
An alternative is a scaling with a factor of -1
scale([-1,1,1]) {
  scale([1,-1,1]) {
    // object definition
  }
}

Regards,
Stefaan
Perhaps this is a fixed bug by now, but with my Moray to OpenSCAD exports I've found negative scales generate geometry that renders in preview but vanishes in compile (there's a chance it vanished in preview *and* compile, but I can't remember for certain now! I've avoided using negative scales since I first found problems, so not tested in months).