So, I have three orthogonal vectors and I wish to set my viewport to the 'top view' of these vectors. How would I go about doing that? I'm thinking that I would have to modify the $vpr variable, but how?

You just set the $vpt, $vpr and $vpd values in your OpenSCAD script, usually at the beginning, or at the toplevel (ie not in any module), of the main file, eg:
$vpt = [ 0,0,0 ]; $vpr = [ 60,0,30 ]; $vpd = 500; When you press F5, it will draw the scene from this viewpoint. For more information, see https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#.24vpr.2C_.24vpt_and_.24vpd When you come to animate your model, you can use $t ("time", is a value between 0 and 1, see https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#.24t ) to move the viewport around your object, eg: $vpt = [ 0, 0, 0 ]; $vpr = [ 90$t*30, 0.00, 30+$t*720 ]; $vpd = 500; Open the "animate" dialogue, set Time to 0, Steps to 720 and FPS to a number greater than 0 (depends on model complexity, and how quick your PC is at to how many FPS you can get). This should move the viewport around the object in a spiral motion, going up, but keep the focus on the origin. Ian 
Ok. Let's get a more generic example.
I have axis, represented by vectors A, B and C. I want to view that location as if it were the origin from the top view. How would I do that? 
$vpt sets the viewport translation, $vpr sets the rotation ( [0,0,0] sets the view from above), $vpd sets the distance. So...
$vpt = [ A,B,C ]; $vpr = [ 0,0,0 ]; You may need to set a distance, too. The current viewport vectors are shown in the bottom left of the OpenSCAD window, usually. Ian 
I don't understand. A, B and C are 3D vectors. $vpt is a triple of numbers. If A = [1,0,0], B = [0,1,0] and C = [0,0,1], then what you stated was $vpt = [[1,0,0], [0,1,0], [0,0,1]]; which is a triple of triples. That doesn't make sense.

Adrian,
You are right. Euler angles really sucks. It is the worst system to represent rotations. The rotation of $vpr should be defined by a vector of 3 Euler angles: the rotation angles about each of the original coordinate system to be applied to the viewport. Just like rotate(...) for children. The question, the answer to your question, is how to find this Euler angles given an orthogonal system for the viewport? To solve this problem we have to solve a trigonometric system of equations. Worst than that, there is many interpretation for the Euler angles. Even worst, depending on the coordinate system, the system of equations has infinite solutions! The following code includes a function, RM2EAxyz, that solves the problem above by converting a rotation matrix into a vector of the three Euler angles where the rotations are supposed to be applied in the order Rx*Ry*Rz. That is what you need. This code is an illustration of how to solve your problem and a test of the function RM2EAxyz. The first 3 lines generates an orthonormal reference system: the vectors ax, ay, az, besides being orthogonal, have unitary norm. With them we form a rotation matrix M and convert M to the Euler angle form with RM2EAxyz. Those Euler angles are assigned to $vpr. The following 3 lines draw the viewport axis with different colors. If you animate this code, you will see the original coordinate system (the system axis) rotating madly about the origin and the 3 drawn vectors completely motionless: red to the right, green to above and blue projected on the origin. 
Thanks Ronaldo, that's cool. I'm going to have to look into this further.
Thanks again! :) 
I have found two other methods to compute the Euler angles from a rotation matrix: I have superficially checked them.// a version found in // https://www.learnopencv.com/rotationmatrixtoeulerangles/ function RM2EAxyz2(M) = let( sy = norm([M[0][0],M[0][1]]) ) sy > 1e6 ? [ atan2(M[1][2],M[2][2]), atan2(M[0][2],sy), atan2(M[0][1],M[0][0]) ] : [ atan2(M[2][1], M[1][1]), atan2(M[0][2],sy), 0 ]; // a version found in // https://www.geometrictools.com/Documentation/EulerAngles.pdf function RM2EAxyz3(M) = M[0][2] < 1 ? [ atan2(M[1][2],M[2][2]), asin(M[0][2]), atan2(M[0][1],M[0][0]) ] : // Not a unique solution : // ang3 + ang1 = atan2(M[1][0], M[1][1]) [ atan2(M[1][0], M[1][1]), 90, 0 ] * sign(M[0][2]); _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by Ronaldo
Ronaldo said: "Euler angles really sucks. It is the worst system to represent rotations." Haha, that's a pretty strong statement. I am considering to use quaternions to represent 3D rotations in my new geometry engine. The upside is no gimbal lock, normalization, and the slerp function, which are real benefits. The downside is that the 4 numbers stored in a quaternion are incomprehensible to ordinary humans, so you need to use library functions to manipulate quaternions. Euler angles are at least easier to understand.https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles On 2 February 2017 at 00:20, Ronaldo <[hidden email]> wrote: Adrian, _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by Ronaldo
Thanks for that. Now that I know what to look for, I've found the wiki that states matrices that do the same thing:
https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix 
In reply to this post by doug.moen
On 20170202 20:58, doug moen wrote:
> Ronaldo said: "Euler angles really sucks. It is the worst system to > represent rotations." > > Haha, that's a pretty strong statement. I am considering to use > quaternions to represent 3D rotations in my new geometry engine. The > upside is no gimbal lock, normalization, and the slerp function, which > are real benefits. The downside is that the 4 numbers stored in a > quaternion are incomprehensible to ordinary humans, so you need to use > library functions to manipulate quaternions. Euler angles are at least > easier to understand. Describing the position and orientation of e.g. a camera in this case becomes awkward if you consider it as "3D rotations". It is well defined as a local coordinate system: A location for the location origin and 3 direction vectors (3 cosines each) for the local axes, all relative to the global coordinate system. All this again is simply expressed as a 4x4 homogenous transformation matrix, as in the multmatrix command. To modify the camera locaton and/or orientation you pre or postmultiply (depending on the wanted effect) with another matrix to get a new local coordinate system. Carste Arnholm _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by doug.moen
Let me clarify my statement. Euler angles is the one of the worst systems to represent rotations in a API. Quaternions would be even worst. I don't care which representation is used internally. It may be quaternions, Euler angles, whatever  what is better from the system point of view. But for the user, that means, in the language, neither one are acceptable. At least for me, with a nocomplexnumbers mind neither a pilot driver's licence. I live with the feet on earth, a 2D surface. I can turn right or left. I can't fly. To work with Euler angles means to compose 3 basic rotations. In my mind, I can compose 2 at most without twisting it. The most natural way to represent a rotation for me would be a direction and an angle. I can't see which rotation is represented in a rotation matrix the same way I can't see it in a quaternion. These are mathematical representations and not modeling tools! That is my question: which is the best modeling means to represent rotations? BTW, unitary coordinate system change is a rotation. 
Ronaldo said: "for the user, in the language ... which is the best modeling means to represent rotations?" Let's represent a 3D rotation as an abstract data type, call it Q. As a user you don't care about the internal representation. Construction of a Q: q = q_from_axis_and_angle(axis, angle)  axis is a [x,y,z] vector q = q_from_directions(forward_direction, upward_direction) q = q_from_xyz_angles(angles) From Euler angles, using the OpenSCAD convention. q = q_from_rotation_matrix(matrix) q = q_rotation_to(from_vector, to_vector) The shortest arc quaternion that rotates from the 'from' direction to the 'to' direction. q = q_slerp(q1, q2, t)Interpolates along the shortest spherical path between the rotational positions q1 and q2. The value t should be between 0 and 1. [axis, angle] = q_to_axis_and_angle(q) [forward_direction, upward_direction] = q_to_directions(q) [xangle,yangle,zangle] = q_to_xyz_angles(q) rotation_matrix = q_to_rotation_matrix(q) Applying a Q: vector = q_rotate(q, vector) matrix = q_rotate(q, matrix) rotate(q) shape  a possible extension to OpenSCAD Implementing this as an OpenSCAD library, I'd represent a Q as a quaternion, specifically as a 4vector, [x,y,z,s], so that's what you'd see if you echo'ed a Q. There are other possible internal representations for a Q, but the quaternion representation would be the most efficient. The internal representation shouldn't matter to users: you would not normally attempt to construct a Q directly, you'd only use the library functions. On 3 February 2017 at 09:28, Ronaldo <[hidden email]> wrote: doug.moen wrote _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Adrian said: So, I have three orthogonal vectors and I wish to set my viewport to the 'top view' of these vectors. How would I go about doing that? I'm thinking that I would have to modify the $vpr variable, but how? q_from_axes(xaxis, yaxis, zaxis) to my proposed Q library, then Adrian could probably write $vpr = q_to_xyz_angles(q_from_axes(xaxis, yaxis, zaxis)); I haven't actually started to write any quaternion code yet. But there are lots of open source packages to copy from, and the QT5 code could be starting point. Eg, On 3 February 2017 at 11:29, doug moen <[hidden email]> wrote:
_______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
dough,
I like the idea of having conversion functions from one rotation representations to the others. They are simple enough to be written in OpenSCAD and be efficient. They should be part of a OpenSCAD standard library. I have however doubts about using quaternions as an internal representation in OpenSCAD and have an abstract object rotation to be used as argument of rotate() for instance. The main advantage of quaternions seems to be in applications where a long sequence of small rotations should be applied. In this case, troubles due to numerical errors are easier to correct by normalization of quaternions than normalization of a rotation matrix. This advantage is the reason of its success in animation. But I don't see OpenSCAD incorporating real animation resources in a mid term. The only OpenSCAD operation I see now that could benefit from this quaternion superiority is sweep (rotate_extrude, linear_extrude with twist and sweep operations similar to the Oskar Linde's one) and even so if we need a very very refined discretization. I don't know how it is coded in C, but I don't see any presence of approximation errors with rotate_extrude with $fn=1000. An other point to consider is time expended in operations with quaternions. Composing quaternion rotations is faster than rotation matrix multiplications. But applying quaternions to rotate points is quite slower. So, in an application with a complex model, it is recommended to convert the quaternion rotation to a matrix rotation before rotating points. It seems to me that typical OpenSCAD codes will not benefit from the composing speed of quaternions. Gimbal lock is an issue just to the representation by Euler angles and quaternions are equivalent to the other representations in this aspect. So, I would like you to know which is the benefits you see in using quaternions over other representations (excluding Euler angles) in the context of OpenSCAD codes? 
Ronaldo said "applying quaternions to rotate points is quite slower." I didn't know this. Rotating a point using quaternions is 24 multiplications, vs 9 multiplications (using a 3x3 rotation matrix) or 16 multiplications (using a 4x4 rotation matrix). If you are performing a large number of these quaternion operations during each frame of a video game, then it could be a significant performance hit, relative to using a 3x3 rotation matrix. Especially since I suspect GPUs have hardware support for matrix multiplication. In the context of game programming, you want to have both rotation matrixes and quaternions available as tools. In OpenSCAD, execution time of a script is *usually* not an issue, it's usually CGAL operations on complex objects that limit performance. The evaluator is extremely slow compared to C, so if the performance of the rotation library does turn out to be important, then hard coding the operations in C is going to have a much bigger impact than the actual representation chosen for 3D rotations. The other general representation that makes sense to me is a 3x3 rotation matrix. A few of the operations I specified would require conversion to/from quaternions to implement, so you'd still like a quaternion library to implement those operations: q_from_axis_and_angle(), q_rotation_to(from, to) and q_slerp(q1,q2,t). Slerp is quite useful for animation. General purpose 3D graphics libraries provide both matrices and quaternions, so I guess the right answer is to support both. On 6 February 2017 at 09:47, Ronaldo <[hidden email]> wrote: dough, _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Free forum by Nabble  Edit this page 