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 |
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, _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
>
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 _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org |
In reply to this post by Parkinbot
As I said, rotFromTo() is all you need:
Thanks, but it doesn't do what I want. I've built a whole structure, _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org |
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 |
Free forum by Nabble | Edit this page |