//[MethodImpl(MethodImplOptions.AggressiveInlining)] //may not work in .NET 4.0 public void SetRow(int row, Vector3H1 V, float W = 0) { Data[row, 0] = V.X; Data[row, 1] = V.Y; Data[row, 2] = V.Z; Data[row, 3] = W; }
//I got this method for rotating around an arbitary axis from the //GLspec15.pdf. (page number 42 in the image, page 55 of the pdf file) //IMPORTANT!!! The angle 'radians' is in the direction of the //"finger curl of the right hand rule" around the vector {x,y,z} //------------------------------------------------------------------------------------------ public void RotateAnyAxis(float radians, IVector3H1 axisUnitVector) //unitize Axis first!!!!! { //but remember the cross product of 2 unit vectors is only a unit vector if the original 2 vectors are @ 90degrees ..... ///................... should I go ahead & always run the unit calculation here for safety? ///maybe not b/c in FlightSimulator I pretty much always unit-ize the vectors before haand //double myAxis[3] = {Axis.vect[0], Axis.vect[1], Axis.vect[2]}; //int mySize = 3; //UnitVOfArray(myAxis, mySize); Matrix3X3 S = new Matrix3X3(); S.Data[0, 0] = 0; S.Data[0, 1] = -axisUnitVector.Z; S.Data[0, 2] = axisUnitVector.Y; S.Data[1, 0] = axisUnitVector.Z; S.Data[1, 1] = 0; S.Data[1, 2] = -axisUnitVector.X; S.Data[2, 0] = -axisUnitVector.Y; S.Data[2, 1] = axisUnitVector.X; S.Data[2, 2] = 0; Matrix3X3 outter = (Matrix3X3)Vector3H1.OutterProduct(axisUnitVector, axisUnitVector); Matrix3X3 Id = new Matrix3X3(); Id.SetIdentity(); Matrix3X3 Result = outter + ((float)Math.Cos(radians)) * (Id - outter) + ((float)Math.Sin(radians)) * S; //Manually copy for maximum speed this.Data[0, 0] = Result.Data[0, 0]; this.Data[0, 1] = Result.Data[0, 1]; this.Data[0, 2] = Result.Data[0, 2]; this.Data[1, 0] = Result.Data[1, 0]; this.Data[1, 1] = Result.Data[1, 1]; this.Data[1, 2] = Result.Data[1, 2]; this.Data[2, 0] = Result.Data[2, 0]; this.Data[2, 1] = Result.Data[2, 1]; this.Data[2, 2] = Result.Data[2, 2]; }
/// <summary> //Can only be done in Matrix4X4 b/c it uses the 3rd row /// Build a world space to camera space matrix - Based on OpenTK.Matrix4.LookAt /// </summary> /// <param name="eye">Eye (camera) position in world space</param> /// <param name="target">Target position in world space</param> /// <param name="unitUpVector">Up vector in world space (should not be parallel to the camera direction, that is target - eye)</param> public void SetLookAt(Vector3H1 eye, Vector3H1 target, Vector3H1 unitUpVector) { //unitUpVector.SetUnitVector() Vector3H1 z = eye - target; z.SetUnitVector(); Vector3H1 x = Vector3H1.CrossProduct(unitUpVector, z); x.SetUnitVector(); Vector3H1 y = Vector3H1.CrossProduct(z, x); y.SetUnitVector(); Data[0, 0] = x.X; Data[0, 1] = y.X; Data[0, 2] = z.X; Data[0, 3] = 0; Data[1, 0] = x.Y; Data[1, 1] = y.Y; Data[1, 2] = z.Y; Data[1, 3] = 0; Data[2, 0] = x.Z; Data[2, 1] = y.Z; Data[2, 2] = z.Z; Data[2, 3] = 0; Data[3, 0] = -((x.X * eye.X) + (x.Y * eye.Y) + (x.Z * eye.Z)); Data[3, 1] = -((y.X * eye.X) + (y.Y * eye.Y) + (y.Z * eye.Z)); Data[3, 2] = -((z.X * eye.X) + (z.Y * eye.Y) + (z.Z * eye.Z)); Data[3, 3] = 1; }
//[MethodImpl(MethodImplOptions.AggressiveInlining)] //may not work in .NET 4.0 public void SetColumn(int col, Vector3H1 V, float W = 0) { Data[0, col] = V.X; Data[1, col] = V.Y; Data[2, col] = V.Z; Data[3, col] = W; }
//I got this method for rotating around an arbitary axis from the //GLspec15.pdf. (page number 42 in the image, page 55 of the pdf file) //IMPORTANT!!! The angle 'radians' is in the direction of the //"finger curl of the right hand rule" around the vector {x,y,z} //------------------------------------------------------------------------------------------ public void RotateAnyAxis(float radians, IVector3H1 axisUnitVector) //unitize Axis first!!!!! { //but remember the cross product of 2 unit vectors is only a unit vector if the original 2 vectors are @ 90degrees ..... ///................... should I go ahead & always run the unit calculation here for safety? ///maybe not b/c in FlightSimulator I pretty much always unit-ize the vectors before haand //double myAxis[3] = {Axis.vect[0], Axis.vect[1], Axis.vect[2]}; //int mySize = 3; //UnitVOfArray(myAxis, mySize); Matrix3X3 S = new Matrix3X3(); S.Data[0, 0] = 0; S.Data[0, 1] = -axisUnitVector.Z; S.Data[0, 2] = axisUnitVector.Y; S.Data[1, 0] = axisUnitVector.Z; S.Data[1, 1] = 0; S.Data[1, 2] = -axisUnitVector.X; S.Data[2, 0] = -axisUnitVector.Y; S.Data[2, 1] = axisUnitVector.X; S.Data[2, 2] = 0; Matrix3X3 outter = (Matrix3X3)Vector3H1.OutterProduct(axisUnitVector, axisUnitVector); Matrix3X3 Id = new Matrix3X3(); Id.SetIdentity(); //I'm not sure what to do about this error - may be necessary to have different interfaces for Matrix3H4 & Matrix4X4..... IMatrix3D Result = outter + ((float)Math.Cos(radians)) * (Id - outter) + ((float)Math.Sin(radians)) * S; //Manually copy for maximum speed this.Data[0, 0] = Result.Data[0, 0]; this.Data[0, 1] = Result.Data[0, 1]; this.Data[0, 2] = Result.Data[0, 2]; this.Data[0, 3] = 0; this.Data[1, 0] = Result.Data[1, 0]; this.Data[1, 1] = Result.Data[1, 1]; this.Data[1, 2] = Result.Data[1, 2]; this.Data[1, 3] = 0; this.Data[2, 0] = Result.Data[2, 0]; this.Data[2, 1] = Result.Data[2, 1]; this.Data[2, 2] = Result.Data[2, 2]; this.Data[2, 3] = 0; //this.Copy(Result); //replaces current value of calling matrix //forces bottom row & last col to be all 0s }
/// <summary> /// QuickSolve3D /// Solves matrix equation [A] * x = N for x based on Cramer's Rule /// where A is a Matrix, N is a vector (usually a normal) /// ----------------------------------------------------------------- /// Marix A is typed as IMatrix so that Matrix3X3, Matrix3H4 or Matrix4X4 can be used /// extra data is ignored, but Matrix2X2 would cause an error (but it doesn't exist yet) /// </summary> /// <param name="A">IMatrix</param> /// <param name="N">IVector3H1</param> /// <param name="bUnitize">bool</param> /// <returns></returns> public static Vector3H1 QuickSolve3D(IMatrix A, IVector3H1 N, bool bUnitize = true) { float determinate = Determinate3D(A); //if the determinate comes out to zero, it's probably b/c this is actually a small if (determinate == 0) //2X2 matrix in a larger object w/ the rest zeros, so just { determinate = Determinate2D(A); //go ahead & take the 2X2 determinate A.Data[2, 2] = 1; //but you aldo have to set the Z-identity } //this works, but it it good to change the matrix???????? Vector3H1 V = new Vector3H1(); V.X = ((A.Data[2, 2] * A.Data[1, 1] - A.Data[1, 2] * A.Data[2, 1]) * N.X + (A.Data[2, 1] * A.Data[0, 2] - A.Data[0, 1] * A.Data[2, 2]) * N.Y + (A.Data[0, 1] * A.Data[1, 2] - A.Data[1, 1] * A.Data[0, 2]) * N.Z) / determinate; V.Y = ((A.Data[1, 2] * A.Data[2, 0] - A.Data[2, 2] * A.Data[1, 0]) * N.X + (A.Data[0, 0] * A.Data[2, 2] - A.Data[2, 0] * A.Data[0, 2]) * N.Y + (A.Data[1, 0] * A.Data[0, 2] - A.Data[0, 0] * A.Data[1, 2]) * N.Z) / determinate; V.Z = ((A.Data[2, 1] * A.Data[1, 0] - A.Data[1, 1] * A.Data[2, 0]) * N.X + (A.Data[0, 1] * A.Data[2, 0] - A.Data[0, 0] * A.Data[2, 1]) * N.Y + (A.Data[0, 0] * A.Data[1, 1] - A.Data[0, 1] * A.Data[1, 0]) * N.Z) / determinate; if (bUnitize) { V.SetUnitVector(); } return(V); }
//[MethodImpl(MethodImplOptions.AggressiveInlining)] //may not work in .NET 4.0 public void SetColumn(int col, Vector3H1 V) { Data[0, col] = V.X; Data[1, col] = V.Y; Data[2, col] = V.Z; }