discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

weird rotate around 2 axis

CA
Carsten Arnholm
Sun, Apr 10, 2016 10:50 AM

On 09. april 2016 22:18, Carsten Arnholm wrote:

Regarding mirror transformations, the more interesting thing is that it
is unnecessarily restricted to perform mirroring only through the origin.
Mirroring through an arbitrary point is useful.

This restriction applied to AngelScript CSG as well, but it is easily
removed. An OpenSCAD trivial base case serves as an example:

module sph1() { translate([0,100,0])sphere(30); }
sph1();
mirror([1,1,0])sph1();

As the manual says, it "Mirrors the child element on a plane through the
origin". However, restricting the mirror plane to go through the origin
only is unnecessary.

A couple of AngelScript CSG snippets of the same case follow. First, the
same "OpenSCAD-style mirroring" around origin:

solid@ sph1 = translate(0,100,0)*sphere(30);
solid@ sph2 = mirror(1,1,0)*sph1;

second, same as above, just using explicit vector argument for the
mirror normal, the mirror plane point still defaults to origin:

solid@ sph2 = mirror(vec3d(1,1,0))*sph1;

third, same plane normal, but using mirror plane point different from
origin:

solid@ sph2 = mirror(vec3d(1,1,0),pos3d(100,100,0))*sph1;

The third case obviously gives a different result than the two first
cases, sph2 ends up at x=100,y=200. This is a useful and practical
scenario that I think isn't quite as easily expressed in OpenSCAD, so it
might be something to consider.

Carsten Arnholm

On 09. april 2016 22:18, Carsten Arnholm wrote: > Regarding mirror transformations, the more interesting thing is that it > is unnecessarily restricted to perform mirroring only through the origin. > Mirroring through an arbitrary point is useful. This restriction applied to AngelScript CSG as well, but it is easily removed. An OpenSCAD trivial base case serves as an example: module sph1() { translate([0,100,0])sphere(30); } sph1(); mirror([1,1,0])sph1(); As the manual says, it "Mirrors the child element on a plane through the origin". However, restricting the mirror plane to go through the origin only is unnecessary. A couple of AngelScript CSG snippets of the same case follow. First, the same "OpenSCAD-style mirroring" around origin: solid@ sph1 = translate(0,100,0)*sphere(30); solid@ sph2 = mirror(1,1,0)*sph1; second, same as above, just using explicit vector argument for the mirror normal, the mirror plane point still defaults to origin: solid@ sph2 = mirror(vec3d(1,1,0))*sph1; third, same plane normal, but using mirror plane point different from origin: solid@ sph2 = mirror(vec3d(1,1,0),pos3d(100,100,0))*sph1; The third case obviously gives a different result than the two first cases, sph2 ends up at x=100,y=200. This is a useful and practical scenario that I think isn't quite as easily expressed in OpenSCAD, so it might be something to consider. Carsten Arnholm
DM
doug moen
Sun, Apr 10, 2016 4:22 PM

Carsten said: "Regarding mirror transformations, the more interesting thing
is that it unnecessarily restricted to perform mirroring only through the
origin. Mirroring through an arbitrary point is useful."

This is equally true for rotate, scale and shear transformations. If a
shape has its own local origin, then often you want to transform it
relative to its local origin.

In OpenSCAD, the standard idiom for transforming relative to a shape's
local origin is:
translate(origin) rotate(R) translate(-origin) shape

In OpenSCAD2, transformations will be values, so it will be possible to
encapsulate this idiom using a function:

at(origin,transform)(shape) =
translate(origin) transform translate(-origin) shape;

at(origin, rotate(R)) shape

On 9 April 2016 at 16:18, Carsten Arnholm arnholm@arnholm.org wrote:

On 09. april 2016 22:05, doug moen wrote:

The same arguments would work with mirror(), which takes a vector
argument:
mirror(X) -- reflect through the origin along the X axis
mirror(Y)
mirror(Z)

I don't think so.

Regarding mirror transformations, the more interesting thing is that it
unnecessarily restricted to perform mirroring only through the origin.
Mirroring through an arbitrary point is useful.

Carsten Arnholm


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

Carsten said: "Regarding mirror transformations, the more interesting thing is that it unnecessarily restricted to perform mirroring only through the origin. Mirroring through an arbitrary point is useful." This is equally true for rotate, scale and shear transformations. If a shape has its own local origin, then often you want to transform it relative to its local origin. In OpenSCAD, the standard idiom for transforming relative to a shape's local origin is: translate(origin) rotate(R) translate(-origin) shape In OpenSCAD2, transformations will be values, so it will be possible to encapsulate this idiom using a function: at(origin,transform)(shape) = translate(origin) transform translate(-origin) shape; at(origin, rotate(R)) shape On 9 April 2016 at 16:18, Carsten Arnholm <arnholm@arnholm.org> wrote: > On 09. april 2016 22:05, doug moen wrote: > >> The same arguments would work with mirror(), which takes a vector >> argument: >> mirror(X) -- reflect through the origin along the X axis >> mirror(Y) >> mirror(Z) >> > > I don't think so. > > Regarding mirror transformations, the more interesting thing is that it > unnecessarily restricted to perform mirroring only through the origin. > Mirroring through an arbitrary point is useful. > > > Carsten Arnholm > > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > >
CA
Carsten Arnholm
Sun, Apr 10, 2016 6:23 PM

On 10. april 2016 18:22, doug moen wrote:

In OpenSCAD, the standard idiom for transforming relative to a shape's
local origin is:
translate(origin) rotate(R) translate(-origin) shape

For rotate, yes you must do that, if rotation around the shape local
origin is what you want, or if you want to rotate around some other point.

For a mirror plane through an arbitrary point, both the the location of
the mirror plane and the shape matters. The position specified with
mirror transformation isn't a local transformation origin though, it is
any point in the mirror plane, there are infinitely many such points for
the same transformation.

Using my previous example
solid@ sph1 = translate(0,100,0)*sphere(30);

The following gives identical mirror transformations, using different
points in the same mirror plane:
solid@ sph2 = mirror(vec3d(1,1,0),pos3d(100,100,0))*sph1;
solid@ sph3 = mirror(vec3d(1,1,0),pos3d(0,200,0))*sph1;
solid@ sph4 = mirror(vec3d(1,1,0),pos3d(-100,300,0))*sph1;

In OpenSCAD2, transformations will be values, so it will be possible to
encapsulate this idiom using a function:

 at(origin,transform)(shape) =
     translate(origin) transform translate(-origin) shape;

 at(origin, rotate(R)) shape

I am not quite sure how your OpenSCAD2 idiom will handle this case.
Perhaps it will work the same. Building it into the mirror
transformation directly is relatively straightforward and the standard
method I have encountered elsewhere, so it seems natural to me.

Carsten Arnholm

On 10. april 2016 18:22, doug moen wrote: > In OpenSCAD, the standard idiom for transforming relative to a shape's > local origin is: > translate(origin) rotate(R) translate(-origin) shape For rotate, yes you must do that, if rotation around the shape local origin is what you want, or if you want to rotate around some other point. For a mirror plane through an arbitrary point, both the the location of the mirror plane and the shape matters. The position specified with mirror transformation isn't a local transformation origin though, it is any point in the mirror plane, there are infinitely many such points for the same transformation. Using my previous example solid@ sph1 = translate(0,100,0)*sphere(30); The following gives identical mirror transformations, using different points in the same mirror plane: solid@ sph2 = mirror(vec3d(1,1,0),pos3d(100,100,0))*sph1; solid@ sph3 = mirror(vec3d(1,1,0),pos3d(0,200,0))*sph1; solid@ sph4 = mirror(vec3d(1,1,0),pos3d(-100,300,0))*sph1; > In OpenSCAD2, transformations will be values, so it will be possible to > encapsulate this idiom using a function: > > at(origin,transform)(shape) = > translate(origin) transform translate(-origin) shape; > > at(origin, rotate(R)) shape I am not quite sure how your OpenSCAD2 idiom will handle this case. Perhaps it will work the same. Building it into the mirror transformation directly is relatively straightforward and the standard method I have encountered elsewhere, so it seems natural to me. Carsten Arnholm
DM
doug moen
Sun, Apr 10, 2016 7:51 PM

Yes, I understand why your interface to mirror() could be considered more
natural.

But it's still true that in OpenSCAD, you use
translate(origin) mirror(vec) translate(-origin) shape
to mirror a shape using a reflection plane passing through 'origin'. It
will often be the case that the 'origin' will be located relative to the
shape being reflected.

On 10 April 2016 at 14:23, Carsten Arnholm arnholm@arnholm.org wrote:

On 10. april 2016 18:22, doug moen wrote:

In OpenSCAD, the standard idiom for transforming relative to a shape's
local origin is:
translate(origin) rotate(R) translate(-origin) shape

For rotate, yes you must do that, if rotation around the shape local
origin is what you want, or if you want to rotate around some other point.

For a mirror plane through an arbitrary point, both the the location of
the mirror plane and the shape matters. The position specified with mirror
transformation isn't a local transformation origin though, it is any point
in the mirror plane, there are infinitely many such points for the same
transformation.

Using my previous example
solid@ sph1 = translate(0,100,0)*sphere(30);

The following gives identical mirror transformations, using different
points in the same mirror plane:
solid@ sph2 = mirror(vec3d(1,1,0),pos3d(100,100,0))*sph1;
solid@ sph3 = mirror(vec3d(1,1,0),pos3d(0,200,0))*sph1;
solid@ sph4 = mirror(vec3d(1,1,0),pos3d(-100,300,0))*sph1;

In OpenSCAD2, transformations will be values, so it will be possible to

encapsulate this idiom using a function:

 at(origin,transform)(shape) =
     translate(origin) transform translate(-origin) shape;

 at(origin, rotate(R)) shape

I am not quite sure how your OpenSCAD2 idiom will handle this case.
Perhaps it will work the same. Building it into the mirror transformation
directly is relatively straightforward and the standard method I have
encountered elsewhere, so it seems natural to me.

Carsten Arnholm


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

Yes, I understand why your interface to mirror() could be considered more natural. But it's still true that in OpenSCAD, you use translate(origin) mirror(vec) translate(-origin) shape to mirror a shape using a reflection plane passing through 'origin'. It will often be the case that the 'origin' will be located relative to the shape being reflected. On 10 April 2016 at 14:23, Carsten Arnholm <arnholm@arnholm.org> wrote: > On 10. april 2016 18:22, doug moen wrote: > >> In OpenSCAD, the standard idiom for transforming relative to a shape's >> local origin is: >> translate(origin) rotate(R) translate(-origin) shape >> > > For rotate, yes you must do that, if rotation around the shape local > origin is what you want, or if you want to rotate around some other point. > > For a mirror plane through an arbitrary point, both the the location of > the mirror plane and the shape matters. The position specified with mirror > transformation isn't a local transformation origin though, it is any point > in the mirror plane, there are infinitely many such points for the same > transformation. > > Using my previous example > solid@ sph1 = translate(0,100,0)*sphere(30); > > The following gives identical mirror transformations, using different > points in the same mirror plane: > solid@ sph2 = mirror(vec3d(1,1,0),pos3d(100,100,0))*sph1; > solid@ sph3 = mirror(vec3d(1,1,0),pos3d(0,200,0))*sph1; > solid@ sph4 = mirror(vec3d(1,1,0),pos3d(-100,300,0))*sph1; > > In OpenSCAD2, transformations will be values, so it will be possible to >> encapsulate this idiom using a function: >> >> at(origin,transform)(shape) = >> translate(origin) transform translate(-origin) shape; >> >> at(origin, rotate(R)) shape >> > > I am not quite sure how your OpenSCAD2 idiom will handle this case. > Perhaps it will work the same. Building it into the mirror transformation > directly is relatively straightforward and the standard method I have > encountered elsewhere, so it seems natural to me. > > > Carsten Arnholm > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > >