The rotation matrix between two vectors can be found by taking the dot product, taking the arc cosine of that value, determining the cross product of the 2 vectors you are comparing, then finally creating the matrix using the angle and cross vector.

01 | public static Matrix GetRotationMatrix(this Vector3 source, Vector3 target) |

02 | { |

03 | float dot = Vector3.Dot(source, target); |

04 | if (!float.IsNaN(dot)) |

05 | { |

06 | float angle = (float)Math.Acos(dot); |

07 | if (!float.IsNaN(angle)) |

08 | { |

09 | Vector3 cross = Vector3.Cross(source, target); |

10 | cross.Normalize(); |

11 | Matrix rotation = Matrix.CreateFromAxisAngle(cross, angle); |

12 | return rotation; |

13 | } |

14 | } |

15 | return Matrix.Identity; |

16 | } |

Hi,

I’ve tried to use this method to create the rotation matrix between two vectors so I wrote this to test it:

Vector3 x = new Vector3(1, 0, 0);

Vector3 y = new Vector3(0, 1, 0);

Matrix m = GetRotationMatrix(x, y);

Vector3 res = Vector3.Transform(x, m);

But: y != res ( res = {X:-4,371139E-08 Y:1 Z:0} )

Did I mess up something?

(Sorry for my English)

I think the solution is not to check equality but check for a range +/- epsilon.

Anyway thanks for the code.

Okay, I understand what you mean by +/- epsilon, and you’re exactly right. using the case of the example you gave, (1,0,0) to (0,1,0), the code returns a matrix, which once applied results in the vector (-0.00000004371139, 1, 0). It struck me as weird at first because the unit test I was using failed, but the reason it failed is due to a rounding issue. Here’s another extension method I added on to Vector3 earlier on which will help deal with this:

public static Vector3 Round(this Vector3 source, int decimals)

{

Vector3 rounded = source;

rounded.X = (float)Math.Round(rounded.X, decimals);

rounded.Y = (float)Math.Round(rounded.Y, decimals);

rounded.Z = (float)Math.Round(rounded.Z, decimals);

return rounded;

}