static Matrix3x3() { _identityMatrix = new Matrix3x3( 1, 0, 0, 0, 1, 0, 0, 0, 1); }
/// <summary> /// Prepends a transformation matrix <paramref name="a"/> to this matrix. /// </summary> /// <param name="a">The matrix to prepend.</param> public void PrependTransform(Matrix3x3 a) { double h1, h2, h3; h1 = M11 * a.M11 + M21 * a.M12 + M31 * a.M13; h2 = M11 * a.M21 + M21 * a.M22 + M31 * a.M23; h3 = M11 * a.M31 + M21 * a.M32 + M31 * a.M33; M11 = h1; M21 = h2; M31 = h3; h1 = M12 * a.M11 + M22 * a.M12 + M32 * a.M13; h2 = M12 * a.M21 + M22 * a.M22 + M32 * a.M23; h3 = M12 * a.M31 + M22 * a.M32 + M32 * a.M33; M12 = h1; M22 = h2; M32 = h3; h1 = M13 * a.M11 + M23 * a.M12 + M33 * a.M13; h2 = M13 * a.M21 + M23 * a.M22 + M33 * a.M23; h3 = M13 * a.M31 + M23 * a.M32 + M33 * a.M33; M13 = h1; M23 = h2; M33 = h3; Determinant *= a.Determinant; }
/// <summary> /// Appends a transformation matrix <paramref name="f"/> to this matrix, and returns a new matrix with the result. The original matrix is unchanged. /// </summary> /// <param name="f">The matrix to append.</param> /// <returns>A new matrix based on the existing one, but with matrix <paramref name="f"/> appended.</returns> public Matrix4x3 WithAppendedTransformation(Matrix3x3 f) { return new Matrix4x3( M11 * f.M11 + M12 * f.M21 + M13 * f.M31, M11 * f.M12 + M12 * f.M22 + M13 * f.M32, M11 * f.M13 + M12 * f.M23 + M13 * f.M33, M21 * f.M11 + M22 * f.M21 + M23 * f.M31, M21 * f.M12 + M22 * f.M22 + M23 * f.M32, M21 * f.M13 + M22 * f.M23 + M23 * f.M33, M31 * f.M11 + M32 * f.M21 + M33 * f.M31, M31 * f.M12 + M32 * f.M22 + M33 * f.M32, M31 * f.M13 + M32 * f.M23 + M33 * f.M33, M41 * f.M11 + M42 * f.M21 + M43 * f.M31, M41 * f.M12 + M42 * f.M22 + M43 * f.M32, M41 * f.M13 + M42 * f.M23 + M43 * f.M33, Determinant * f.Determinant ); }
/// <summary> /// Gets a transformation matrix by specifying rotation (translation is 0, shear is 0 and scale is 1). /// </summary> /// <param name="angleX">The rotation around x axis in degrees.</param> /// <param name="angleY">The rotation around y axis in degrees</param> /// <param name="angleZ">The rotation around z axis in degrees</param> /// <returns>The transformation matrix.</returns> public static Matrix3x3 FromRotation(double angleX, double angleY, double angleZ) { var result = new Matrix3x3(); result.SetRotationShearScale(angleX, angleY, angleZ, 0, 0, 0, 1, 1, 1); return result; }
/// <summary> /// Appends a transformation matrix <paramref name="f"/> to this matrix. /// </summary> /// <param name="f">The matrix to append.</param> public void AppendTransform(Matrix3x3 f) { double h1, h2, h3; h1 = M11 * f.M11 + M12 * f.M21 + M13 * f.M31; h2 = M11 * f.M12 + M12 * f.M22 + M13 * f.M32; h3 = M11 * f.M13 + M12 * f.M23 + M13 * f.M33; M11 = h1; M12 = h2; M13 = h3; h1 = M21 * f.M11 + M22 * f.M21 + M23 * f.M31; h2 = M21 * f.M12 + M22 * f.M22 + M23 * f.M32; h3 = M21 * f.M13 + M22 * f.M23 + M23 * f.M33; M21 = h1; M22 = h2; M23 = h3; h1 = M31 * f.M11 + M32 * f.M21 + M33 * f.M31; h2 = M31 * f.M12 + M32 * f.M22 + M33 * f.M32; h3 = M31 * f.M13 + M32 * f.M23 + M33 * f.M33; M31 = h1; M32 = h2; M33 = h3; Determinant *= f.Determinant; }
public RectangleD3D GetBounds(Matrix3x3 additionalTransformation) { return RectangleD3D.NewRectangleIncludingAllPoints(Points.Select(p => additionalTransformation.Transform(_transformation.Transform(p)))); }
/// <summary> /// Gets a transformation matrix by specifying translation, rotation, shear and scale. /// </summary> /// <param name="angleX">The rotation around x axis in degrees.</param> /// <param name="angleY">The rotation around y axis in degrees</param> /// <param name="angleZ">The rotation around z axis in degrees</param> /// <param name="shearX">The shear value x.</param> /// <param name="shearY">The shear value y.</param> /// <param name="shearZ">The shear value z.</param> /// <param name="scaleX">The scale value x.</param> /// <param name="scaleY">The scale value y.</param> /// <param name="scaleZ">The scale value z.</param> /// <returns>The transformation matrix. A point transformed with this matrix is first translated, then rotated, then sheared, then scaled.</returns> public static Matrix3x3 FromTranslationRotationShearScale(double angleX, double angleY, double angleZ, double shearX, double shearY, double shearZ, double scaleX, double scaleY, double scaleZ) { var result = new Matrix3x3(); result.SetRotationShearScale(angleX, angleY, angleZ, shearX, shearY, shearZ, scaleX, scaleY, scaleZ); return result; }
public override void RotateTransform(double degreeX, double degreeY, double degreeZ) { if (0 != degreeZ) _transformation.RotationZDegreePrepend(degreeZ); if (0 != degreeY) _transformation.RotationYDegreePrepend(degreeY); if (0 != degreeX) _transformation.RotationXDegreePrepend(degreeX); if (0 != degreeZ || 0 != degreeY || 0 != degreeX) _transposedInverseTransformation = _transformation.GetTransposedInverseMatrix3x3(); }
internal GraphicState(Matrix4x3 transformation, Matrix3x3 transposedInverseTransformation) { Transformation = transformation; TransposedInverseTransformation = transposedInverseTransformation; }
public override void PrependTransform(Matrix4x3 m) { _transformation.PrependTransform(m); _transposedInverseTransformation = _transformation.GetTransposedInverseMatrix3x3(); }
public override void RestoreGraphicsState(object graphicsState) { var gs = graphicsState as GraphicState; if (null != gs) { _transformation = gs.Transformation; _transposedInverseTransformation = gs.TransposedInverseTransformation; } else throw new ArgumentException(nameof(graphicsState) + " is not a valid graphic state!"); }
public RectangleD3D GetBounds(Matrix3x3 transformation) { return RectangleD3D.NewRectangleIncludingAllPoints(AsPoints().Select(p => transformation.Transform(p))); }
private RectangleD3D GetBounds(IObjectOutline outline, Matrix3x3 transformation) { return RectangleD3D.NewRectangleIncludingAllPoints(AsPoints(outline).Select(p => transformation.Transform(p))); }
/// <summary> /// Gets the principal coordinate system that results of the camera facing a layer. The plane of the layer that best faced the camera is used for the calculations. /// The normal of that layer is returned as z-axis, the vector that best matches the up-vector of the camera is becoming the y-axis, /// and the x-axis results from the z-axis and the y-axis. /// </summary> /// <param name="camera">The camera.</param> /// <param name="activeLayer">The active layer of the graph document.</param> /// <param name="transformation">Matrix that contains the principal axes as described above. The axes coordinates are in the coordinates of the layer provided in the argument <paramref name="activeLayer"/>.</param> /// <exception cref="InvalidProgramException">There should always be a plane of a rectangle that can be hit!</exception> public static void GetCoordinateSystemBasedOnLayerPlaneFacingTheCamera(CameraBase camera, HostLayer activeLayer, out Matrix3x3 transformation) { PointD3D hitposition = new PointD3D(0.5, 0.5, 1); // this hit position is arbitrary, every other position should work similarly var activeLayerTransformation = activeLayer.TransformationFromRootToHere(); var hitData = new HitTestPointData(camera.GetHitRayMatrix(hitposition)); hitData = hitData.NewFromAdditionalTransformation(activeLayerTransformation); // now hitdata are in layer cos var targetToEye = hitData.WorldTransformation.Transform(camera.TargetToEyeVectorNormalized); // targetToEye in layer coordinates var upEye = hitData.WorldTransformation.Transform(camera.UpVectorPerpendicularToEyeVectorNormalized); // camera up vector in layer coordinates // get the face which has the best dot product between the eye vector of the camera and the plane's normal var layerRect = new RectangleD3D(PointD3D.Empty, activeLayer.Size); double maxval = double.MinValue; PlaneD3D maxPlane = PlaneD3D.Empty; foreach (var plane in layerRect.Planes) { double val = VectorD3D.DotProduct(plane.Normal, targetToEye); if (val > maxval) { maxval = val; maxPlane = plane; } } // bool isHit = hitData.IsPlaneHitByRay(maxPlane, out hitPointOnPlaneInActiveLayerCoordinates); // hitPointOnPlane is in layer coordinates too // if (!isHit) // throw new InvalidProgramException("There should always be a plane of a rectangle that can be hit!"); VectorD3D zaxis = maxPlane.Normal; VectorD3D yaxis = upEye; // Find y axis perpendicular to zaxis maxval = double.MinValue; foreach (var plane in layerRect.Planes) { double val = VectorD3D.DotProduct(plane.Normal, upEye); if (val > maxval && 0 == VectorD3D.DotProduct(plane.Normal, zaxis)) { maxval = val; yaxis = plane.Normal; } } var xaxis = VectorD3D.CrossProduct(yaxis, zaxis); // now we have all information about the spatial position and orientation of the text: // hitPointOnPlane is the position of the text // maxPlane.Normal is the face orientation of the text // maxUpVector is the up orientation of the text xaxis = xaxis.Normalized; yaxis = yaxis.Normalized; zaxis = zaxis.Normalized; transformation = new Matrix3x3( xaxis.X, yaxis.X, zaxis.X, xaxis.Y, yaxis.Y, zaxis.Y, xaxis.Z, yaxis.Z, zaxis.Z ); }