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 nonlinear transformations. I think support for nonlinear 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: 1) pass data through, no change to vertices transform(x, y, z) { ... } 2) scale([xf,yf,zf]) { ... } <> transform(xf*x, yf*y, zf*z) { ... } 3) translate([x1,y1,z1]) { ... } <> transform(x+x1, y+y1, z+z1) { ... } 4) multmatrix([[xx, xy, xz, xc], [yx, yy, yz, yc], [zx, zy, zz, zc], [0, 0, 0, 1]) { ... } <> transform(xx*x+xy*y+xz*z+xc, yx*x+yy*y+yz*z+yc, zx*x+zy*y+zz*z+zc) { ... } NonLinear Transformations: 1) exponential x scaling transform(x*x, y, z) { ... } 2) "conic" expansion in xy plane, scale factor=1 for z=20 transform(x*z/20 ,y*z/20 ,z) cylinder(h=40, r=10); 3) scale specific coordinate ranges transform(x>0?2*x:x, abs(y)>50?3*y:y, z) { ... } 4) insert "gap" of 40mm centred on y=0 transform(x ,y>0?y+20:y20, z) cylinder(h=20, r=10); Comments please! Cheers, Trygon 
Administrator

> On Nov 16, 2015, at 10:11 AM, Trygon <[hidden email]> wrote:
> > OpenSCAD does not provide support for nonlinear transformations. I think > support for nonlinear 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 _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by Trygon
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.// "conic" expansion in xy plane, scale factor=1 for z=20 transform(fx(x)=x*z/20, fy(y)=y*z/20, fz(z)=z) cylinder(h=40, r=10); // exponential x scaling transform(fx(x)=x*x, fy=id, fz=id) { ... }
transform(fx(x)=x*x, id, id) { ... } On 16 November 2015 at 10:11, Trygon <[hidden email]> wrote: OpenSCAD currently supports a whole range of specific linear transformations _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by Trygon
I like the idea of providing nonlinear
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 nonlinear transformations. I think support for nonlinear 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: 1) pass data through, no change to vertices transform(x, y, z) { ... } 2) scale([xf,yf,zf]) { ... } <> transform(xf*x, yf*y, zf*z) { ... } 3) translate([x1,y1,z1]) { ... } <> transform(x+x1, y+y1, z+z1) { ... } 4) multmatrix([[xx, xy, xz, xc], [yx, yy, yz, yc], [zx, zy, zz, zc], [0, 0, 0, 1]) { ... } <> transform(xx*x+xy*y+xz*z+xc, yx*x+yy*y+yz*z+yc, zx*x+zy*y+zz*z+zc) { ... } NonLinear Transformations: 1) exponential x scaling transform(x*x, y, z) { ... } 2) "conic" expansion in xy plane, scale factor=1 for z=20 transform(x*z/20 ,y*z/20 ,z) cylinder(h=40, r=10); 3) scale specific coordinate ranges transform(x>0?2*x:x, abs(y)>50?3*y:y, z) { ... } 4) insert "gap" of 40mm centred on y=0 transform(x ,y>0?y+20:y20, z) cylinder(h=20, r=10); Comments please! Cheers, Trygon  View this message in context: http://forum.openscad.org/NonLinearTransformationstp14539.html Sent from the OpenSCAD mailing list archive at Nabble.com. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by Trygon
1) exponential: it should better be called power law or polynomial. It's a relatively unique requirement... 2) conic: I believe it's actually linear and doable with a simple multmatrix() 3) scale specific coordinate 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. 
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. https://github.com/openscad/openscad/issues/815 On 16 November 2015 at 12:35, ctchin <[hidden email]> wrote: Trygon wrote _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by kintel
Yes this could be used to bend objects, I think this would work:
transform(y*sin(x), y*cos(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 
In reply to this post by doug.moen
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: On 16 November 2015 at 13:02, doug moen <[hidden email]> wrote:
_______________________________________________ OpenSCAD mailing list [hidden email] 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 builtin or not, is a function call with no input parameters (adopting the default values if possible). For nonlinear or more precisely nonaffine transformation to work the way you imagine it, will require remeshing 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. 
In reply to this post by Trygon
// nonlinear 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(y*sin(x),y*cos(x)) polygon(p1); p2=[for(i=p1) [i[1]*sin(i[0]),i[1]*cos(i[0])]]; translate ([0,20,0]) polygon(p2); 
In reply to this post by ctchin
ctchin said: I just described (in a vague way) a smart remeshing algorithm in a previous post. I'd like to hear why my algorithm might not be acceptable.> For nonlinear or more precisely nonaffine transformation to > work the way you imagine it, will require remeshing the children > with some level of smartly selected resolution. Which spells... > no universally acceptable algorithm exists. On 16 November 2015 at 13:35, ctchin <[hidden email]> wrote: The more I read the more I understand the request, the more _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by ctchin
You are perfectly right!
Anyway only ismorphic nonlinear transformations would make sense. Most of them are not isomorphic in a general sense  but might be in a subset, as the given examples. A more general approach for this feature would be to get hands on the mesh points, as requested in my topic "feature request: obj2vec(); bug report: freeze on standby recovery (Windows)". Then, everyone is free to use his own mappings even nonisomorphic ones and also responsible if the resulting polyhedron will be malformed. > If it doesn't work sensibly on a cube() primitive, it's highly > questionable it ought to be added to OpenSCAD. 
Parkinbot, could you explain your comment "Anyway only ismorphic nonlinear transformations would make sense." What will go wrong if a nonisomorphic transformation is specified? Isomorphic means that the structure of the geometric object is preserved, in the sense that there is a reverse transformation that takes the transformed object back to the original. I can imagine evil transformations that result in a nonmanifold object, or which cause my smartremeshing algorithm to go into an infinite loop. I think we'd want error checking to detect these situations and report an error.On 16 November 2015 at 14:27, Parkinbot <[hidden email]> wrote: You are perfectly right! _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Well, a nonisomorphic map in R³>R³ will have singularities (points, lines or planes) in the sense that more than one points will be mapped to the same point  so no inverse map can be found. As bijectivity is lost, vertices and triangles simply might get lost.
Restricting a nonisomorphic map to a region (partial isomorphism), say to the unit cube, it might be locally isomorphic as long as the region does not contain any fix points. So if we have a (partial) isomorphism all points (of a region) will be mapped to separate image points and no merging can occur (numerically yes, which is still another severe problem). Also triangle orientation will be mapped in the same sense, as a partial flip of orientation of a triangle would need a singularity for separation. But you are right. Proving that a map is a (partial) isomorphism will only be a first step. Even then, nonintersecting triangles might intersect after being mapped (think of simply mapping one axis to a vortex like the Archimedian spiral), and demand some careful post processing. To sum it up: Nonlinear operations have many pitfalls. I guess one could allow for some of them in very specific contexts, like with extrusion operations. For linear_extrusion() instead of linear scaling and twisting one could think of nonlinear stepping or allow for a vector expressing an ordered list of values, which will be used as zheights, while scaling and twisting will be done in a linear fashion with equidistant stepping as it is done now. 
This post was updated on .
In reply to this post by ctchin
@ctchin you said, "conic: I believe it's actually linear and doable with a simple multmatrix()", with regard to:
transform(x*z/20 ,y*z/20 ,z) This transformation would be really useful for a model that I am scripting at present, I couldn't work out how to do it with multmatrix(), please could you provide the affine transformation matrix to use. Thanks, Trygon 
@Doug  This remeshing algorithm was designed specifically for this exact purpose and worked very well at the time. (1992). May be worth a read:
 http://www.red3d.com/cwr/papers/1992/df.html 
In reply to this post by Trygon
Hi Trygon. Wikipedia uses the term "perspective transformation" for what you call a conic transformation. I tried using the perspective transformation matrix from wikipedia in OpenSCAD and it didn't work, I got a runtime error. Don't remember the details, it was a while ago. At the time, I concluded that we don't support arbitrary affine transformations.On 16 November 2015 at 16:37, Trygon <[hidden email]> wrote: @ctchin you said, "conic: I believe it's actually linear and doable with a _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by Neon22
Oh, nice. This algorithm "removes excess detail in crowded regions where the
surface is contracting", which is more sophisticated than what I specified. On 16 November 2015 at 16:45, Neon22 <[hidden email]> wrote: @Doug  This remeshing algorithm was designed specifically for this exact _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Administrator

In reply to this post by doug.moen
> On Nov 16, 2015, at 16:52 PM, doug moen <[hidden email]> wrote:
> > I tried using the perspective transformation matrix from wikipedia in OpenSCAD and it didn't work, I got a runtime error. Don't remember the details, it was a while ago. At the time, I concluded that we don't support arbitrary affine transformations. > The perspective transformation is not affine. We currently don’t support nonaffine transformations because CGAL doesn’t. Marius _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by Trygon
1) Given that a transform function could be defined in OpenSCAD as:
function transform(v)=let(x=v[0], y=v[1], z=v[2]) [x*z/20, y*z/20, z]; which maps a single vertex to a new position (as per doug.moen: vector in, vector out), perhaps a better syntax would be: transform()=[x*z/20, y*z/20, z] { ... } 2) I have been using non affine transformations in my code for a while and the world has not ended. Yes they do have to be used with care, but are useful. The main issue is that they can only be used at present when all the geometry data has been computed directly so that the vertex data is visible. Trygon 
Free forum by Nabble  Edit this page 