I have code with recursive functions that use translate() to change the
current location. The code works fine, but now I have to add code that needs
to know the current x, y, z location that resulted from many nested
translate() functions. How can I find the current x, y, z location?
Thank you!
--
Sent from: http://forum.openscad.org/
jamcultur wrote
I have code with recursive functions that use translate() to change the
current location. The code works fine, but now I have to add code that
needs
to know the current x, y, z location that resulted from many nested
translate() functions. How can I find the current x, y, z location?
Your question is too vague. I think you need to post a code example and
explain what you are trying to do. What is the "current location"? The
(x,y,z) location of what? And what are you hoping to do with it once you
find it?
--
Sent from: http://forum.openscad.org/
To me, the "current location" is location that is the reference point of any
object that you draw. For example, if you wrote sphere(d=10);, the center of
the sphere would be at the current location. That location could have any x,
y, and z coordinates, depending on the previous translates and rotates. I
need to know those coordinates in order to determine whether to draw the
next object.
I should also mention that there are also many rotate() functions in the
recursive functions I mentioned previously.
--
Sent from: http://forum.openscad.org/
Short answer is you can't get it from OpenSCAD.
You do all the translates etc, so you can calculate where 'here' is.
There are libraries which can help like local
https://github.com/jreinhardt/local-scad , there are others, I just can't
find them ATM.
Admin - email* me if you need anything, or if I've done something stupid...
Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.
Sent from: http://forum.openscad.org/
You mention rotate() and translate() function but I assume you mean modules.
You could replace the recursive modules that use translate and rotate with
recursive functions that generate a transformation matrix instead by
multiplying translation and rotation matrices. Then you could apply that to
position your object using multmatrix() and you could also multiply it by
[0, 0, 0, 1] to get the numeric position as a vector.
Basically you always tell OpenSCAD where something is, you can never ask it.
On Sat, 2 Mar 2019 at 05:59, MichaelAtOz oz.at.michael@gmail.com wrote:
Short answer is you can't get it from OpenSCAD.
You do all the translates etc, so you can calculate where 'here' is.
There are libraries which can help like local
https://github.com/jreinhardt/local-scad , there are others, I just
can't
find them ATM.
Admin - email* me if you need anything, or if I've done something stupid...
Unless specifically shown otherwise above, my contribution is in the
Public Domain; to the extent possible under law, I have waived all
copyright and related or neighbouring rights to this work. Obviously
inclusion of works of previous authors is not included in the above.
Sent from: http://forum.openscad.org/
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
If I correctly understand your needs: you could add absolute position
(vector) as a parameter of the recursive function, so every time you call
again the function, you update the vector you pass accordingly to the
applied translation.
I used a similar approach to apply color to a 3D fractal, depending on the
cumulative displacement from [0,0,0].
jamcultur wrote
I have code with recursive functions that use translate() to change the
current location. The code works fine, but now I have to add code that
needs
to know the current x, y, z location that resulted from many nested
translate() functions. How can I find the current x, y, z location?
Thank you!
--
Sent from: http://forum.openscad.org/
You understand correctly, and I was thinking of doing exactly what you
suggest. I was hoping that OpenSCAD had an easier way to do it. OpenSCAD
obviously knows the current [x, y, z] and it seems like it should be simple
for it to make that information available to the program.
--
Sent from: http://forum.openscad.org/
The generated geometry depends on the variables. Making the variables
dependent on the geometry could create a circular dependency unless it is
restricted by scope rules and would require more passes.
On Sat, 2 Mar 2019 at 15:54, jamcultur nyponen@gmail.com wrote:
You understand correctly, and I was thinking of doing exactly what you
suggest. I was hoping that OpenSCAD had an easier way to do it. OpenSCAD
obviously knows the current [x, y, z] and it seems like it should be simple
for it to make that information available to the program.
--
Sent from: http://forum.openscad.org/
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
don't know whether it will help you, but the way nophead described, is not
too difficult to go, if you have translate(), rotate(), and scale() as
functions.
Say your module contains code like this
rotate([100,0,100])
translate([0,30,100])
rotate([33,0,100])
translate([0,0,100])
cube(100);
if you want to know where cube is mapped, or where any other point q will be
mapped, you just use the same transformation sequence in function syntax.
q=[0,0,0];
q1 =
rotate([100,0,100],
translate([0,30,100],
rotate([33,0,100],
translate([0,0,100], q))));
echo(q1);
Here is my implementation of the three functions. The code looks more
difficult than it is, because the functions are part of a richer interface,
accept parameter calls without [] and work recursive. They operate over
points, lists of points, lists of lists of points and so on. I use them
mainly in connection with sweep(), but they will also serve your needs.
function translate(x=0, y=0, z=0, v) =
let(v = (len(x)==3)?y:v, x = (len(x)==3)?x:[x, y, z])
len(v[0])?[for (i=v) translate(x,i)]:v+x;
function rotate(x=0, y=0, z=0, v) = // 2D vectors allowed
let(v = (len(x)==3)?y:v, x=(len(x)==3)?x:[x, y, z])
len(v[0])? [for(i=v) rotate(x,i)]:Rz(x[2], Ry(x[1], Rx(x[0], v)));
function Rx(x, A) = len(A[0][0])?[for(i=A) Rx(x, i)]:
A*[[1, 0, 0], [0, cos(x), sin(x)], [0, -sin(x), cos(x)]];
function Ry(y, A) = len(A[0][0])?[for(i=A) Ry(y, i)]:
A*[[cos(y), 0, sin(y)], [0, 1, 0], [-sin(y), 0, cos(y)]];
function Rz(z, A) = len(A[0][0])?
[for(i=A) Rz(z, i)]:
len(A[0])==2?
A*[[cos(z), sin(z)], [-sin(z), cos(z)]]:
A*[[cos(z), sin(z), 0], [-sin(z), cos(z), 0], [0, 0, 1]];
function scale(x=1, y=1, z=1, v) =
let(v = (len(x)==3)?y:v, x = (len(x)==3)?x:[x, y, z])
len(v[0])?[for (i=v) S_(x,i)]:[v[0]*x[0], v[1]*x[1], v[2]*x[2]];
--
Sent from: http://forum.openscad.org/
On 3/2/2019 12:17 AM, nop head wrote:
Basically you always tell OpenSCAD where something is, you can never
ask it.
(I know that you know this.)
And even then, you can only tell it where something is relative to its
own transformations... you can't specify an absolute location.
That is, you can't say
sequence( ) of( ) transformations() {
translate_back_to_origin( ) {
object( );
}
}
The only way to do that would be to know the sequence of transformations
and unwind them.
I still want to know what the original poster was actually trying to do with
a specific code example. I think without that it's difficult to really say
what the best solution is.
Why, if you have a series of transformations, would you not just put
whatever second thing you need inside that same code. What is the reason
for wanting to do something later inside a series of transformations you did
before? That is the obvious question I have.
--
Sent from: http://forum.openscad.org/
On 3/2/2019 7:49 AM, jamcultur wrote:
OpenSCAD obviously knows the current [x, y, z]
[ Speaking from an external observer's point of view, without knowledge
of the internals... others, feel free to correct me.]
First, note that "current position" isn't the complete picture - there's
also rotation, scale, and skew.
I don't think it does know the current position..
It doesn't execute a program in a conventional sense, producing geometry
as a direct result of the execution.
Rather, it executes a program[*] that produces a tree of
transformations, operations, and objects, and a subsequent step applies
those transformations and operations to those objects to produce the
final absolute geometry.
Turn on Design/"Display CSG Tree" to see the results of the execution.
Note that the generated geometry still has each of the transformation
steps; there are no absolute coordinates.
[*] Even that isn't quite right. Note that there are almost no
unbounded loops and there are no conventional variables. In a lot
of ways it's more like a macro processor than a language
interpreter. Everything is done at "compile" time and there is no
"run time".
<weeds level=deep>
Even if it was a conventional language that directly generated the final
geometry, I don't know if it always would know the current
transformation relative to the absolute coordinate system.
The most straightforward way to do it would be to have a transformation
function call its children and then apply its transformation to them,
returning a transformed object. In such a design, each function would
have no idea what coordinate system it was embedded in; you would only
know absolute coordinates when you get back to the top of the call stack.
It might be equivalent to "left associate" the transformations,
building up a "current transformation", applying that to the primitive
objects, and then doing all of the boolean operations in the absolute
coordinate system. I don't think that can work for operations like
offset, projection, and extrusion, but maybe I just haven't warped my
brain enough.
Yes indeed. I never need to do this. To put the object at the origin I
simply don't put it under some transformations. If I want to transform
other objects to the same place I create a module that transforms its
children and apply it wherever wanted.
I don't need to ask where something is because I have placed it relative to
other objects in the design and then my machines make it. I sometimes add
echos of sizes that hare calculated to make sure they will fit on my
printers.
On Sun, 3 Mar 2019 at 21:03, adrianv avm4@cornell.edu wrote:
I still want to know what the original poster was actually trying to do
with
a specific code example. I think without that it's difficult to really say
what the best solution is.
Why, if you have a series of transformations, would you not just put
whatever second thing you need inside that same code. What is the reason
for wanting to do something later inside a series of transformations you
did
before? That is the obvious question I have.
--
Sent from: http://forum.openscad.org/
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
This ties back to the prior threads on libraries and learning OpenSCAD.
I think both of you have the best (and correct) strategy for approaching
this. Unfortunately we don't have a lot of documentation about how to
use OpenSCAD "well" so that a beginner learns to tackle things this way
from the start.
Whether you believe in libraries or not, coming up with resources to
share this type of knowledge would be valuable. I'm not really sure how
to teach it (let alone sure if I have a very good handle on many such
techniques) but it'd be great to see the community discuss these types
of practices so we can get them documented.
On 3/3/19 3:12 PM, nop head wrote:
Yes indeed. I never need to do this. To put the object at the origin I
simply don't put it under some transformations. If I want to transform
other objects to the same place I create a module that transforms its
children and apply it wherever wanted.
I don't need to ask where something is because I have placed it
relative to other objects in the design and then my machines make it.
I sometimes add echos of sizes that hare calculated to make sure they
will fit on my printers.
On Sun, 3 Mar 2019 at 21:03, adrianv <avm4@cornell.edu
mailto:avm4@cornell.edu> wrote:
I still want to know what the original poster was actually trying
to do with
a specific code example. I think without that it's difficult to
really say
what the best solution is.
Why, if you have a series of transformations, would you not just put
whatever second thing you need inside that same code. What is
the reason
for wanting to do something later inside a series of
transformations you did
before? That is the obvious question I have.
JordanBrown wrote
And even then, you can only tell it where something is relative to its
own transformations... you can't specify an absolute location.
That is, you can't say
sequence( ) of( ) transformations() {
translate_back_to_origin( ) {
object( );
}
}
The only way to do that would be to know the sequence of transformations
and unwind them.
Hmm, why would one like to write this? You can simple write
object( );
--
Sent from: http://forum.openscad.org/
One reason to what to know the global coordinates would be for labeling. I
posted questions about this recently and got good feedback.
For example, if I want to produce a printable schematic or design document
for translating the on-screen object into a real-world object through
traditional machining techniques, I need to know real world coordinates.
So if a particular edge or point is the result of multiple transformations,
it is difficult to determine that location for labeling.
A great solution would be to have built-in transformation functions of
vectors. But short of that, there are libraries that can do the same, so
that it can be determined manually.
Kevin
On Sun, Mar 3, 2019 at 1:13 PM nop head nop.head@gmail.com wrote:
Yes indeed. I never need to do this. To put the object at the origin I
simply don't put it under some transformations. If I want to transform
other objects to the same place I create a module that transforms its
children and apply it wherever wanted.
I don't need to ask where something is because I have placed it relative
to other objects in the design and then my machines make it. I sometimes
add echos of sizes that hare calculated to make sure they will fit on my
printers.
On Sun, 3 Mar 2019 at 21:03, adrianv avm4@cornell.edu wrote:
I still want to know what the original poster was actually trying to do
with
a specific code example. I think without that it's difficult to really say
what the best solution is.
Why, if you have a series of transformations, would you not just put
whatever second thing you need inside that same code. What is the reason
for wanting to do something later inside a series of transformations you
did
before? That is the obvious question I have.
--
Sent from: http://forum.openscad.org/
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
I should start by stating that I don’t really know what I’m talking about, so I’ve already got an excuse if my question is stupid.
As I understand it, the primary impediment of access to things like current x,y,z location and getting a list of the current points in an object is because the CGAL CSG library API that OpenSCAD is built open doesn’t provide that kind of access. On the other hand, I note that OpenJSCAD has implemented their own CSG library in javascript, which, as I understand it, does provide access to the information.
Would that be the way to provide OpenSCAD with that kind of functionality?
I’m certainly aware that it’s easy to wave one's hand and say “let’s just get a whole bunch of contributors who have lots of free time to create this library for absolutely no compensation”, so I’m not saying that, I’m just wondering if that would be possible path forward and if it’s ever been considered as a possible roadmap for future work. I appreciate that any CSG functionality may not be as robust as CGAL, but on the other hand there’s already situations in which I’m piecing together point lists for simple geometric constructions for polygon() and polyhedron() that get overly complex rather quickly. I was thinking that some built-in CSG for union(), difference() and intersection() might provide the functionality that many people would want, even if it collapsed under sophisticated or overly complex constructions.
On Mar 4, 2019, at 8:40 AM, Kevin Toppenberg kdtop3@gmail.com wrote:
One reason to what to know the global coordinates would be for labeling. I posted questions about this recently and got good feedback.
For example, if I want to produce a printable schematic or design document for translating the on-screen object into a real-world object through traditional machining techniques, I need to know real world coordinates. So if a particular edge or point is the result of multiple transformations, it is difficult to determine that location for labeling.
A great solution would be to have built-in transformation functions of vectors. But short of that, there are libraries that can do the same, so that it can be determined manually.
Kevin
On Sun, Mar 3, 2019 at 1:13 PM nop head <nop.head@gmail.com mailto:nop.head@gmail.com> wrote:
Yes indeed. I never need to do this. To put the object at the origin I simply don't put it under some transformations. If I want to transform other objects to the same place I create a module that transforms its children and apply it wherever wanted.
I don't need to ask where something is because I have placed it relative to other objects in the design and then my machines make it. I sometimes add echos of sizes that hare calculated to make sure they will fit on my printers.
On Sun, 3 Mar 2019 at 21:03, adrianv <avm4@cornell.edu mailto:avm4@cornell.edu> wrote:
I still want to know what the original poster was actually trying to do with
a specific code example. I think without that it's difficult to really say
what the best solution is.
Why, if you have a series of transformations, would you not just put
whatever second thing you need inside that same code. What is the reason
for wanting to do something later inside a series of transformations you did
before? That is the obvious question I have.
--
Sent from: http://forum.openscad.org/ http://forum.openscad.org/
OpenSCAD mailing list
Discuss@lists.openscad.org mailto:Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
OpenSCAD mailing list
Discuss@lists.openscad.org mailto:Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/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
There is no problem accessing CGAL data but I think it is only the stack of
transformation matrices that would be needed and they are outside of CGAL
as they are also needed for preview.
And as I previously pointed out OpenSCAD evaluates all the expressions and
then generates geometry. So the transformation matrices are not generated
at the point you could use them in an expression.
Since the user always places geometry in theory one can always work out
where it is but that may require a working knowledge of trigonometry and
matrix maths.
On Mon, 4 Mar 2019 at 18:00, Hugo Jackson hugo@apres.net wrote:
I should start by stating that I don’t really know what I’m talking about,
so I’ve already got an excuse if my question is stupid.
As I understand it, the primary impediment of access to things like
current x,y,z location and getting a list of the current points in an
object is because the CGAL CSG library API that OpenSCAD is built open
doesn’t provide that kind of access. On the other hand, I note that
OpenJSCAD has implemented their own CSG library in javascript, which, as I
understand it, does provide access to the information.
Would that be the way to provide OpenSCAD with that kind of functionality?
I’m certainly aware that it’s easy to wave one's hand and say “let’s just
get a whole bunch of contributors who have lots of free time to create this
library for absolutely no compensation”, so I’m not saying that, I’m just
wondering if that would be possible path forward and if it’s ever been
considered as a possible roadmap for future work. I appreciate that any CSG
functionality may not be as robust as CGAL, but on the other hand there’s
already situations in which I’m piecing together point lists for simple
geometric constructions for polygon() and polyhedron() that get overly
complex rather quickly. I was thinking that some built-in CSG for union(),
difference() and intersection() might provide the functionality that many
people would want, even if it collapsed under sophisticated or overly
complex constructions.
On Mar 4, 2019, at 8:40 AM, Kevin Toppenberg kdtop3@gmail.com wrote:
One reason to what to know the global coordinates would be for labeling.
I posted questions about this recently and got good feedback.
For example, if I want to produce a printable schematic or design document
for translating the on-screen object into a real-world object through
traditional machining techniques, I need to know real world coordinates.
So if a particular edge or point is the result of multiple transformations,
it is difficult to determine that location for labeling.
A great solution would be to have built-in transformation functions of
vectors. But short of that, there are libraries that can do the same, so
that it can be determined manually.
Kevin
On Sun, Mar 3, 2019 at 1:13 PM nop head nop.head@gmail.com wrote:
Yes indeed. I never need to do this. To put the object at the origin I
simply don't put it under some transformations. If I want to transform
other objects to the same place I create a module that transforms its
children and apply it wherever wanted.
I don't need to ask where something is because I have placed it relative
to other objects in the design and then my machines make it. I sometimes
add echos of sizes that hare calculated to make sure they will fit on my
printers.
On Sun, 3 Mar 2019 at 21:03, adrianv avm4@cornell.edu wrote:
I still want to know what the original poster was actually trying to do
with
a specific code example. I think without that it's difficult to really
say
what the best solution is.
Why, if you have a series of transformations, would you not just put
whatever second thing you need inside that same code. What is the
reason
for wanting to do something later inside a series of transformations you
did
before? That is the obvious question I have.
--
Sent from: http://forum.openscad.org/
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Thanks for the reply… I’m less ignorant than I was yesterday. :)
On Mar 4, 2019, at 10:28 AM, nop head nop.head@gmail.com wrote:
There is no problem accessing CGAL data but I think it is only the stack of transformation matrices that would be needed and they are outside of CGAL as they are also needed for preview.
And as I previously pointed out OpenSCAD evaluates all the expressions and then generates geometry. So the transformation matrices are not generated at the point you could use them in an expression.
Since the user always places geometry in theory one can always work out where it is but that may require a working knowledge of trigonometry and matrix maths.
On Mon, 4 Mar 2019 at 18:00, Hugo Jackson <hugo@apres.net mailto:hugo@apres.net> wrote:
I should start by stating that I don’t really know what I’m talking about, so I’ve already got an excuse if my question is stupid.
As I understand it, the primary impediment of access to things like current x,y,z location and getting a list of the current points in an object is because the CGAL CSG library API that OpenSCAD is built open doesn’t provide that kind of access. On the other hand, I note that OpenJSCAD has implemented their own CSG library in javascript, which, as I understand it, does provide access to the information.
Would that be the way to provide OpenSCAD with that kind of functionality?
I’m certainly aware that it’s easy to wave one's hand and say “let’s just get a whole bunch of contributors who have lots of free time to create this library for absolutely no compensation”, so I’m not saying that, I’m just wondering if that would be possible path forward and if it’s ever been considered as a possible roadmap for future work. I appreciate that any CSG functionality may not be as robust as CGAL, but on the other hand there’s already situations in which I’m piecing together point lists for simple geometric constructions for polygon() and polyhedron() that get overly complex rather quickly. I was thinking that some built-in CSG for union(), difference() and intersection() might provide the functionality that many people would want, even if it collapsed under sophisticated or overly complex constructions.
On Mar 4, 2019, at 8:40 AM, Kevin Toppenberg <kdtop3@gmail.com mailto:kdtop3@gmail.com> wrote:
One reason to what to know the global coordinates would be for labeling. I posted questions about this recently and got good feedback.
For example, if I want to produce a printable schematic or design document for translating the on-screen object into a real-world object through traditional machining techniques, I need to know real world coordinates. So if a particular edge or point is the result of multiple transformations, it is difficult to determine that location for labeling.
A great solution would be to have built-in transformation functions of vectors. But short of that, there are libraries that can do the same, so that it can be determined manually.
Kevin
On Sun, Mar 3, 2019 at 1:13 PM nop head <nop.head@gmail.com mailto:nop.head@gmail.com> wrote:
Yes indeed. I never need to do this. To put the object at the origin I simply don't put it under some transformations. If I want to transform other objects to the same place I create a module that transforms its children and apply it wherever wanted.
I don't need to ask where something is because I have placed it relative to other objects in the design and then my machines make it. I sometimes add echos of sizes that hare calculated to make sure they will fit on my printers.
On Sun, 3 Mar 2019 at 21:03, adrianv <avm4@cornell.edu mailto:avm4@cornell.edu> wrote:
I still want to know what the original poster was actually trying to do with
a specific code example. I think without that it's difficult to really say
what the best solution is.
Why, if you have a series of transformations, would you not just put
whatever second thing you need inside that same code. What is the reason
for wanting to do something later inside a series of transformations you did
before? That is the obvious question I have.
--
Sent from: http://forum.openscad.org/ http://forum.openscad.org/
OpenSCAD mailing list
Discuss@lists.openscad.org mailto:Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
OpenSCAD mailing list
Discuss@lists.openscad.org mailto:Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
OpenSCAD mailing list
Discuss@lists.openscad.org mailto:Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
OpenSCAD mailing list
Discuss@lists.openscad.org mailto:Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/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
On 3/4/2019 1:51 AM, Parkinbot wrote:
JordanBrown wrote
And even then, you can only tell it where something is relative to its
own transformations... you can't specify an absolute location.
That is, you can't say
sequence( ) of( ) transformations() {
translate_back_to_origin( ) {
object( );
}
}
The only way to do that would be to know the sequence of transformations
and unwind them.
Hmm, why would one like to write this? You can simple write
object( );
It was a thought experiment, not a real-world example. The point was
that not only is it impossible to retrieve the absolute position from
inside a series of transformations, but it is also impossible to
specify an absolute position for whatever reason.
Perhaps object() is buried in a module with other stuff that is
intended to be relative to the transformations.
On 3/4/2019 8:40 AM, Kevin Toppenberg wrote:
One reason to what to know the global coordinates would be for
labeling. I posted questions about this recently and got good feedback.
For example, if I want to produce a printable schematic or design
document for translating the on-screen object into a real-world object
through traditional machining techniques, I need to know real world
coordinates. So if a particular edge or point is the result of
multiple transformations, it is difficult to determine that location
for labeling.
Position isn't everything. An object is rendered in a coordinate space
that is the result of the stack of transformations that are on top of
that object. Translation is one of the transformations, but only one.
Even if you could retrieve the absolute position, if you drew text at
that location it would be rotated, scaled, et cetera, and you probably
wouldn't want any of that. Even if you could retrieve the current
origin in absolute coordinates, you couldn't do much with it - if you
tried to translate( ) back to the origin, that translation would itself
be subject to the stack of transformations.
scale([5,1,1]) translate([1,1,1]) {
// the origin for this block is at [5,1,1]
origin=[5,1,1]; // imagine we could get this back from OpenSCAD
sphere(1);
translate(-origin) text("hello");
}
Note that our sphere is stretched because of the scale, but is centered
on [5,1,1].
Note that even though we attempted to translate the text back to the
origin, we failed because -[5,1,1] times the scale of [5,1,1] is
-[25,1,1], plus the "origin" is [-20,0,0]. (I don't immediately know
why it ended up starting at -15.)
Note that the text is stretched in the X axis because of the scale.
Similarly, if you tried to translate back to the origin in a rotated
frame of reference, you won't get what you expect.
rotate([0,0,90]) translate([2,0,0]) {
// the origin for this block is at [0,2,0]
origin=[0,2,0]; // imagine we could get this back from OpenSCAD
sphere(1);
translate(-origin) cube(1,center=true);
}
Note that the cube that was supposed to be translated back to the origin
ended up nowhere near the origin, because the translate(-origin) is
itself relative to a rotated coordinate system.
JordanBrown wrote
It was a thought experiment, not a real-world example. The point was
that not only is it impossible to retrieve the absolute position from
inside a series of transformations, but it is also impossible to
specify an absolute position for whatever reason.
I'm loomking for the same thing.
Is there an solution on this issue?
I have a model of a builing in openscad, an need to put markers at a number
of known locations.
The easiest way to to it would be to add them to my model, and during
compilation of the model have it echo the marker-id and location to the
console. Having x,y,z would be ok for me, but having all other details as
rotations and scale wouldn't hurt.
Some time ago I made a model of a IKEA-kitchen, that echoed a complete list
of what I had put into my model.
I then put the echoed item-numbers thru a script that fetched pricing etc
from ikea.com and ended up showing me a complete list of everything I needed
to buy including price and weight ;-)
/Henning
--
Sent from: http://forum.openscad.org/
On 2/28/2020 7:51 AM, wangerin wrote:
The easiest way to to it would be to add them to my model, and during
compilation of the model have it echo the marker-id and location to
the console. Having x,y,z would be ok for me, but having all other
details as rotations and scale wouldn't hurt.
Hey, OpenSCAD internals people...
How practical would it be to have a function that "rendered" an [x,y,z]
triple and returned an [x,y,z] triple in the top-level coordinate system?
At the time that functions and echo( ) are executed, has OpenSCAD even
constructed all of the "parent" transformations? Would it be possible
to walk up the work-in-progress tree transforming a point, at execution
time?
Not quite as general, but would it be possible to have an "object" that
didn't actually generate any geometry, but that got transformed like
geometry and, at the time that one would otherwise output geometry,
would print a value to the console?
Does OpenSCAD pass objects, transforms, and boolean operations to CGAL
for execution, or does it do the transforms itself and only pass objects
and boolean operations to CGAL? (Boolean operations are "distributive"
with respect to transforms, right? That is, transform(boolean(obj,
obj)) is the same as boolean(transform(obj), transform(obj)), right?)
I have started to look at doing actual hands-on development. I got
OpenSCAD to build under Windows, and the executable that I built ran.
Yay! But I am very far from being familiar enough with it to look at
this aspect. My first project is to try to figure out how to meld the
desires of the multi-tab-editor people with my desires as a multi-window
user so that we can both be happy.
Hi!
How practical would it be to have a function that "rendered"
an [x,y,z] triple and returned an [x,y,z] triple in the
top-level coordinate system?
Not sure, seems difficult to express that.
At the time that functions and echo( ) are executed, has
OpenSCAD even constructed all of the "parent" transformations?
No.
Would it be possible to walk up the work-in-progress tree
transforming a point, at execution time?
There's no execution time as such. It's a multi-step process.
https://github.com/openscad/openscad/blob/master/doc/OpenSCAD-compile.pdf
It might be possible to get that information at some point.
Not quite as general, but would it be possible to have an
"object" that didn't actually generate any geometry, but
that got transformed like geometry and, at the time that
one would otherwise output geometry, would print a value
to the console?
I certainly hope so, some initial discussion in this issue:
https://github.com/openscad/openscad/pull/3087
There's a number of topics to clarify, and help with that
would be appreciated.
ciao,
Torsten.
Given a set of functions identity(), rotate([xa,ya,za]),
translate([x,y,z]), et cetera, which return transformation matrices, one
could imagine:
$m = identity();
module xrot(a) {
$m = $m * rotate(a);
rotate(a) children();
}
module xtrans(off) {
$m = $m * translate(off);
translate(off) children();
}
function prender(p) = $m * p;
... and if you used xrot() and xtrans() instead of rotate() and
translate(), you could at any point
echo(prender([0,0,0]));
to print the "global" coordinates of the local origin.
Does that make sense? (See a more complete example at the bottom.)
Other notes:
So it seems pretty clear that one could construct such a mechanism on
top of current OpenSCAD, entirely in userspace. The question is whether
OpenSCAD has equivalent data already available to it.
To prove to myself that the $m scheme above was actually viable, I
implemented some of it. As long as I've written it...
ECHO: "marker", [21.2132, 21.2132, 10, 1]
Note that the unit cube emitted by whoami() has been transformed - it's
rotated and elongated - but the label is aligned with the axes and is
undistorted.
Here's the source:
$m = identity();
xrot([0,0,45]) xscale([3,1,1]) xtrans([10,0,10]) whereami("marker");
function identity() = [
[1,0,0,0],
[0,1,0,0],
[0,0,1,0],
[0,0,0,1]
];
function translate(p) = [
[1,0,0,p.x],
[0,1,0,p.y],
[0,0,1,p.z],
[0,0,0, 1]
];
function scale(s) = [
[s.x, 0, 0, 0],
[ 0, s.y, 0, 0],
[ 0, 0, s.z, 0],
[ 0, 0, 0, 1]
];
function rotatex(a) = [
[ 1, 0, 0, 0 ],
[ 0, cos(a), -sin(a), 0 ],
[ 0, sin(a), cos(a), 0 ],
[ 0, 0, 0, 1 ]
];
function rotatey(a) = [
[ cos(a), 0, sin(a), 0 ],
[ 0, 1, 0, 0 ],
[ -sin(a), 0, cos(a), 0 ],
[ 0, 0, 0, 1 ]
];
function rotatez(a) = [
[ cos(a), -sin(a), 0, 0 ],
[ sin(a), cos(a), 0, 0 ],
[ 0, 0, 1, 0 ],
[ 0, 0, 0, 1 ]
];
function rotate(xyz) =
rotatex(xyz[0])
* rotatey(xyz[1])
* rotatez(xyz[2]);
module xrot(xyz) {
$m = $m * rotate(xyz);
rotate(xyz) children();
}
module xtrans(off) {
$m = $m * translate(off);
translate(off) children();
}
module xscale(s) {
$m = $m * scale(s);
scale(s) children();
}
// Place a unit cube (in local coordinates) at the origin.
// Place a label (with global-default parameters) at that point.
// Echo the label and the global coordinates.
module whereami(label) {
p = $m * [0,0,0,1];
echo(label,p);
cube(1, center=true);
multmatrix(matrix_invert($m)) translate([p.x,p.y,p.z]) text(label);
}
// Matrix inversion, from
//https://github.com/openscad/scad-utils/pull/1/files
function remove(list, i) = [for (i_=[0:1:len(list)-2]) list[i_ < i ? i_ : i_ + 1]];
function det(m) = let(r=[for(i=[0:1:len(m)-1]) i]) det_help(m, 0, r);
function det_help(m, i, r) = len(r) == 0 ? 1 :
m[len(m)-len(r)][r[i]]*det_help(m,0,remove(r,i)) - (i+1<len(r)? det_help(m, i+1, r) : 0);
function matrix_invert(m) = let(r=[for(i=[0:len(m)-1]) i]) [for(i=r) [for(j=r)
((i+j)%2==0 ? 1:-1) * matrix_minor(m,0,remove(r,j),remove(r,i))]] / det(m);
function matrix_minor(m,k,ri, rj) = let(len_r=len(ri)) len_r == 0 ? 1 :
m[ri[0]][rj[k]]*matrix_minor(m,0,remove(ri,0),remove(rj,k)) - (k+1<len_r?matrix_minor(m,k+1,ri,rj) : 0);
The question is whether OpenSCAD has equivalent data already available to
it.
I think the answer is no at the time variables are evaluated, although I
could be wrong.
In OpenSCAD you define variables and expressions and then geometry is
instantiated with known constant values after all expressions have been
evaluated.
On Sun, 1 Mar 2020 at 23:01, Jordan Brown openscad@jordan.maileater.net
wrote:
Given a set of functions identity(), rotate([xa,ya,za]),
translate([x,y,z]), et cetera, which return transformation matrices, one
could imagine:
$m = identity();
module xrot(a) {
$m = $m * rotate(a);
rotate(a) children();
}
module xtrans(off) {
$m = $m * translate(off);
translate(off) children();
}
function prender(p) = $m * p;
... and if you used xrot() and xtrans() instead of rotate() and
translate(), you could at any point
echo(prender([0,0,0]));
to print the "global" coordinates of the local origin.
Does that make sense? (See a more complete example at the bottom.)
Other notes:
- At any point you could set $m to the identity matrix to "reset" it
for the children, so that they would report coordinates relative to *that*
coordinate system.
- Given $m, you can invert it to get a global-to-local transformation,
allowing you to then do things like add labels that are described in terms
of the global coordinate system.
So it seems pretty clear that one could construct such a mechanism on top
of current OpenSCAD, entirely in userspace. The question is whether
OpenSCAD has equivalent data already available to it.
To prove to myself that the $m scheme above was actually viable, I
implemented some of it. As long as I've written it...
ECHO: "marker", [21.2132, 21.2132, 10, 1]
Note that the unit cube emitted by whoami() has been transformed - it's
rotated and elongated - but the label is aligned with the axes and is
undistorted.
Here's the source:
$m = identity();
xrot([0,0,45]) xscale([3,1,1]) xtrans([10,0,10]) whereami("marker");
function identity() = [
[1,0,0,0],
[0,1,0,0],
[0,0,1,0],
[0,0,0,1]
];
function translate(p) = [
[1,0,0,p.x],
[0,1,0,p.y],
[0,0,1,p.z],
[0,0,0, 1]
];
function scale(s) = [
[s.x, 0, 0, 0],
[ 0, s.y, 0, 0],
[ 0, 0, s.z, 0],
[ 0, 0, 0, 1]
];
function rotatex(a) = [
[ 1, 0, 0, 0 ],
[ 0, cos(a), -sin(a), 0 ],
[ 0, sin(a), cos(a), 0 ],
[ 0, 0, 0, 1 ]
];
function rotatey(a) = [
[ cos(a), 0, sin(a), 0 ],
[ 0, 1, 0, 0 ],
[ -sin(a), 0, cos(a), 0 ],
[ 0, 0, 0, 1 ]
];
function rotatez(a) = [
[ cos(a), -sin(a), 0, 0 ],
[ sin(a), cos(a), 0, 0 ],
[ 0, 0, 1, 0 ],
[ 0, 0, 0, 1 ]
];
function rotate(xyz) =
rotatex(xyz[0])
* rotatey(xyz[1])
* rotatez(xyz[2]);
module xrot(xyz) {
$m = $m * rotate(xyz);
rotate(xyz) children();
}
module xtrans(off) {
$m = $m * translate(off);
translate(off) children();
}
module xscale(s) {
$m = $m * scale(s);
scale(s) children();
}
// Place a unit cube (in local coordinates) at the origin.
// Place a label (with global-default parameters) at that point.
// Echo the label and the global coordinates.
module whereami(label) {
p = $m * [0,0,0,1];
echo(label,p);
cube(1, center=true);
multmatrix(matrix_invert($m)) translate([p.x,p.y,p.z]) text(label);
}
// Matrix inversion, from
//https://github.com/openscad/scad-utils/pull/1/files
function remove(list, i) = [for (i_=[0:1:len(list)-2]) list[i_ < i ? i_ : i_ + 1]];
function det(m) = let(r=[for(i=[0:1:len(m)-1]) i]) det_help(m, 0, r);
function det_help(m, i, r) = len(r) == 0 ? 1 :
m[len(m)-len(r)][r[i]]*det_help(m,0,remove(r,i)) - (i+1<len(r)? det_help(m, i+1, r) : 0);
function matrix_invert(m) = let(r=[for(i=[0:len(m)-1]) i]) [for(i=r) [for(j=r)
((i+j)%2==0 ? 1:-1) * matrix_minor(m,0,remove(r,j),remove(r,i))]] / det(m);
function matrix_minor(m,k,ri, rj) = let(len_r=len(ri)) len_r == 0 ? 1 :
m[ri[0]][rj[k]]*matrix_minor(m,0,remove(ri,0),remove(rj,k)) - (k+1<len_r?matrix_minor(m,k+1,ri,rj) : 0);
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org