public static void EigenSolve(Matrix4x4 D, out Vector3 S, out Matrix4x4 V) { // D is symmetric // S is a vector whose elements are eigenvalues // V is a matrix whose columns are eigenvectors S = EigenValues(D); Vector3 V0, V1, V2; if (S[0] - S[1] > S[1] - S[2]) { V0 = EigenVector(D, S[0]); if (S[1] - S[2] < Mathf.Epsilon) { V2 = V0.unitOrthogonal(); } else { V2 = EigenVector(D, S[2]); V2 -= V0 * Vector3.Dot(V0, V2); V2 = Vector3.Normalize(V2); } V1 = Vector3.Cross(V2, V0); } else { V2 = EigenVector(D, S[2]); if (S[0] - S[1] < Mathf.Epsilon) { V1 = V2.unitOrthogonal(); } else { V1 = EigenVector(D, S[1]); V1 -= V2 * Vector3.Dot(V2, V1); V1 = Vector3.Normalize(V1); } V0 = Vector3.Cross(V1, V2); } V = Matrix4x4.identity; V.SetColumn(0, V0); V.SetColumn(1, V1); V.SetColumn(2, V2); }
public static void EigenSolve(float3x3 D, out float3 S, out float3x3 V) { // D is symmetric // S is a vector whose elements are eigenvalues // V is a matrix whose columns are eigenvectors S = EigenValues(D); float3 V0, V1, V2; if (S[0] - S[1] > S[1] - S[2]) { V0 = EigenVector(D, S[0]); if (S[1] - S[2] < math.FLT_MIN_NORMAL) { V2 = V0.unitOrthogonal(); } else { V2 = EigenVector(D, S[2]); V2 -= V0 * math.dot(V0, V2); V2 = math.normalize(V2); } V1 = math.cross(V2, V0); } else { V2 = EigenVector(D, S[2]); if (S[0] - S[1] < math.FLT_MIN_NORMAL) { V1 = V2.unitOrthogonal(); } else { V1 = EigenVector(D, S[1]); V1 -= V2 * math.dot(V2, V1); V1 = math.normalize(V1); } V0 = math.cross(V1, V2); } V.c0 = V0; V.c1 = V1; V.c2 = V2; }