public void FitToScreenTransform(Box2 bbox) { Offset.Set(0, 0); TurnOrigin.Set(0, 0); Scale = 1; // применяем к собранным вершинам преобразование координат // инвертирование оси Y, перенос базиса в центр экрана // + изменяемый масштаб, поворот и перенос var transformedVertices = bbox.ToArray(); var center = GetDefaultOrigin(); var mx = new Matrix(); DefaultTransform(mx, center); mx.Multiply(Transform); mx.TransformPoints(transformedVertices); // получили экранные координаты вершин var tbbox = Box2.Empty; // ищем мин/макс координаты группы вершин for (var i = 0; i < transformedVertices.Length; i++) { tbbox.Merge(transformedVertices[i]); } // получили bounding box в экранных координатах. // (ось Y направлена вниз) var tbbDiag = tbbox.Max - tbbox.Min; var tbbCenter = tbbox.Min + tbbDiag / 2; var cbbox = RenderingOutput.ClientRectangle; var cbboxCenter = new Vector2(cbbox.Width, cbbox.Height) / 2; var addOffset = cbboxCenter - tbbCenter; addOffset.X /= +Scale; addOffset.Y /= -Scale; addOffset.Rotate(-Turn.Radians); var boundingRect = new System.Drawing.Rectangle(0, 0, (int)Math.Ceiling(Math.Abs(tbbDiag.X)), (int)Math.Ceiling(Math.Abs(tbbDiag.Y))); var newScale = Math.Min((double)cbbox.Width / boundingRect.Width, (double)cbbox.Height / boundingRect.Height); Offset += addOffset; Scale = newScale * Scale * 0.8; }