public T_Viewport(SizeF sourceSize, Vector2D sourceUnits, SizeF targetSize, Vector2D targetUnits, Rotation targetRotation) { this.sourceSize = sourceSize; this.sourceUnits = sourceUnits; this.targetSize = targetSize; this.targetUnits = targetUnits; this.targetRotation = targetRotation; // create 2D scaling & rotation & axis reflection var normalizedTargetSize = Matrix2x2.RotationMatrix(targetRotation.ReverseRotation()) * targetSize; float mx = normalizedTargetSize.Width / sourceSize.Width; float my = normalizedTargetSize.Height / sourceSize.Height; var reflection = Matrix2x2.Unit(); if (targetUnits.x * sourceUnits.x < 0) { reflection.x1y1 = -1; } if (targetUnits.y * sourceUnits.y < 0) { reflection.x2y2 = -1; } Matrix2x2 scaleRotateReflect = new Matrix2x2(mx, 0, 0, my) * Matrix2x2.RotationMatrix(targetRotation) * reflection; // combine with translation into a 3D matrix m = new Matrix3x3(scaleRotateReflect); if (m.x1y1 < 0) { m.x3y1 = normalizedTargetSize.Width; } if (m.x1y2 < 0) { m.x3y2 = normalizedTargetSize.Width; } if (m.x2y1 < 0) { m.x3y1 = normalizedTargetSize.Height; } if (m.x2y2 < 0) { m.x3y2 = normalizedTargetSize.Height; } }
public static Matrix2x2 RotationMatrix(Rotation rotation, float unit = 1f) { switch (rotation) { case Rotation.Rotate90: return(new Matrix2x2(0f, -unit, unit, 0f)); case Rotation.Rotate180: return(new Matrix2x2(-unit, 0f, 0f, -unit)); case Rotation.Rotate270: return(new Matrix2x2(0f, unit, -unit, 0f)); default: break; } return(Matrix2x2.Unit(unit)); }