 # What is the right method to convert quaternion to plane using rhinocommon

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;
}``````
1 Like

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);
}``````
1 Like

Do you also know conversion to construct Quaternion from Euler angles?

``````  /// <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;
}
``````
1 Like

Thank you very very much Martin Baker’s site also has a good collection of conversions between all the different rotation representations

1 Like

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, …

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)

This is the Unity conversion, is it somehow possible to use your method when Euler angles in Unity are YXZ ?

In whatever order I am swapping quaternion values,
it does not produce good result.