/** * Converts {@link DMatrixRMaj} into {@link DMatrix4} * * @param input Input matrix. * @param output Output matrix. If null a new matrix will be declared. * @return Converted matrix. */ public static DMatrix4 convert(DMatrixRMaj input, DMatrix4 output) { if (output == null) { output = new DMatrix4(); } 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 != 4) { throw new ArgumentException("Length of input vector is not 4. It is " + length); } output.a1 = input.data[0]; output.a2 = input.data[1]; output.a3 = input.data[2]; output.a4 = input.data[3]; return(output); }
/** * Converts {@link DMatrix4} 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(DMatrix4 input, DMatrixRMaj output) { if (output == null) { output = new DMatrixRMaj(4, 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 != 4) { throw new ArgumentException("Length of input vector is not 4. It is " + length); } output.data[0] = input.a1; output.data[1] = input.a2; output.data[2] = input.a3; output.data[3] = input.a4; return(output); }
private void UpdatePerspectve(OpenGL gl) { gl.MatrixMode(OpenGL.GL_PROJECTION); if (Isometric) { double scale = 0.005; double isoX = Math.Sqrt(3) * 0.5 * scale; double isoY = -0.5 * scale; double f = 100, n = 0.1; pMatrix = new DMatrix4( isoX, 0, -isoX, -isoX * cameraDistance, isoY, scale, isoY, isoY * cameraDistance, 0, 0, -0.001, 0, 0, 0, 0, 1 ); } else { pMatrix = Perspective(60, (double)w / h, 0.1, 100); } gl.LoadMatrix(pMatrix.ToArray(true)); }
private void DrawAxis(OpenGL gl) { gl.MatrixMode(OpenGL.GL_MODELVIEW); gl.PushMatrix(); DMatrix4 mat = DMatrix4.Identity; RotateMatrix(ref mat, Rotation.X, Rotation.Y, Rotation.Z); gl.LoadMatrix(mat.ToArray(true)); gl.Disable(OpenGL.GL_DEPTH_TEST); gl.Begin(OpenGL.GL_LINES); const float AxisLength = 0.7f; gl.Color(1f, 0f, 0f); gl.Vertex(0f, 0f, 0f); gl.Vertex(AxisLength, 0f, 0f); gl.Color(0f, 1f, 0f); gl.Vertex(0f, 0f, 0f); gl.Vertex(0f, AxisLength, 0f); gl.Color(0f, 0f, 1f); gl.Vertex(0f, 0f, 0f); gl.Vertex(0f, 0f, AxisLength); gl.End(); gl.Enable(OpenGL.GL_DEPTH_TEST); gl.PopMatrix(); }
private void ScaleMatrix(ref DMatrix4 mat, double sX, double sY, double sZ) { DMatrix4 m = new DMatrix4 { M11 = sX, M22 = sY, M33 = sZ }; mat *= m; }
public static double normF(DMatrix4 M) { double scale = CommonOps_DDF4.elementMaxAbs(M); if (scale == 0.0) { return(0.0); } double a1 = M.a1 / scale, a2 = M.a2 / scale, a3 = M.a3 / scale, a4 = M.a4 / scale; double sum = a1 * a1 + a2 * a2 + a3 * a3 + a4 * a4; return(scale * Math.Sqrt(sum)); }
private void UpdateModelViewMatrix() // метод вызывается при измении свойств cameraAngle и cameraDistance { #region Обновление объектно-видовой матрицы --------------------------------------------------------- RenderDevice.AddScheduleTask((gl, s) => { DMatrix4 modelMat = DMatrix4.Identity; RotateMatrix(ref modelMat, Rotation.X, Rotation.Y, Rotation.Z); ScaleMatrix(ref modelMat, Scale.X, Scale.Y, Scale.Z); gl.MatrixMode(OpenGL.GL_MODELVIEW); gl.LoadMatrix(modelMat.ToArray(true)); }); #endregion }
private void DrawAxis(OpenGL gl) { gl.UseProgram(0); gl.MatrixMode(OpenGL.GL_MODELVIEW); gl.PushMatrix(); DMatrix4 mat = DMatrix4.Identity; RotateMatrix(ref mat, Rotation.X, Rotation.Y, Rotation.Z); gl.LoadMatrix(mat.ToArray(true)); gl.MatrixMode(OpenGL.GL_PROJECTION); gl.PushMatrix(); gl.LoadMatrix(OrthoNormalized(gl.RenderContextProvider.Width, gl.RenderContextProvider.Height).ToArray(true)); gl.Disable(OpenGL.GL_DEPTH_TEST); gl.Begin(OpenGL.GL_LINES); const float AxisLength = 0.7f; // X-axis gl.Color(1f, 0f, 0f); gl.Vertex(0f, 0f, 0f); gl.Vertex(AxisLength, 0f, 0f); // Y-axis gl.Color(0f, 1f, 0f); gl.Vertex(0f, 0f, 0f); gl.Vertex(0f, AxisLength, 0f); // Z-axis gl.Color(0f, 0f, 1f); gl.Vertex(0f, 0f, 0f); gl.Vertex(0f, 0f, AxisLength); gl.End(); gl.Enable(OpenGL.GL_DEPTH_TEST); gl.MatrixMode(OpenGL.GL_PROJECTION); gl.PopMatrix(); gl.MatrixMode(OpenGL.GL_MODELVIEW); gl.PopMatrix(); }
private void RotateMatrix(ref DMatrix4 mat, double aX, double aY, double aZ) { double xRad = ToRadians(aX); double yRad = ToRadians(aY); double zRad = ToRadians(aZ); double xCos = Math.Cos(xRad); double xSin = Math.Sin(xRad); double yCos = Math.Cos(yRad); double ySin = Math.Sin(yRad); double zCos = Math.Cos(zRad); double zSin = Math.Sin(zRad); DMatrix4 rx = new DMatrix4 { M11 = 1.0, M22 = xCos, M23 = -xSin, M32 = xSin, M33 = xCos, M44 = 1.0 }; DMatrix4 ry = new DMatrix4 { M11 = yCos, M13 = ySin, M22 = 1.0, M31 = -ySin, M33 = yCos, M44 = 1.0 }; DMatrix4 rz = new DMatrix4 { M11 = zCos, M12 = -zSin, M21 = zSin, M22 = zCos, M33 = 1.0, M44 = 1.0 }; mat *= rx * ry * rz; }
public static bool isIdentical(DMatrix4 a, DMatrix4 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); } if (!MatrixFeatures_DDRM.isIdentical(a.a4, b.a4, tol)) { return(false); } return(true); }
public static bool hasUncountable(DMatrix4 a) { if (UtilEjml.isUncountable(a.a1)) { return(true); } if (UtilEjml.isUncountable(a.a2)) { return(true); } if (UtilEjml.isUncountable(a.a3)) { return(true); } if (UtilEjml.isUncountable(a.a4)) { return(true); } return(false); }
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 }
private static DMatrix4 LookAt(DMatrix4 matrix, DVector3 eye, DVector3 center, DVector3 up) { var forward = (center - eye).Normalized(); if (forward.ApproxEqual(DVector3.Zero, 0.00001)) { return(matrix); } var side = (forward * up).Normalized(); var upVector = side * forward; var result = matrix * new DMatrix4( +side.X, +side.Y, +side.Z, 0, +upVector.X, +upVector.Y, +upVector.Z, 0, -forward.X, -forward.Y, -forward.Z, 0, 0, 0, 0, 1 ); result.M14 -= result.M11 * eye.X + result.M12 * eye.Y + result.M13 * eye.Z; result.M24 -= result.M21 * eye.X + result.M22 * eye.Y + result.M23 * eye.Z; result.M34 -= result.M31 * eye.X + result.M32 * eye.Y + result.M33 * eye.Z; result.M44 -= result.M41 * eye.X + result.M42 * eye.Y + result.M43 * eye.Z; return(result); }
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); float[] modelMat = new float[16]; gl.GetFloat(OpenGL.GL_MODELVIEW_MATRIX, modelMat); float[] projectionMat = new float[16]; gl.GetFloat(OpenGL.GL_PROJECTION_MATRIX, projectionMat); DMatrix4 mM = new DMatrix4(modelMat.Select(val => (double)val).ToArray()); DMatrix4 pM = new DMatrix4(projectionMat.Select(val => (double)val).ToArray()); mM.Transpose(); pM.Transpose(); transformationMatrix = pM * mM; if (Wireframe || Border) { DVector3 b0Color = new DVector3(1.0, 0.0, 0.0); DVector3 b1Color = new DVector3(0.0, 1.0, 0.0); DVector3 b2Color = new DVector3(0.0, 0.0, 1.0); DVector3 b3Color = new DVector3(1.0, 1.0, 0.0); if (Border) { surface.border0.Draw(gl, b0Color); surface.border1.Draw(gl, b1Color); surface.border2.Draw(gl, b2Color); surface.border3.Draw(gl, b3Color); } if (Wireframe) { surface.border0.DrawWireframe(gl, b0Color); surface.border1.DrawWireframe(gl, b1Color); surface.border2.DrawWireframe(gl, b2Color); surface.border3.DrawWireframe(gl, b3Color); } } gl.Color(1.0, 1.0, 1.0, 1.0); surface.DrawByLines(gl); if (Axis) { DrawAxis(gl); gl.DrawText(20, 20, 1.0f, 0.0f, 0.0f, "Arial", 16, "X"); gl.DrawText(35, 20, 0.0f, 1.0f, 0.0f, "Arial", 16, "Y"); gl.DrawText(50, 20, 0.0f, 0.0f, 1.0f, "Arial", 16, "Z"); } lock (ActiveVertexLocker) { if (ActiveVertex != null) { gl.Color(1.0, 0.0, 1.0, 1.0); gl.PointSize(15f); gl.Begin(OpenGL.GL_POINTS); gl.Vertex(ActiveVertex.Point.X, ActiveVertex.Point.Y, ActiveVertex.Point.Z); gl.End(); gl.Color(1.0, 1.0, 1.0, 1.0); gl.PointSize(1f); } } return; }
public DisplayNumericPropertyAttribute(DMatrix4 Default, double Increment, int Decimals, string Name, double Minimum = (double)long.MinValue, double Maximum = (double)long.MaxValue) : this(Default, Name, Increment, Minimum, Maximum, Decimals) { }
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); } }
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); } }
Vertex3 FindClosestVertex(DMatrix4 mat, DVector4 vec) { List <Vertex3> vs = new List <Vertex3>(); double radius = NormalizeDistance(VertexSize); foreach (Vertex3 v in surface.border0.vertices) { DVector4 tmp = mat * new DVector4(v.Point, 1.0); DVector2 d = new DVector2(tmp.X, tmp.Y) - new DVector2(vec.X, vec.Y); if (d.GetLength() < radius) { vs.Add(v); } } foreach (Vertex3 v in surface.border1.vertices) { DVector4 tmp = mat * new DVector4(v.Point, 1.0); DVector2 d = new DVector2(tmp.X, tmp.Y) - new DVector2(vec.X, vec.Y); if (d.GetLength() < radius) { vs.Add(v); } } foreach (Vertex3 v in surface.border2.vertices) { DVector4 tmp = mat * new DVector4(v.Point, 1.0); DVector2 d = new DVector2(tmp.X, tmp.Y) - new DVector2(vec.X, vec.Y); if (d.GetLength() < radius) { vs.Add(v); } } foreach (Vertex3 v in surface.border3.vertices) { DVector4 tmp = mat * new DVector4(v.Point, 1.0); DVector2 d = new DVector2(tmp.X, tmp.Y) - new DVector2(vec.X, vec.Y); if (d.GetLength() < radius) { vs.Add(v); } } Vertex3 res = null; double minDist = 100000000; foreach (Vertex3 v in vs) { DVector4 tmp = mat * new DVector4(v.Point, 1.0); DVector2 d = new DVector2(tmp.X, tmp.Y) - new DVector2(vec.X, vec.Y); double dist = d.GetLength(); if (dist < minDist) { res = v; minDist = dist; } } return(res); }
public static void normalizeF(DMatrix4 M) { double val = normF(M); CommonOps_DDF4.divide(M, val); }
protected override void OnDeviceUpdate(object s, GDIDeviceUpdateArgs e) { if (PrevApproxLevel != ApproxLevel) { ComputeObject(); PrevApproxLevel = ApproxLevel; } if (e.Heigh < e.Width) { WindowScale = (double)e.Heigh / InitialHeight; } else { WindowScale = (double)e.Width / InitialWidth; } switch (ProjMode) { case ProjectionMode.FR: rotX = Rotation.X; rotY = Rotation.Y; rotZ = Rotation.Z; break; case ProjectionMode.ISO: rotX = -35.0; rotY = -45.0; rotZ = 0.0; break; case ProjectionMode.ORT_F: rotX = 0.0; rotY = 0.0; rotZ = 0.0; break; case ProjectionMode.ORT_L: rotX = 0.0; rotY = 90.0; rotZ = 0.0; break; case ProjectionMode.ORT_T: rotX = -90.0; rotY = 0.0; rotZ = 0.0; break; } // compute transformation ( scale and rotation ) matrix DMatrix4 mat = DMatrix4.Identity; double scale = 100.0; RotateMatrix(ref mat, rotX, rotY, rotZ); ScaleMatrix(ref mat, scale * Scale.X * WindowScale, scale * Scale.Y * WindowScale, scale * Scale.Z * WindowScale); // transform verticis of object foreach (Vertex v in Vertecis) { v.Point = mat * v._Point; } Polygons.QuickSort(p => p.Vertex.Average(v => v.Point.Z)); // draw main object foreach (Polygon p in Polygons) { p.Normal = CrossProduct(p.Vertex[0].Point - p.Vertex[1].Point, p.Vertex[1].Point - p.Vertex[2].Point); p.Normal /= p.Normal.GetLength(); if (p.Normal.Z > 0) { DrawPolygonFixGaps2(p, e.Graphics, e.Width, e.Heigh); } } // some optional features foreach (Polygon p in Polygons) { if (p.Normal.Z > 0) { if (EnableNormals) { DrawNormal(p, e.Graphics, e.Width, e.Heigh); } if (EnableVertexNumbers) { DrawVertexNumbers(p, e.Graphics, e.Width, e.Heigh); } } } // Drawing axis (in the right lower corner) DVector4 ox = mat * (new DVector4(1.0, 0.0, 0.0, 0.0)); DVector4 oy = mat * (new DVector4(0.0, 1.0, 0.0, 0.0)); DVector4 oz = mat * (new DVector4(0.0, 0.0, 1.0, 0.0)); ox = ox / ox.GetLength() * 50.0 * WindowScale; oy = oy / oy.GetLength() * 50.0 * WindowScale; oz = oz / oz.GetLength() * 50.0 * WindowScale; DVector4 pos = new DVector4(e.Width - 70.0 * WindowScale, e.Heigh - 70.0 * WindowScale, 0.0, 0.0); DrawAxis(e.Graphics, ox, oy, oz, pos); }
public static double fastNormF(DMatrix4 M) { double sum = M.a1 * M.a1 + M.a2 * M.a2 + M.a3 * M.a3 + M.a4 * M.a4; return(Math.Sqrt(sum)); }