Rotation question

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Rotation question

Maurice van Peursem
Hi,

A plane is defined by O, X (x1,x2,x3) and Y (y1,y2,y3). What is the
(simplest) way to rotate this plane so that O stays O and both X and
Y rotate to the x, y plane (immaterial where)?

I want to lay an object flat on my printer table, and Cura refuses to
do it unfortunately...

Thanks,
Maurice

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rotation question

nophead
Not sure what what you mean exactly by X(x1,x2,x3) but if you have a plane defined by three points you can calculate its normal by taking the cross product of two vectors between the points.

If you do that for two planes then you have two normals and you need to rotate on to match the other. The is a neat way to do that with mirror that had been posted in the forum.

If you are taking about 3d printer bed leveling then this might help: http://hydraraptor.blogspot.com/2011/04/auto-bed-leveling.html

On Sun, 16 Dec 2018, 03:00 Maurice van Peursem <[hidden email] wrote:
Hi,

A plane is defined by O, X (x1,x2,x3) and Y (y1,y2,y3). What is the
(simplest) way to rotate this plane so that O stays O and both X and
Y rotate to the x, y plane (immaterial where)?

I want to lay an object flat on my printer table, and Cura refuses to
do it unfortunately...

Thanks,
Maurice

_______________________________________________
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
Reply | Threaded
Open this post in threaded view
|

Re: Rotation question

Ronaldo
Complementing @nophead suggestion, you may find a rotation that brings the plane normal cross(X-O, Y-O) to [0,0,1] either as a matrix frotFromTo or a module rotFromTo, both found in 






_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
rew
Reply | Threaded
Open this post in threaded view
|

Re: Rotation question

rew
In reply to this post by nophead
On Sun, Dec 16, 2018 at 10:05:31AM +0000, nop head wrote:
> Not sure what what you mean exactly by X(x1,x2,x3) but if you have a plane
> defined by three points you can calculate its normal by taking the cross
> product of two vectors between the points.

That's not   what he's asking.  We have  a  point X  defined  by three
coordinates (x,y,z) = (x1, x2, x3)

Then he wants to rotate space, such that this point will rotate to
somewhere on the XY plane.

I will chose to rotate around the X axis. To visualize this, project
everything onto the YZ plane. So our point (x1, x2, x3) becomes (0,
x2, x3). Now when we rotate this by -atan (x3/x2) our point should end
up on the XY  plane.

Alas I now don't know how to get the coordinates of the rotated X point,
but you can calculate it with something like:
  x1' = x1
  x2' = x2 * cos (-atan(x3/x2)) - x3 * sin(-atan(x3/x2));
  x3' = x3 * cos (-atan(x3/x2)) - x2 * sin(-atan(x3/x2));

Recalculate Y' the same way.

Now we can rotate along the Z axis. to make X'' coincide with the
positive X axis. Again a rotation by an angle with -atan
(something/something) .

Recalculate Y'' as where Y' ends up after this rotation.

Now the only thing we have to do is to rotate by -atan (Y''3/Y''2)
along the X axis again. Voila!

        Roger.



>
> If you do that for two planes then you have two normals and you need to
> rotate on to match the other. The is a neat way to do that with mirror that
> had been posted in the forum.
>
> If you are taking about 3d printer bed leveling then this might help:
> http://hydraraptor.blogspot.com/2011/04/auto-bed-leveling.html
>
> On Sun, 16 Dec 2018, 03:00 Maurice van Peursem <[hidden email]
> wrote:
>
> > Hi,
> >
> > A plane is defined by O, X (x1,x2,x3) and Y (y1,y2,y3). What is the
> > (simplest) way to rotate this plane so that O stays O and both X and
> > Y rotate to the x, y plane (immaterial where)?
> >
> > I want to lay an object flat on my printer table, and Cura refuses to
> > do it unfortunately...
> >
> > Thanks,
> > Maurice
> >
> > _______________________________________________
> > 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


--
** [hidden email] ** http://www.BitWizard.nl/ ** +31-15-2049110 **
**    Delftechpark 11 2628 XJ  Delft, The Netherlands. KVK: 27239233    **
*-- BitWizard writes Linux device drivers for any device you may have! --*
The plan was simple, like my brother-in-law Phil. But unlike
Phil, this plan just might work.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rotation question

Parkinbot
In reply to this post by Maurice van Peursem
This is your code. It uses two rotations, one around the y axis and the other
one around the x axis.
You can play with the vectors.


X = [3, -2, .10];
Y = [2, 0, 3];

vector(X, .02, "red");
vector(Y, .02, "blue");

x = X/norm(X);  // 1st rotation

X_ = mmult(rotxz(x), [X]);  // rot X by X projected to xz
Y1 = mmult(rotxz(x), [Y]);  // rot Y by X projected to xz
y = Y1/norm(Y1); // second rotation
Y_ = mmult(rotyz(y), [Y1]); // rot Y1 by Y1 projected to yz

vector(X_, 0.02, "black");
vector(Y_, 0.02, "white");

function rotxz(d) =
  [[d[0],  0, d[2]],
   [0,     1, 0],
   [-d[2], 0, d[0]]];  
       
function rotyz(d) =
  [[1, 0,    0],
   [0, d[1], d[2]],
   [0, -d[2], d[1]]];  

function mmult(X, Y) = len(X) != len(Y[0])? undef:
  [for(i=[0:len(Y)-1])
   [for(j=[0:len(X[0])-1])
     X[j]*Y[i]]][0];
   
   
module vector(p1=[100,100], r=undef, color=undef, reverse=false)
{
  t = reverse?p1:[0,0,0];
  s = reverse?-1:1;
  r = r==undef?norm(p1)/100:r;
 
  translate(t)scale(s)
  if(color) color(color) vec();
    else vec();
  module vec()
  {
    l = norm(p1);
    v = p1/l;
    hull()
    {
      sphere(r);
      translate((l-5*r)*v) sphere(r);
    }
    hull()
    {
      translate((l-5*r)*v) sphere(2*r);
      translate(p1) sphere(r/10);
    }
  }
}



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rotation question

Maurice van Peursem
Hi Parkinbot,

Thanks, but it doesn't do what I want. I've built a whole structure,
and I want to rotate the structure so it will lay horizontally
according to the 2 vectors, but the structure itself must stay
unchanged. If I feed in these vectors in your script:

X = [1, 1, 1];
Y = [0, 0, 1];

The angle between X and Y changes. Or do I interpret your script wrongly?

Rogier Wolff gives a hint of how to do it, but it is not a complete
solution unfortunately...

Maurice



>This is your code. It uses two rotations, one around the y axis and the other
>one around the x axis.
>You can play with the vectors.
>
>X = [3, -2, .10];
>Y = [2, 0, 3];
>
>vector(X, .02, "red");
>vector(Y, .02, "blue");
>
>x = X/norm(X);  // 1st rotation
>
>X_ = mmult(rotxz(x), [X]);  // rot X by X projected to xz
>Y1 = mmult(rotxz(x), [Y]);  // rot Y by X projected to xz
>y = Y1/norm(Y1); // second rotation
>Y_ = mmult(rotyz(y), [Y1]); // rot Y1 by Y1 projected to yz
>
>vector(X_, 0.02, "black");
>vector(Y_, 0.02, "white");
>
>function rotxz(d) =
>   [[d[0],  0, d[2]],
>    [0,     1, 0],
>    [-d[2], 0, d[0]]];
>      
>function rotyz(d) =
>   [[1, 0,    0],
>    [0, d[1], d[2]],
>    [0, -d[2], d[1]]];
>
>function mmult(X, Y) = len(X) != len(Y[0])? undef:
>   [for(i=[0:len(Y)-1])
>    [for(j=[0:len(X[0])-1])
>      X[j]*Y[i]]][0];
>  
>  
>module vector(p1=[100,100], r=undef, color=undef, reverse=false)
>{
>   t = reverse?p1:[0,0,0];
>   s = reverse?-1:1;
>   r = r==undef?norm(p1)/100:r;
>
>   translate(t)scale(s)
>   if(color) color(color) vec();
>     else vec();
>   module vec()
>   {
>     l = norm(p1);
>     v = p1/l;
>     hull()
>     {
>       sphere(r);
>       translate((l-5*r)*v) sphere(r);
>     }
>     hull()
>     {
>       translate((l-5*r)*v) sphere(2*r);
>       translate(p1) sphere(r/10);
>     }
>   }
>}
>
>
>
>--
>Sent from: http://forum.openscad.org/
>
>_______________________________________________
>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
Reply | Threaded
Open this post in threaded view
|

Re: Rotation question

Maurice van Peursem
In reply to this post by Maurice van Peursem
I've been looking for an answer to this question for quite some time,
but in the end it turned out easier than I thought. I've defined 3
points (P1, P2 and P3) in space that I want to lay flat (i.e.
parallel to the X - Y plane). Firstly, I translate P1 to the origin
so I get what I described in the question, then I take the
cross-product of the two other (translated) points, en determine the
spherical coordinates of the endpoint of this product. Then 2
rotations will rotate this vector to make it point in the direction
of the Z-axis. The rotated points P1', P2' and P3' are not in the X -
Y plane, but that is no problem, the slicer will fix that.

Maurice

P1=[1,2,3];
P2=[3,4,5];
P3=[-5,6,1];

D=.3;


hull(){                     // original plane
     translate(P1)
         sphere(D);
     translate(P2)
         sphere(D);
     translate(P3)
         sphere(D);
}

P12=P2-P1;                  // translate P1 to origin
P13=P3-P1;
Cr=cross(P12,P13);          // calculate cross product

R=norm(Cr);                 // calculate spherical coordinates
Inclin=acos(Cr.z/R);
Azim=atan2(Cr.y,Cr.x);

rotate([0,-Inclin,0])       // and rotate accodingly
     rotate([0,0,-Azim])
         color("Red")
             hull(){         // rotated plane
                 translate(P1)
                     sphere(D);
                 translate(P2)
                     sphere(D);
                 translate(P3)
                     sphere(D);
             }


>Hi,
>
>A plane is defined by O, X (x1,x2,x3) and Y (y1,y2,y3). What is the
>(simplest) way to rotate this plane so that O stays O and both X and
>Y rotate to the x, y plane (immaterial where)?
>
>I want to lay an object flat on my printer table, and Cura refuses
>to do it unfortunately...
>
>Thanks,
>Maurice

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rotation question

Parkinbot
In reply to this post by Parkinbot
Sorry, there must be a bug choosing the rotations

The usual solution is to create an orthogonal base and use it as
transformation. So try this:

X = [1, 1, 1];
Y = [0, 0, 1];

vector(X, .02, "red");
vector(Y, .02, "blue");

x = X/norm(X);   // unit length
y_ = Y/norm(Y);  // unit length
y = y_-x*(x*y_); // orthogonal to x
z = cross(x,y);  // orthogonal to x and y

X1 = mmult([x,y,z], [X]);
Y1 = mmult([x,y,z], [Y]);

vector(X1, 0.02, "black");
vector(Y1, 0.02, "white");

function mmult(X, Y) = len(X) != len(Y[0])? undef:
  [for(i=[0:len(Y)-1])
   [for(j=[0:len(X[0])-1])
     X[j]*Y[i]]][0];




--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rotation question

Parkinbot
and last but not least: I forgot to unify the lenght of y and z. So the
proper coordinate system is:


x = X/norm(X);   //
y_ = Y/norm(Y);  //
y1 = y_-x*y_*x; // orthogonal to x
y = y1/norm(y1);
z1 = cross(x,y);  // orthogonal to x and y
z = z1/norm(z1);




--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rotation question

nophead
> The rotated points P1', P2' and P3' are not in the X - Y plane, but that is no problem, the slicer will fix that.

A simple translate(-P1) before the hull leaves the result on the XY plane.

On Mon, 17 Dec 2018 at 01:39, Parkinbot <[hidden email]> wrote:
and last but not least: I forgot to unify the lenght of y and z. So the
proper coordinate system is:


x = X/norm(X);   //
y_ = Y/norm(Y);  //
y1 = y_-x*y_*x; // orthogonal to x
y = y1/norm(y1);
z1 = cross(x,y);  // orthogonal to x and y
z = z1/norm(z1);




--
Sent from: http://forum.openscad.org/

_______________________________________________
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
Reply | Threaded
Open this post in threaded view
|

Re: Rotation question

Ronaldo
In reply to this post by Parkinbot
As I said, rotFromTo() is all you need:

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();
   
module axis(x,y){
  color("red") hull() {sphere(0.01*norm(x)); translate(x) sphere(0.01*norm(x)); }
  color("blue") hull() {sphere(0.01*norm(y)); translate(y) sphere(0.01*norm(y)); }
}
  
module object(x,y,colour=undef) {
  axis(x,y);
  color(colour)
  polyhedron([[0,0,0], x, y, cross(x,y)/norm(x)/norm(y)+(x+y)/3],
             [[0,1,2],[3,2,1],[3,1,0],[3,2,0], ]);
}
  
X = [-1,2,1];
Y = [1,1,1];

object(X,Y);
translate([(norm(X)+norm(Y))/2,0,0]) 
  rotFromTo(cross(X,Y),[0,0,1]) 
    object(X,Y,"magenta");
translate([(norm(X)+norm(Y)),0,0]) 
  rotFromTo(cross(Y,X),[0,0,1]) 
    object(X,Y,"green");
laydown.PNG
Maurice van Peursem <[hidden email]> wrote:
Thanks, but it doesn't do what I want. I've built a whole structure,
and I want to rotate the structure so it will lay horizontally
according to the 2 vectors, but the structure itself must stay
unchanged.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Rotation question

Parkinbot
Ronaldo,
 
cool! I didn't follow your link, but now I remember.



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org