/// <summary> /// Assume the following structure, return the determinant coeficients for v0, v1, v2, v3 /// v0 v1 v2 v3 /// x00 x01 x02 x03 /// x10 x11 x12 x13 /// x20 x21 x22 x23 /// </summary> /// <param name="matrix"></param> /// <returns></returns> private static Unity.Mathematics.float4 determinantCoef(Unity.Mathematics.float4x3 matrix) { Unity.Mathematics.float4 bottomRow = matrix.c2; float[] determinants = Determinant2X2(matrix.c0, matrix.c1); return(new Unity.Mathematics.float4( bottomRow.y * determinants[5] - bottomRow.z * determinants[4] + bottomRow.w * determinants[3], -(bottomRow.x * determinants[5] - bottomRow.z * determinants[2] + bottomRow.w * determinants[3]), bottomRow.x * determinants[4] - bottomRow.y * determinants[2] + bottomRow.w * determinants[0], -(bottomRow.x * determinants[3] - bottomRow.y * determinants[1] + bottomRow.z * determinants[0]) )); }
/// <summary> /// Return the basis of a hyper plane orthagonal to a given vector /// </summary> /// <param name="v"></param> /// <returns></returns> public static Unity.Mathematics.float4x3 basisSystem(this Unity.Mathematics.float4 v) { Unity.Mathematics.math.normalize(v); //use method described here: https://www.geometrictools.com/Documentation/OrthonormalSets.pdf if (v.x == 0 && v.y == 0 && v.z == 0 && v.w == 0) { UnityEngine.Debug.LogError("Can't form basis from zero vector"); } //the vector is the first basis vector for the 4-space, orthag to the hyperplane Unity.Mathematics.math.normalize(v); //establish a second basis vector Unity.Mathematics.float4 basis0; if (v.x != 0 || v.y != 0) { basis0 = new UnityEngine.Vector4(v.y, v.x, 0, 0); } else { basis0 = new UnityEngine.Vector4(0, 0, v.w, v.z); } Unity.Mathematics.math.normalize(basis0); float[] determinants = Determinant2X2(v, basis0); //index of largest determinant int idx = 0; for (int i = 0; i < 6; i++) { if (determinants[i] > determinants[idx]) { idx = i; } } if (determinants[idx] != 0) { UnityEngine.Debug.LogError("No non-zero determinant"); } //choose bottom row of det matrix to generate next basis vector Unity.Mathematics.float4 bottomRow; if (idx == 0 || idx == 1 || idx == 3) { bottomRow = new Unity.Mathematics.float4(0, 0, 0, 1); } else if (idx == 2 || idx == 4) { bottomRow = new Unity.Mathematics.float4(0, 0, 1, 0); } else { bottomRow = new Unity.Mathematics.float4(0, 1, 0, 0); } Unity.Mathematics.float4 basis1 = determinantCoef(new Unity.Mathematics.float4x3(v, basis0, bottomRow)); Unity.Mathematics.math.normalize(basis1); Unity.Mathematics.float4 basis2 = determinantCoef(new Unity.Mathematics.float4x3(v, basis0, basis1)); Unity.Mathematics.math.normalize(basis2); //returns the basis that spans the hyperplane orthogonal to v Unity.Mathematics.float4x3 basis = new Unity.Mathematics.float4x3(basis0, basis1, basis2); //check that v is orthogonal. // v.projectDownDimension(basis, ProjectionMethod.parallel, null, null, null); // if (v.x != 0 || v.y != 0 || v.z != 0) UnityEngine.Debug.LogError("Basis is not orthogonal to v"); return(basis); }