/// <summary> /// Make an orientation matrix from a direction. Note the rotation around the direction /// vector is not defined. 'axis' is the axis that 'direction' will become.</summary> public static m3x4 OriFromDir(AxisId axis, v4 dir, v4?up = null) { // Get the preferred up direction (handling parallel cases) var up_ = up == null || Parallel(up.Value, dir) ? Perpendicular(dir) : up.Value; var ori = m3x4.Identity; ori.z = Normalise(Sign(axis) * dir); ori.x = Normalise(Cross(up_, ori.z)); ori.y = Cross(ori.z, ori.x); // Permute the column vectors so +Z becomes 'axis' return(PermuteRotation(ori, Math.Abs(axis))); }
/// <summary>Create a rotation transform that maps 'from' to 'to'</summary> public static m3x4 Rotation(AxisId from, AxisId to) { // 'o2f' = the rotation from Z to 'from_axis' // 'o2t' = the rotation from Z to 'to_axis' // 'f2t' = o2t * Invert(o2f) m3x4 o2f, o2t; switch (from) { default: throw new Exception("axis_id must one of �1, �2, �3"); case -1: o2f = Rotation(0f, (float)+Math_.TauBy4, 0f); break; case +1: o2f = Rotation(0f, (float)-Math_.TauBy4, 0f); break; case -2: o2f = Rotation((float)+Math_.TauBy4, 0f, 0f); break; case +2: o2f = Rotation((float)-Math_.TauBy4, 0f, 0f); break; case -3: o2f = Rotation(0f, (float)+Math_.TauBy2, 0f); break; case +3: o2f = Identity; break; } switch (to) { default: throw new Exception("axis_id must one of �1, �2, �3"); case -1: o2t = Rotation(0f, (float)-Math_.TauBy4, 0f); break; // I know this sign looks wrong, but it isn't. Must be something to do with signs passed to cos()/sin() case +1: o2t = Rotation(0f, (float)+Math_.TauBy4, 0f); break; case -2: o2t = Rotation((float)+Math_.TauBy4, 0f, 0f); break; case +2: o2t = Rotation((float)-Math_.TauBy4, 0f, 0f); break; case -3: o2t = Rotation(0f, (float)+Math_.TauBy2, 0f); break; case +3: o2t = Identity; break; } return(o2t * Math_.InvertFast(o2f)); }
/// <summary> /// Make an orientation matrix from a direction. Note the rotation around the direction /// vector is not defined. 'axis' is the axis that 'direction' will become.</summary> public static m4x4 TxfmFromDir(AxisId axis, v4 direction, v4 translation, v4?up = null) { // Notes: use 'up' = Math_.Perpendicular(direction) Debug.Assert(FEql(translation.w, 1f), "'translation' must be a position vector"); return(new m4x4(OriFromDir(axis, direction, up), translation)); }