/** * Extracts the row from the matrix a. * @param a Input matrix * @param row Which row is to be extracted * @param output output. Storage for the extracted row. If null then a new vector will be returned. * @return The extracted row. */ public static DMatrix3 extractRow(DMatrix3x3 a, int row, DMatrix3 output) { if (output == null) { output = new DMatrix3(); } switch (row) { case 0: output.a1 = a.a11; output.a2 = a.a12; output.a3 = a.a13; break; case 1: output.a1 = a.a21; output.a2 = a.a22; output.a3 = a.a23; break; case 2: output.a1 = a.a31; output.a2 = a.a32; output.a3 = a.a33; break; default: throw new ArgumentException("Out of bounds row. row = " + row); } return(output); }
/** * Extracts the column from the matrix a. * @param a Input matrix * @param column Which column is to be extracted * @param output output. Storage for the extracted column. If null then a new vector will be returned. * @return The extracted column. */ public static DMatrix3 extractColumn(DMatrix3x3 a, int column, DMatrix3 output) { if (output == null) { output = new DMatrix3(); } switch (column) { case 0: output.a1 = a.a11; output.a2 = a.a21; output.a3 = a.a31; break; case 1: output.a1 = a.a12; output.a2 = a.a22; output.a3 = a.a32; break; case 2: output.a1 = a.a13; output.a2 = a.a23; output.a3 = a.a33; break; default: throw new ArgumentException("Out of bounds column. column = " + column); } return(output); }
public static void main(string[] args) { // declare the matrix DMatrix3x3 a = new DMatrix3x3(); DMatrix3x3 b = new DMatrix3x3(); // Can assign values the usual way for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { a.set(i, j, i + j + 1); } } // Direct manipulation of each value is the fastest way to assign/read values a.a11 = 12; a.a23 = 64; // can print the usual way too a.print(); // most of the standard operations are support CommonOps_DDF3.transpose(a, b); b.print(); Console.WriteLine("Determinant = " + CommonOps_DDF3.det(a)); // matrix-vector operations are also supported // Constructors for vectors and matrices can be used to initialize its value DMatrix3 v = new DMatrix3(1, 2, 3); DMatrix3 result = new DMatrix3(); CommonOps_DDF3.mult(a, v, result); // Conversion into DMatrixRMaj can also be done DMatrixRMaj dm = ConvertDMatrixStruct.convert(a, null); dm.print(); // This can be useful if you need do more advanced operations SimpleMatrix <DMatrixRMaj> sv = SimpleMatrix <DMatrixRMaj> .wrap(dm).svd().getV() as SimpleMatrix <DMatrixRMaj>; // can then convert it back into a fixed matrix DMatrix3x3 fv = ConvertDMatrixStruct.convert(sv.getDDRM(), (DMatrix3x3)null); Console.WriteLine("Original simple matrix and converted fixed matrix"); sv.print(); fv.print(); }
public static double normF(DMatrix3 M) { double scale = CommonOps_DDF3.elementMaxAbs(M); if (scale == 0.0) { return(0.0); } double a1 = M.a1 / scale, a2 = M.a2 / scale, a3 = M.a3 / scale; double sum = a1 * a1 + a2 * a2 + a3 * a3; return(scale * Math.Sqrt(sum)); }
/** * <p> * Returns the value of the element in the vector that has the largest value.<br> * <br> * Max{ a<sub>i</sub> } for all i<br> * </p> * * @param a A vector. Not modified. * @return The max element value of the matrix. */ public static double elementMax(DMatrix3 a) { double max = a.a1; if (a.a2 > max) { max = a.a2; } if (a.a3 > max) { max = a.a3; } return(max); }
/** * <p> * Returns the value of the element in the vector that has the minimum value.<br> * <br> * Min{ a<sub>i</sub> } for all<br> * </p> * * @param a A matrix. Not modified. * @return The value of element in the vector with the minimum value. */ public static double elementMin(DMatrix3 a) { double min = a.a1; if (a.a2 < min) { min = a.a2; } if (a.a3 < min) { min = a.a3; } return(min); }
public static bool isIdentical(DMatrix3 a, DMatrix3 b, double tol) { if (!MatrixFeatures_DDRM.isIdentical(a.a1, b.a1, tol)) { return(false); } if (!MatrixFeatures_DDRM.isIdentical(a.a2, b.a2, tol)) { return(false); } if (!MatrixFeatures_DDRM.isIdentical(a.a3, b.a3, tol)) { return(false); } return(true); }
public static bool hasUncountable(DMatrix3 a) { if (UtilEjml.isUncountable(a.a1)) { return(true); } if (UtilEjml.isUncountable(a.a2)) { return(true); } if (UtilEjml.isUncountable(a.a3)) { return(true); } return(false); }
/** * <p> * Returns the absolute value of the element in the vector that has the largest absolute value.<br> * <br> * Max{ |a<sub>i</sub>| } for all i<br> * </p> * * @param a A matrix. Not modified. * @return The max abs element value of the vector. */ public static double elementMaxAbs(DMatrix3 a) { double max = Math.Abs(a.a1); double tmp = Math.Abs(a.a2); if (tmp > max) { max = tmp; } tmp = Math.Abs(a.a2); if (tmp > max) { max = tmp; } tmp = Math.Abs(a.a3); if (tmp > max) { max = tmp; } return(max); }
/** * <p> * Returns the absolute value of the element in the vector that has the smallest absolute value.<br> * <br> * Min{ |a<sub>i</sub>| } for all i<br> * </p> * * @param a A matrix. Not modified. * @return The max element value of the vector. */ public static double elementMinAbs(DMatrix3 a) { double min = Math.Abs(a.a1); double tmp = Math.Abs(a.a1); if (tmp < min) { min = tmp; } tmp = Math.Abs(a.a2); if (tmp < min) { min = tmp; } tmp = Math.Abs(a.a3); if (tmp < min) { min = tmp; } return(min); }
private void UpdateModelViewMatrix() // метод вызывается при измении свойств cameraAngle и cameraDistance { #region Обновление объектно-видовой матрицы --------------------------------------------------------- RenderDevice.AddScheduleTask((gl, s) => { gl.MatrixMode(OpenGL.GL_MODELVIEW); var deg2rad = Math.PI / 180; // Вращается камера, а не сам объект double phi = deg2rad * cameraAngle.X; double teta = deg2rad * cameraAngle.Y; double psi = deg2rad * cameraAngle.Z; // матрицы поворота вокруг осей DMatrix3 RX = new DMatrix3(1, 0, 0, 0, Math.Cos(phi), -Math.Sin(phi), 0, Math.Sin(phi), Math.Cos(phi)); DMatrix3 RY = new DMatrix3(Math.Cos(teta), 0, Math.Sin(teta), 0, 1, 0, -Math.Sin(teta), 0, Math.Cos(teta)); DMatrix3 RZ = new DMatrix3(Math.Cos(psi), -Math.Sin(psi), 0, Math.Sin(psi), Math.Cos(psi), 0, 0, 0, 1); var cameraTransform = (RX * RY) * RZ; var cameraPosition = cameraTransform * new DVector3(0, 0, cameraDistance); var cameraUpDirection = cameraTransform * new DVector3(0, 1, 0); // Мировая матрица (преобразование локальной системы координат в мировую) mMatrix = DMatrix4.Identity; // нет никаких преобразований над объекта // Видовая матрица (переход из мировой системы координат к системе координат камеры) vMatrix = LookAt(DMatrix4.Identity, cameraPosition, DVector3.Zero, cameraUpDirection); // матрица ModelView var mvMatrix = vMatrix * mMatrix; gl.LoadMatrix(mvMatrix.ToArray(true)); //gl.Rotate(45, 1f, 0f, 0); //gl.Rotate(-45, 0f, 1f, 0); }); #endregion }
/** * Converts {@link DMatrixRMaj} into {@link DMatrix3} * * @param input Input matrix. * @param output Output matrix. If null a new matrix will be declared. * @return Converted matrix. */ public static DMatrix3 convert(DMatrixRMaj input, DMatrix3 output) { if (output == null) { output = new DMatrix3(); } if (input.getNumRows() != 1 && input.getNumCols() != 1) { throw new ArgumentException("One row or column must have a length of 1 for it to be a vector"); } int length = Math.Max(input.getNumRows(), input.getNumCols()); if (length != 3) { throw new ArgumentException("Length of input vector is not 3. It is " + length); } output.a1 = input.data[0]; output.a2 = input.data[1]; output.a3 = input.data[2]; return(output); }
/** * Converts {@link DMatrix3} into {@link DMatrixRMaj}. * * @param input Input matrix. * @param output Output matrix. If null a new matrix will be declared. * @return Converted matrix. */ public static DMatrixRMaj convert(DMatrix3 input, DMatrixRMaj output) { if (output == null) { output = new DMatrixRMaj(3, 1); } if (output.NumRows != 1 && output.NumCols != 1) { throw new ArgumentException("One row or column must have a length of 1 for it to be a vector"); } int length = Math.Max(output.NumRows, output.NumCols); if (length != 3) { throw new ArgumentException("Length of input vector is not 3. It is " + length); } output.data[0] = input.a1; output.data[1] = input.a2; output.data[2] = input.a3; return(output); }
/** * <p> * Performs an element by element scalar multiplication.<br> * <br> * b<sub>i</sub> = α*a<sub>i</sub> * </p> * * @param alpha the amount each element is multiplied by. * @param a The vector that is to be scaled. Not modified. * @param b Where the scaled matrix is stored. Modified. */ public static void scale(double alpha, DMatrix3 a, DMatrix3 b) { b.a1 = a.a1 * alpha; b.a2 = a.a2 * alpha; b.a3 = a.a3 * alpha; }
protected unsafe override void OnDeviceUpdate(object s, OGLDeviceUpdateArgs e) { var gl = e.gl; gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT); gl.UseProgram(shaderProgram); DMatrix4 modelMat = DMatrix4.Identity; RotateMatrix(ref modelMat, Rotation.X, Rotation.Y, Rotation.Z); ScaleMatrix(ref modelMat, Scale.X, Scale.Y, Scale.Z); double H = gl.RenderContextProvider.Height; double W = gl.RenderContextProvider.Width; double AspectRatio = W / H; DMatrix4 projectionlMat = OrthoNormalized(W, H); DMatrix4 normalMat = DMatrix3.NormalVecTransf(modelMat); LoadGlobalUniforms(gl, shaderProgram); int modelViewMatrixUniformLocation = gl.GetUniformLocation(shaderProgram, "modelViewMatrix"); int projectionMatrixUniformLocation = gl.GetUniformLocation(shaderProgram, "projectionMatrix"); int modelViewNormalMatrixUniformLocation = gl.GetUniformLocation(shaderProgram, "modelViewNormalMatrix"); gl.UniformMatrix4(modelViewMatrixUniformLocation, 1, false, modelMat.ToArray(true).Select(d => (float)d).ToArray()); gl.UniformMatrix4(projectionMatrixUniformLocation, 1, false, projectionlMat.ToArray(true).Select(d => (float)d).ToArray()); gl.UniformMatrix4(modelViewNormalMatrixUniformLocation, 1, false, normalMat.ToArray(true).Select(d => (float)d).ToArray()); #region ендинг сцены методом VBO (Vertex Buffer Object) -------------------------------------------- gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, VertexVBOID); unsafe { fixed(float *ptr = &GLVertecis[0].vx) { gl.BufferData(OpenGL.GL_ARRAY_BUFFER, sizeof(GLVertex) * GLVertecis.Length, new IntPtr(ptr), OpenGL.GL_STATIC_DRAW); } } gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, IndexVBOID); unsafe { fixed(uint *ptr = &indices[0]) { gl.BufferData(OpenGL.GL_ELEMENT_ARRAY_BUFFER, sizeof(uint) * indices.Length, new IntPtr(ptr), OpenGL.GL_STATIC_DRAW); } } gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, VertexVBOID); gl.EnableVertexAttribArray(0); // We like submitting vertices on stream 0 for no special reason gl.VertexAttribPointer(0, 3, OpenGL.GL_FLOAT, false, sizeof(GLVertex), BUFFER_OFFSET(0)); // The starting point of the VBO, for the vertices gl.EnableVertexAttribArray(1); // We like submitting normals on stream 1 for no special reason gl.VertexAttribPointer(1, 3, OpenGL.GL_FLOAT, false, sizeof(GLVertex), BUFFER_OFFSET(12)); // The starting point of normals, 12 bytes away gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, IndexVBOID); gl.DrawElements(OpenGL.GL_TRIANGLES, indices.Length, OpenGL.GL_UNSIGNED_INT, BUFFER_OFFSET(0)); gl.DisableVertexAttribArray(0); gl.DisableVertexAttribArray(1); gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, 0); gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, 0); #endregion if (Axis) { DrawAxis(gl); } }
/** * <p> * Performs an element by element scalar division. Scalar denominator.<br> * <br> * b<sub>i</sub> = a<sub>i</sub> /α * </p> * * @param alpha the amount each element is divided by. * @param a The vector whose elements are to be divided. Not modified. * @param b Where the results are stored. Modified. */ public static void divide(DMatrix3 a, double alpha, DMatrix3 b) { b.a1 = a.a1 / alpha; b.a2 = a.a2 / alpha; b.a3 = a.a3 / alpha; }
/** * <p> * Performs an in-place element by element scalar division. Scalar denominator.<br> * <br> * a<sub>i</sub> = a<sub>i</sub>/α * </p> * * @param a The vector whose elements are to be divided. Modified. * @param alpha the amount each element is divided by. */ public static void divide(DMatrix3 a, double alpha) { a.a1 /= alpha; a.a2 /= alpha; a.a3 /= alpha; }
protected unsafe override void OnDeviceUpdate(object s, OGLDeviceUpdateArgs e) { var gl = e.gl; // Очищаем буфер экрана и буфер глубины (иначе рисоваться все будет поверх старого) gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT); gl.UseProgram(shaderProgram); //Console.WriteLine(gl.GetErrorDescription(gl.GetError())); DMatrix4 modelMat = DMatrix4.Identity; RotateMatrix(ref modelMat, Rotation.X, Rotation.Y, Rotation.Z); ScaleMatrix(ref modelMat, Scale.X, Scale.Y, Scale.Z); double H = gl.RenderContextProvider.Height; double W = gl.RenderContextProvider.Width; double AspectRatio = W / H; DMatrix4 projectionlMat = OrthoNormalized(W, H); DMatrix4 normalMat = DMatrix3.NormalVecTransf(modelMat); LoadGlobalUniforms(gl, shaderProgram); int modelViewMatrixUniformLocation = gl.GetUniformLocation(shaderProgram, "modelViewMatrix"); int projectionMatrixUniformLocation = gl.GetUniformLocation(shaderProgram, "projectionMatrix"); int modelViewNormalMatrixUniformLocation = gl.GetUniformLocation(shaderProgram, "modelViewNormalMatrix"); gl.UniformMatrix4(modelViewMatrixUniformLocation, 1, false, modelMat.ToArray(true).Select(d => (float)d).ToArray()); gl.UniformMatrix4(projectionMatrixUniformLocation, 1, false, projectionlMat.ToArray(true).Select(d => (float)d).ToArray()); gl.UniformMatrix4(modelViewNormalMatrixUniformLocation, 1, false, normalMat.ToArray(true).Select(d => (float)d).ToArray()); // Рендинг сцены реализуется одним из двух методов - VB (Vertex Buffer) или VA (Vertex Array), // в зависимости от выбранного пользователем режима. #region ендинг сцены методом VBO (Vertex Buffer Object) -------------------------------------------- gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, VertexVBOID); unsafe { fixed(float *ptr = &GLVertecis[0].vx) { gl.BufferData(OpenGL.GL_ARRAY_BUFFER, sizeof(GLVertex) * GLVertecis.Length, new IntPtr(ptr), OpenGL.GL_STATIC_DRAW); } } gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, IndexVBOID); unsafe { fixed(uint *ptr = &indices[0]) { gl.BufferData(OpenGL.GL_ELEMENT_ARRAY_BUFFER, sizeof(uint) * indices.Length, new IntPtr(ptr), OpenGL.GL_STATIC_DRAW); } } gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, VertexVBOID); gl.EnableVertexAttribArray(0); // We like submitting vertices on stream 0 for no special reason gl.VertexAttribPointer(0, 3, OpenGL.GL_FLOAT, false, sizeof(GLVertex), BUFFER_OFFSET(0)); // The starting point of the VBO, for the vertices gl.EnableVertexAttribArray(1); // We like submitting normals on stream 1 for no special reason gl.VertexAttribPointer(1, 3, OpenGL.GL_FLOAT, false, sizeof(GLVertex), BUFFER_OFFSET(12)); // The starting point of normals, 12 bytes away gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, IndexVBOID); gl.DrawElements(OpenGL.GL_TRIANGLES, indices.Length, OpenGL.GL_UNSIGNED_INT, BUFFER_OFFSET(0)); gl.DisableVertexAttribArray(0); gl.DisableVertexAttribArray(1); gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, 0); gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, 0); /* общий код удаления буфферов */ #endregion if (Axis) { DrawAxis(gl); } }
/** * <p> * Changes the sign of every element in the vector.<br> * <br> * a<sub>i</sub> = -a<sub>i</sub> * </p> * * @param a A vector. Modified. */ public static void changeSign(DMatrix3 a) { a.a1 = -a.a1; a.a2 = -a.a2; a.a3 = -a.a3; }
/** * <p>Performs the following operation:<br> * <br> * a = a + b <br> * a<sub>i</sub> = a<sub>i</sub> + b<sub>i</sub> <br> * </p> * * @param a A Vector. Modified. * @param b A Vector. Not modified. */ public static void addEquals(DMatrix3 a, DMatrix3 b) { a.a1 += b.a1; a.a2 += b.a2; a.a3 += b.a3; }
/** * <p>Performs the following operation:<br> * <br> * c = a + b <br> * c<sub>i</sub> = a<sub>i</sub> + b<sub>i</sub> <br> * </p> * * <p> * Vector C can be the same instance as Vector A and/or B. * </p> * * @param a A Vector. Not modified. * @param b A Vector. Not modified. * @param c A Vector where the results are stored. Modified. */ public static void add(DMatrix3 a, DMatrix3 b, DMatrix3 c) { c.a1 = a.a1 + b.a1; c.a2 = a.a2 + b.a2; c.a3 = a.a3 + b.a3; }
/** * <p>Performs the following operation:<br> * <br> * c = a - b <br> * c<sub>i</sub> = a<sub>i</sub> - b<sub>i</sub> <br> * </p> * * <p> * Vector C can be the same instance as Vector A and/or B. * </p> * * @param a A Vector. Not modified. * @param b A Vector. Not modified. * @param c A Vector where the results are stored. Modified. */ public static void subtract(DMatrix3 a, DMatrix3 b, DMatrix3 c) { c.a1 = a.a1 - b.a1; c.a2 = a.a2 - b.a2; c.a3 = a.a3 - b.a3; }
/** * <p> * Sets every element in the vector to the specified value.<br> * <br> * a<sub>i</sub> = value * <p> * * @param a A vector whose elements are about to be set. Modified. * @param v The value each element will have. */ public static void fill(DMatrix3 a, double v) { a.a1 = v; a.a2 = v; a.a3 = v; }
/** * <p>Performs the following operation:<br> * <br> * a = a - b <br> * a<sub>i</sub> = a<sub>i</sub> - b<sub>i</sub> <br> * </p> * * @param a A Vector. Modified. * @param b A Vector. Not modified. */ public static void subtractEquals(DMatrix3 a, DMatrix3 b) { a.a1 -= b.a1; a.a2 -= b.a2; a.a3 -= b.a3; }
/** * <p>Performs matrix to vector multiplication:<br> * <br> * c = a * b <br> * <br> * c<sub>i</sub> = ∑<sub>k=1:n</sub> { a<sub>ik</sub> * b<sub>k</sub>} * </p> * * @param a The left matrix in the multiplication operation. Not modified. * @param b The right vector in the multiplication operation. Not modified. * @param c Where the results of the operation are stored. Modified. */ public static void mult(DMatrix3x3 a, DMatrix3 b, DMatrix3 c) { c.a1 = a.a11 * b.a1 + a.a12 * b.a2 + a.a13 * b.a3; c.a2 = a.a21 * b.a1 + a.a22 * b.a2 + a.a23 * b.a3; c.a3 = a.a31 * b.a1 + a.a32 * b.a2 + a.a33 * b.a3; }
/** * <p>Performs vector to matrix multiplication:<br> * <br> * c = a * b <br> * <br> * c<sub>j</sub> = ∑<sub>k=1:n</sub> { b<sub>k</sub> * a<sub>kj</sub> } * </p> * * @param a The left vector in the multiplication operation. Not modified. * @param b The right matrix in the multiplication operation. Not modified. * @param c Where the results of the operation are stored. Modified. */ public static void mult(DMatrix3 a, DMatrix3x3 b, DMatrix3 c) { c.a1 = a.a1 * b.a11 + a.a2 * b.a21 + a.a3 * b.a31; c.a2 = a.a1 * b.a12 + a.a2 * b.a22 + a.a3 * b.a32; c.a3 = a.a1 * b.a13 + a.a2 * b.a23 + a.a3 * b.a33; }
public DisplayNumericPropertyAttribute(DMatrix3 Default, double Increment, int Decimals, string Name, double Minimum = (double)long.MinValue, double Maximum = (double)long.MaxValue) : this(Default, Name, Increment, Minimum, Maximum, Decimals) { }
/** * <p>Performs an element by element multiplication operation:<br> * <br> * a<sub>i</sub> = a<sub>i</sub> * b<sub>i</sub> <br> * </p> * @param a The left vector in the multiplication operation. Modified. * @param b The right vector in the multiplication operation. Not modified. */ public static void elementMult(DMatrix3 a, DMatrix3 b) { a.a1 *= b.a1; a.a2 *= b.a2; a.a3 *= b.a3; }
/** * <p> * Extracts all diagonal elements from 'input' and places them inside the 'output' vector. Elements * are in sequential order. * </p> * * * @param input Matrix. Not modified. * @param output Vector containing diagonal elements. Modified. */ public static void diag(DMatrix3x3 input, DMatrix3 output) { output.a1 = input.a11; output.a2 = input.a22; output.a3 = input.a33; }
/** * <p>Performs the vector dot product:<br> * <br> * c = a * b <br> * <br> * c ≥ ∑<sub>k=1:n</sub> { b<sub>k</sub> * a<sub>k</sub> } * </p> * * @param a The left vector in the multiplication operation. Not modified. * @param b The right matrix in the multiplication operation. Not modified. * @return The dot product */ public static double dot(DMatrix3 a, DMatrix3 b) { return(a.a1 * b.a1 + a.a2 * b.a2 + a.a3 * b.a3); }