OpenSCAD currently supports a whole range of specific linear transformations
such as translate(), rotate() and scale(), in addition to the generic linear
transformation multmatrix().
OpenSCAD does not provide support for non-linear transformations. I think
support for non-linear transformations would be very useful and this could
be accomplished with a new transformation command:
transform(x_expression, y_expression, z_expression)
reserved names within transform() expressions: x, y & z, these represent the
vertex being processed
The examples below use this syntax.
Equivalent Linear Transformations:
pass data through, no change to vertices
transform(x, y, z) { ... }
scale([xf,yf,zf]) { ... } <-> transform(xfx, yfy, zf*z) { ... }
translate([x1,y1,z1]) { ... } <-> transform(x+x1, y+y1, z+z1) { ... }
multmatrix([[xx, xy, xz, xc], [yx, yy, yz, yc], [zx, zy, zz, zc], [0, 0,
0, 1]) { ... } <->
transform(xxx+xyy+xzz+xc, yxx+yyy+yzz+yc, zxx+zyy+zz*z+zc) { ...
}
Non-Linear Transformations:
exponential x scaling
transform(x*x, y, z) { ... }
"conic" expansion in x-y plane, scale factor=1 for z=20
transform(xz/20 ,yz/20 ,z) cylinder(h=40, r=10);
scale specific co-ordinate ranges
transform(x>0?2x:x, abs(y)>50?3y:y, z) { ... }
insert "gap" of 40mm centred on y=0
transform(x ,y>0?y+20:y-20, z) cylinder(h=20, r=10);
Comments please!
Cheers,
Trygon
--
View this message in context: http://forum.openscad.org/Non-Linear-Transformations-tp14539.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
On Nov 16, 2015, at 10:11 AM, Trygon db5765@outlook.com wrote:
OpenSCAD does not provide support for non-linear transformations. I think
support for non-linear transformations would be very useful and this could
be accomplished with a new transformation command:
Would this be conceptually similar to the proposed bend modifier?
https://github.com/openscad/openscad/issues/815
-Marius
This is a good example of what OpenSCAD2 is designed to enable.
OpenSCAD2 supports functions as first class values: functions can be passed
as arguments and returned as results. So the 'transform' module would not
need to be implemented as magic syntax. It would just be an ordinary module
that is passed 3 functions as arguments.
The syntax would look something like this:
// "conic" expansion in x-y plane, scale factor=1 for z=20
transform(fx(x)=xz/20, fy(y)=yz/20, fz(z)=z) cylinder(h=40, r=10);
The identity function gets used a lot with your scheme, so maybe we
predefine it. This is OpenSCAD2 function definition syntax:
id(x) = x;
Then,
// exponential x scaling
transform(fx(x)=x*x, fy=id, fz=id) { ... }
or just
transform(fx(x)=x*x, id, id) { ... }
On 16 November 2015 at 10:11, Trygon db5765@outlook.com wrote:
OpenSCAD currently supports a whole range of specific linear
transformations
such as translate(), rotate() and scale(), in addition to the generic
linear
transformation multmatrix().
OpenSCAD does not provide support for non-linear transformations. I think
support for non-linear transformations would be very useful and this could
be accomplished with a new transformation command:
transform(x_expression, y_expression, z_expression)
reserved names within transform() expressions: x, y & z, these represent
the
vertex being processed
The examples below use this syntax.
Equivalent Linear Transformations:
pass data through, no change to vertices
transform(x, y, z) { ... }
scale([xf,yf,zf]) { ... } <-> transform(xfx, yfy, zf*z) { ... }
translate([x1,y1,z1]) { ... } <-> transform(x+x1, y+y1, z+z1) { ...
}
multmatrix([[xx, xy, xz, xc], [yx, yy, yz, yc], [zx, zy, zz, zc], [0, 0,
0, 1]) { ... } <->
transform(xxx+xyy+xzz+xc, yxx+yyy+yzz+yc, zxx+zyy+zz*z+zc) {
...
}
Non-Linear Transformations:
exponential x scaling
transform(x*x, y, z) { ... }
"conic" expansion in x-y plane, scale factor=1 for z=20
transform(xz/20 ,yz/20 ,z) cylinder(h=40, r=10);
scale specific co-ordinate ranges
transform(x>0?2x:x, abs(y)>50?3y:y, z) { ... }
insert "gap" of 40mm centred on y=0
transform(x ,y>0?y+20:y-20, z) cylinder(h=20, r=10);
Comments please!
Cheers,
Trygon
--
View this message in context:
http://forum.openscad.org/Non-Linear-Transformations-tp14539.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
I like the idea of providing non-linear transformations.
However, the suggested approach seems to break the current treatment of
parameters.
The suggested syntax looks as if conventional parameters were passed,
but actually the arguments need to be treated in a very different way,
that is as functions.
Others will know better if that syntax fits into the language.
But I am afraid that it does not.
What about enhancing the language by functions as arguments to provide
the suggested functionality?
Am 16.11.2015 um 16:11 schrieb Trygon:
OpenSCAD currently supports a whole range of specific linear transformations
such as translate(), rotate() and scale(), in addition to the generic linear
transformation multmatrix().
OpenSCAD does not provide support for non-linear transformations. I think
support for non-linear transformations would be very useful and this could
be accomplished with a new transformation command:
transform(x_expression, y_expression, z_expression)
reserved names within transform() expressions: x, y & z, these represent the
vertex being processed
The examples below use this syntax.
Equivalent Linear Transformations:
pass data through, no change to vertices
transform(x, y, z) { ... }
scale([xf,yf,zf]) { ... } <-> transform(xfx, yfy, zf*z) { ... }
translate([x1,y1,z1]) { ... } <-> transform(x+x1, y+y1, z+z1) { ... }
multmatrix([[xx, xy, xz, xc], [yx, yy, yz, yc], [zx, zy, zz, zc], [0, 0,
0, 1]) { ... } <->
transform(xxx+xyy+xzz+xc, yxx+yyy+yzz+yc, zxx+zyy+zz*z+zc) { ...
}
Non-Linear Transformations:
exponential x scaling
transform(x*x, y, z) { ... }
"conic" expansion in x-y plane, scale factor=1 for z=20
transform(xz/20 ,yz/20 ,z) cylinder(h=40, r=10);
scale specific co-ordinate ranges
transform(x>0?2x:x, abs(y)>50?3y:y, z) { ... }
insert "gap" of 40mm centred on y=0
transform(x ,y>0?y+20:y-20, z) cylinder(h=20, r=10);
Comments please!
Cheers,
Trygon
--
View this message in context: http://forum.openscad.org/Non-Linear-Transformations-tp14539.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
**
Trygon wrote
exponential x scaling
transform(x*x, y, z) { ... }
"conic" expansion in x-y plane, scale factor=1 for z=20
transform(xz/20 ,yz/20 ,z) cylinder(h=40, r=10);
scale specific co-ordinate ranges
transform(x>0?2x:x, abs(y)>50?3y:y, z) { ... }
insert "gap" of 40mm centred on y=0
transform(x ,y>0?y+20:y-20, z) cylinder(h=20, r=10);
exponential: it should better be called power law or polynomial.
It's a relatively unique requirement...
conic: I believe it's actually linear and doable with a
simple multmatrix()
scale specific co-ordinate ranges and 4) insert gap
both are easily doable with a smartly written module
using difference() and/or projection()
So only the x = x*x exponential (sic) is new, I'm not
very convinced it justifies inventing a whole new syntax
for it.
--
View this message in context: http://forum.openscad.org/Non-Linear-Transformations-tp14539p14548.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Another way to represent the transformation is as a single function that
maps a point [x,y,z] to another point.
If you think of this function as mapping every point in a 3D shape, then
this is extremely powerful, as you can model any conceivable spatial
transformation: twisting, bending, etc.
In practice, there are difficulties, as pointed out by
https://github.com/openscad/openscad/issues/815
The problem is that, with many of the more interesting transformations,
it's not enough to simply transform each vertex. You may need to subdivide
the mesh to create smaller faces, and then transform each vertex in the
subdivided mesh. An example would be applying a twist or bend
transformation to a cube, with just the 8 vertices.
On 16 November 2015 at 12:35, ctchin c.t.chin@szu.edu.cn wrote:
Trygon wrote
exponential x scaling
transform(x*x, y, z) { ... }
"conic" expansion in x-y plane, scale factor=1 for z=20
transform(xz/20 ,yz/20 ,z) cylinder(h=40, r=10);
scale specific co-ordinate ranges
transform(x>0?2x:x, abs(y)>50?3y:y, z) { ... }
insert "gap" of 40mm centred on y=0
transform(x ,y>0?y+20:y-20, z) cylinder(h=20, r=10);
exponential: it should better be called power law or polynomial.
It's a relatively unique requirement...
conic: I believe it's actually linear and doable with a
simple multmatrix()
scale specific co-ordinate ranges and 4) insert gap
both are easily doable with a smartly written module
using difference() and/or projection()
So only the x = x*x exponential (sic) is new, I'm not
very convinced it justifies inventing a whole new syntax
for it.
--
View this message in context:
http://forum.openscad.org/Non-Linear-Transformations-tp14539p14548.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
Yes this could be used to bend objects, I think this would work:
transform(ysin(x), ycos(x), z)
As noted in the proposed bend modifier discussion, unless the object has
sufficient vertices it will just deform (unpleasantly), e.g. a simple cube
with 8 vertices would not work well. However this is a different issue.
If the use of x, y & z as reserved names makes the "syntax looks as if
conventional parameters were passed", perhaps x(), y() & z() could be used
instead as reserved functions, such that "the arguments need to
be...functions"?
The above example would become:
transform( y()*sin(x()), y()*cos(x()), z() )
-Trygon
--
View this message in context: http://forum.openscad.org/Non-Linear-Transformations-tp14539p14551.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Following up on the "subdivision problem".
I really like the proposal from Trygon last month of using a $fe variable
to specify the "maximal acceptable error" in a polygonal approximation of a
solid.
Having come to OpenSCAD primarily from a design engineering background I am
used to specifying tolerances for specific features, e.g. 20mm +/- 0.1mm.
Wanting to use this principle for arc approximation I have adopted the
approach set out below which I hope might be useful to others.
The maximum error for a facet occurs at it centre, when it is furthest from
the true circular arc that it approximates. I use variable $fe in my
OpenSCAD scripts to specify the maximum acceptable value of this error (the
distance from the centre of the facet to the true circular arc, measured
normal to the facet). I then use the following function to calculate a
value for $fa based on the arc radius and $fe:
So now I'm wondering if we can create an algorithm for optimally
subdividing a polygon, using the minimum number of subdivisions necessary
to keep the error below $fe, when applying one of Trygon's generalized
spatial tranformations. I think it makes sense. We transform all of the
vertexes in a face, then we perform a trial subdivision of that face,
transform the added vertexes, and measure if the added vertexes were
necessary.
On 16 November 2015 at 13:02, doug moen doug@moens.org wrote:
Another way to represent the transformation is as a single function that
maps a point [x,y,z] to another point.
If you think of this function as mapping every point in a 3D shape, then
this is extremely powerful, as you can model any conceivable spatial
transformation: twisting, bending, etc.
In practice, there are difficulties, as pointed out by
https://github.com/openscad/openscad/issues/815
The problem is that, with many of the more interesting transformations,
it's not enough to simply transform each vertex. You may need to subdivide
the mesh to create smaller faces, and then transform each vertex in the
subdivided mesh. An example would be applying a twist or bend
transformation to a cube, with just the 8 vertices.
On 16 November 2015 at 12:35, ctchin c.t.chin@szu.edu.cn wrote:
Trygon wrote
exponential x scaling
transform(x*x, y, z) { ... }
"conic" expansion in x-y plane, scale factor=1 for z=20
transform(xz/20 ,yz/20 ,z) cylinder(h=40, r=10);
scale specific co-ordinate ranges
transform(x>0?2x:x, abs(y)>50?3y:y, z) { ... }
insert "gap" of 40mm centred on y=0
transform(x ,y>0?y+20:y-20, z) cylinder(h=20, r=10);
exponential: it should better be called power law or polynomial.
It's a relatively unique requirement...
conic: I believe it's actually linear and doable with a
simple multmatrix()
scale specific co-ordinate ranges and 4) insert gap
both are easily doable with a smartly written module
using difference() and/or projection()
So only the x = x*x exponential (sic) is new, I'm not
very convinced it justifies inventing a whole new syntax
for it.
--
View this message in context:
http://forum.openscad.org/Non-Linear-Transformations-tp14539p14548.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
The more I read the more I understand the request, the more
I'm convinced there's a lot loony ideas being thrown around.
The syntax x(), whether it's built-in or not, is a function call
with no input parameters (adopting the default values if possible).
For non-linear or more precisely non-affine transformation to
work the way you imagine it, will require re-meshing the children
with some level of smartly selected resolution. Which spells...
no universally acceptable algorithm exists.
If it doesn't work sensibly on a cube() primitive, it's highly
questionable it ought to be added to OpenSCAD.
--
View this message in context: http://forum.openscad.org/Non-Linear-Transformations-tp14539p14553.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
// non-linear transformation: 2D bend demo
x1=-40;
x2=40;
y1=30;
y2=40;
step=10;
p1=concat([for(i=[x1:step:x2]) [i,y1]],[for(i=[x2:-step:x1]) [i,y2]]);
polygon(p1);
// translate([0,-20,0]) transform(ysin(x),ycos(x)) polygon(p1);
p2=[for(i=p1) [i[1]*sin(i[0]),i[1]*cos(i[0])]];
translate ([0,-20,0]) polygon(p2);
--
View this message in context: http://forum.openscad.org/Non-Linear-Transformations-tp14539p14554.html
Sent from the OpenSCAD mailing list archive at Nabble.com.