What would be the way to convert Quaternion to plane in Rhino?
Lets say I have Quaternion q.
Can I write Plane plane = new Plane(q.A,q.B,q.C,q.D); ?
What would be the way to convert Quaternion to plane in Rhino?
Lets say I have Quaternion q.
Can I write Plane plane = new Plane(q.A,q.B,q.C,q.D); ?
Two ways
Rhinocommon
Quaternion.GetRotation(out Plane)
https://developer.rhino3d.com/wip/api/RhinoCommon/html/M_Rhino_Geometry_Quaternion_GetRotation.htm
Or I made that (I see that there are other method that I can join if needed)
//! <summary>
//! Fonction pour reproduire la fonction de RhinoCommon Instance de Quaternion.GetRotation(out Plane)
//! </summary>
//! <param name="arg_quat">Quaternion</param>
//! <returns></returns>
public static Plane GetPlaneFromQuaternion(Quaternion arg_quat)
{
//TODO ne doit pas être très fiable pour les valeurs proches de 0
double yaw=0;
double pitch=0;
double roll=0;
// arg_quat.Unitize();//NĂ©cessaire // Rhinocommon
arg_quat = GUtil.Unitize(arg_quat);//NĂ©cessaire //Rhino3dmIO
ToEulerAngles(arg_quat, out yaw, out pitch, out roll);
Plane plane = Plane.WorldXY;
Transform tf_yaw = Transform.Rotation(yaw, Vector3d.ZAxis, Point3d.Origin);
Transform tf_pitch = Transform.Rotation(pitch, Vector3d.YAxis, Point3d.Origin);
Transform tf_roll = Transform.Rotation(roll, Vector3d.XAxis, Point3d.Origin);
Transform tf = tf_yaw * tf_pitch * tf_roll;
plane.Transform(tf);
return plane;
}
Thank you, it is also nice to see Euler angles implementation.
It is not an effective way but it was done to test methods
//! <summary>
//! Quaternion to Euler Angles Conversion
//! https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
//! </summary>
//! <param name="q"></param>
//! <param name="yaw"></param>
//! <param name="pitch"></param>
//! <param name="roll"></param>
public static void ToEulerAngles(Quaternion q, out double yaw, out double pitch, out double roll)
{
// roll (x-axis rotation)
double sinr_cosp = 2 * (q.A * q.B + q.C * q.D);
double cosr_cosp = 1 - 2 * (q.B * q.B + q.C * q.C);
roll =Math.Atan2(sinr_cosp, cosr_cosp);
// pitch (y-axis rotation)
double sinp = 2 * (q.A * q.C - q.D * q.B);
if (Math.Abs(sinp) >= 1)
pitch = Math.Sign(sinp) * Math.PI; // use 90 degrees if out of range
else
pitch = Math.Asin(sinp);
// yaw (z-axis rotation)
double siny_cosp = 2 * (q.A * q.D + q.B * q.C);
double cosy_cosp = 1 - 2 * (q.C * q.C + q.D * q.D);
yaw = Math.Atan2(siny_cosp, cosy_cosp);
}
The fast way is this
public static void ToPlane(Quaternion quat, out Plane plane)
{
Quaternion vx = new Quaternion(0, 1, 0, 0);
Quaternion vy = new Quaternion(0, 0, 1, 0);
vx = quat * vx * quat.Conjugate;
vy = quat * vy * quat.Conjugate;
plane = new Plane(Point3d.Origin, vx.Vector, vy.Vector);
}
Do you also know conversion to construct Quaternion from Euler angles?
Here something I already have
/// <summary>
/// Euler Angles to Quaternion Conversion
/// https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
/// </summary>
/// <param name="yaw"></param>
/// <param name="pitch"></param>
/// <param name="roll"></param>
/// <returns></returns>
public static Quaternion ToQuaternion(double yaw, double pitch, double roll) // yaw (Z), pitch (Y), roll (X)
{
// Abbreviations for the various angular functions
double cy = Math.Cos(yaw * 0.5);
double sy = Math.Sin(yaw * 0.5);
double cp = Math.Cos(pitch * 0.5);
double sp = Math.Sin(pitch * 0.5);
double cr = Math.Cos(roll * 0.5);
double sr = Math.Sin(roll * 0.5);
Quaternion q;
q = Quaternion.Zero;
q.A = cy * cp * cr + sy * sp * sr;
q.B = cy * cp * sr - sy * sp * cr;
q.C = sy * cp * sr + cy * sp * cr;
q.D = sy * cp * cr - cy * sp * sr;
return q;
}
Thank you very very much
Martin Baker’s site also has a good collection of conversions between all the different rotation representations
Thanks @DanielPiker
You are welcome as I have done a 6DoF simulation model for flying things, all that stuff is quite useful.
Can we see it ?
It seems I am again stuck in Unity and Rhino conversions.
I have a quaternion (0,0,1,0), by converting this quaternion to Euler angles in Unity I get (0,0,180), while using your formula I get (180,0,180), I tried both @DanielPiker and @laurent_delrieu and I get (180,0,180).
I am wondering if by any chance you know what is happening at Unity side when Quaternion is converted to Euler angles and how can I get (0,0,180)?
Unfortunately no, it is a work done for my job.
For the problem of angles, it is surely due to the axes. I use “aeronautic” one. X is in front, Z under, and Y to the right side so all angles are on the “good” direction, roll on X, …
https://www.grc.nasa.gov/www/k-12/airplane/rotations.html
Or could it be because unity Quaternion are xyxw instead of wxyz in Rhino?
Yup tried that it does not work due to different axis system I am quite lost, because I want to replicate Quternion.eulerAngles method and it does not produce good result.
And as we know Unity forum is like a desert comparing to McNeel.
I also looked at source code, but this method is C++ and is not open for developer:
Did you look at my last comment about the fact that it seems that quaternion are not coded the same xyzw vs wxyz ?
Hmm, this produces (180,0,0) instead of (0,0,180)
Unity and rhino XYZ differs like this XZY, still not quite good
I will try to have a look tonight… Axis transformation are always a bit tricky
Thanks, it would be a great help for me.
What is also wierd that Unity print degrees between 0 to 360, while rhino from 0 to 180
This one in Unity:
Quaternion testQ = new Quaternion(0.1f, 0.2f, 0.4f, 0.5f);
Vector3 testA = testQ.eulerAngles;
results in vector (352.5, 37.9,74.7)