# rotate([45,45,0])

12 messages
Open this post in threaded view
|

## rotate([45,45,0])

 hi i dont like this instruction because it is not clear in the formalism wether x or y are calculated first see this example, where tube is any module : //rotate([0,45,0]) rotate([45,0,0]) tube(); rotate([45,0,0]) rotate([0,45,0]) tube(); rotate([45,45,0]) tube(); now, i needed something to automatically put a z-oriented object (say, a cylinder) to any [x,y,z] direction if it can be usegul : module pointervers(v) {     //v=[x,y,z]     x=v[0];     y=v[1];     z=v[2];     rho=sqrt(x*x+y*y+z*z);     r=sqrt(x*x+y*y);     phi=acos(z/rho);     if (r!=0)         {theta=acos(x/r)*sign(asin(y/r));}     else // cas d'un vecteur v=[0,0,-1]         {theta=0;}     echo(theta);     for (i=[0,\$children-1])     {         rotate([0,0,theta]) rotate([0,phi,0]) children([i]);     }     } -- Sent from: http://forum.openscad.org/_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: rotate([45,45,0])

 > i dont like this instruction because it is not clear in the formalism wether x or y are calculated first That's one of the reasons I've made some helper modules: xrot(angle) yrot(angle) zrot(angle) Usually, I only rotate on one axis at the time, and it gives neater code. I also have similar modules for xtran, ytran and ztran, just to get cleaner code. -- Sent from: http://forum.openscad.org/_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: rotate([45,45,0])

 now, i needed something to automatically put a z-oriented object (say, acylinder) to any [x,y,z] directionif it can be usegul :‌​I don't like the rotation by Euler angle​s either. In general it seems more useful something like you did. My version is a bit more general and simpler:module rotFromTo(di,do)     if( norm(di-do)==0 || norm(di)==0 || norm(do)==0 )         children();    else         mirror(do/norm(do)+di/norm(di)) mirror(di) children();It applies the least angle rotation that brings vector di to vector do. _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: rotate([45,45,0])

 @ Ronaldo, it's so amazing to me that this can be done in such a concise way. I think it'd be good especially for alignment 'cos no knowledge of angle is required. In the mean time, readers are welcome to check out my version, which allows for rotating solid obj or a list points about any axis in the space:
https://github.com/runsun/OpenSCAD_Tips/blob/master/snippets.md#rotate_anyaxis// Rotate an obj: rotObj( pq,a ) obj(); // Rotate points: rotPts( pts, pq, a ); function rotM(pq,a) = (  let(         uv = ( pq[0]-pq[1])/norm(pq[1]- pq[0]) // unit vector       , x=uv[0]       , y=uv[1]       , z=uv[2]       , c=cos(a)       , s=sin(a)       , t=1-c       )       [ [ t*(x*x)+c,   t*(x*y)-s*z, t*(x*z)+s*y ]       , [ t*(x*y)+s*z, t*(y*y)+c,   t*(y*z)-s*x ]       , [ t*(x*z)-s*y, t*(y*z)+s*x, t*(z*z)+c   ]       ] );   module rotObj( pq, a ) {     translate( pq[1] )     multmatrix(m= rotM( pq,a) )     {        translate( -1*pq[1] )        children();     }           } function rotPt(pt,pq,a)= rotM(pq,a)*(pt-pq[0]) + pq[0] ; function rotPts(pts,pq,a)= [ for(p=pts) rotPt(p,pq,a) ] ;
----- \$  Runsun Pan, PhD \$ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); \$ Tips ; \$ Snippets -- Sent from: http://forum.openscad.org/_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org \$ Runsun Pan, PhD \$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); \$ Tips; \$ Snippets
Open this post in threaded view
|

## Re: rotate([45,45,0])

 From runsun :@ Ronaldo, it's so amazing to me that this can be done in such a concise way. I think it'd be good especially for alignment 'cos no knowledge of angle is required. ‌​The principle behind is that any rotation may expressed by composing two reflections (mirror)​. In this case, you don't need to compute angles to find the reflections.Besides the operator rotFromTo, I have a functional version of it that computes the rotation matrix:function TrotFromTo(di,do) =    norm(di-do)==0 || norm(di)==0 || norm(do)==0 ?         [[1,0,0],[0,1,0],[0,0,1]] :        Tmirror(do/norm(do)+di/norm(di)) * Tmirror(di);As expected, it requires a function returning the mirror transformation matrix:function Tmirror(v) =    norm(v)==0 ?        [[1,0,0],[0,1,0],[0,0,1]] :       let(u = v/norm(v))       [ [1,0,0] - 2*u[0]*u, [0,1,0] - 2*u[1]*u, [0,0,1] - 2*u[2]*u ]; _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: rotate([45,45,0])

 hi i am working on your codes, but i enconter something that i dont understand : if (3!=0) {a=2;echo(a);} echo(a); the second echo(a); returns "undef" as if the variable a was defined only inside the {if} how shall i understand this ? Vincent _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: rotate([45,45,0])

 On 5/18/2018 12:18 AM, Vincent Douce Mathoscope wrote: ```hi i am working on your codes, but i enconter something that i dont understand : if (3!=0) {a=2;echo(a);} echo(a); the second echo(a); returns "undef" as if the variable a was defined only inside the {if} how shall i understand this ? ``` This might well be the most common OpenSCAD question. OpenSCAD variables... aren't variables.  They're constants, sort of, with the last assignment winning and with inner scopes able to override values from outer scopes.  You can't change them, or at least not exactly, and you especially can't change them inside an "if". ```x=1; echo(x=x); x=2; echo(x=x); ``` produces ```ECHO: x = 2 ECHO: x = 2 ``` and ```x=1; echo(x=x); if (true) { x=2; echo (x=x); } echo (x=x); ``` produces ```ECHO: x = 1 ECHO: x = 2 ECHO: x = 1``` If you need to set a value conditionally, you need to use the ? : operator, e.g. ```a = (3 != 0) ? 2 : 1; ``` _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Open this post in threaded view
|

## Re: rotate([45,45,0])

 In reply to this post by Ronaldo @ Ronaldo, Thx for sharing. Your code, as usual, is concise and elegant. It's also much easier to use than mine for rotations around the origin. ----- \$  Runsun Pan, PhD \$ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); \$ Tips ; \$ Snippets -- Sent from: http://forum.openscad.org/_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org \$ Runsun Pan, PhD \$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); \$ Tips; \$ Snippets
Open this post in threaded view
|

## Re: rotate([45,45,0])

 In reply to this post by vincent_mathoscope @ vincent, Your issue with the variable can be solved by changing this part of your code, > if (r!=0) >         {theta=acos(x/r)*sign(asin(y/r));} >     else // cas d'un vecteur v=[0,0,-1] >         {theta=0;} to > theta= r!=0? acos(x/r)*sign(asin(y/r)):0; Also, note that your code is not a one-step rotation as you described in "put a z-oriented object (say, a cylinder) to any [x,y,z] direction". There's an extra twist other than the rotation from z to [x,y,z]. Suppose we want to rotate a cube from *P=[0,0,4]* to *Q=[2,2,2]*. This would imply a rotation about axis [[-1,1,0],[0,0,0],[1,-1,0]] (red line below) by an angle= *54.7356* : Both of Ranaldo's and my codes, > module C(){ translate([-2,0,0]) cube([2,1,3]); } > P= [0,0,4]; > Q= [2,2,2]; > color("green") rotFromTo( di=P, do=Q) C();  // Ronaldo's code > color("green") rotObj( axis=[[-1,1,0],[1,-1,0]], a= 54.7356 ) C();  // > runsun's code result in the same outcome: Your code: > color("red") pointervers(Q)  C(); results in : I'm not sure if that's intended. The twist is hard to spot if the starting obj is a cylinder aligning w/ the z-axis. IMO, the extra twist makes it harder to use in the context of "put a z-oriented objec to any [x,y,z] direction". ----- \$  Runsun Pan, PhD \$ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); \$ Tips ; \$ Snippets -- Sent from: http://forum.openscad.org/_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org \$ Runsun Pan, PhD \$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); \$ Tips; \$ Snippets
Open this post in threaded view
|

## Re: rotate([45,45,0])

 ​​Module ​pointervers(v) produces a rotation that brings [0,0,1] to v.My module rotFromTo(di,do) produces a rotation that brings di to do.​The point is that there is an infinite set of rotations that bring a vector to another.​ For instance,rotFromTo(w,d0) rotFromTo(di,w)​is able to bring di to do with a different rotation for (almost) any ​other vector w.rotFromTo chooses one specific rotation among that set: the rotation with the minimum angle. The minimum rotation is unique and well defined: its axis is cross(di,do).In general, module pointvers(v) does not compute the minimum rotation (except in trivial cases). That is fine but it has a major drawback: it is not continuous in v. I would expect that for v very near to [0,0,1], pointvers(v) be very near to the identity and that is not true. For v near to [0,0,1], the internally computed angle phi is near to 0 but theta is not.‌ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org