public GroupFigure(List <Figure> figures = null) { if (figures == null) { _placeHolder = new Placeholder(); figures = new List <Figure> { _placeHolder }; } Style.BorderStyle = null; var path = new SerializableGraphicsPath(); path.Path.AddRectangle(new RectangleF(-0.5f, -0.5f, 1, 1)); foreach (var figure in figures) { var fig = figure.DeepClone(); fig.Transform.Matrix.Multiply(Transform, MatrixOrder.Append); _figures.Add(fig); } Geometry = new PrimitiveGeometry(path, AllowedOperations.All ^ (AllowedOperations.Vertex | AllowedOperations.Pathed)) { Name = "Group" }; Renderer = new GroupRenderer(); Transform = new SerializableGraphicsMatrix(); }
/// <summary> /// Масштабирование /// </summary> /// <param name="scaleX">Коэффициент масштабирования по горизонтали</param> /// <param name="scaleY">Коэффициент масштабирования по вертикали</param> /// <param name="anchor">Координаты "якоря" (в мировых координатах)</param> public void Scale(float scaleX, float scaleY, PointF anchor) { //можем менять размер? var allowSize = Geometry.AllowedOperations.HasFlag(AllowedOperations.Size); var allowScale = Geometry.AllowedOperations.HasFlag(AllowedOperations.Scale); if (!allowScale && !allowSize) { return; //не можем менять размеры } if (allowScale && !allowSize) { //можем шкалировать, но с сохранением аспекта //сохраняем аспект scaleX = scaleY = Math.Max(scaleX, scaleY); } //шкалируем относительно якоря var m = new SerializableGraphicsMatrix(); m.Matrix.Translate(anchor.X, anchor.Y); //переводим центр координат в якорь m.Matrix.Scale(scaleX, scaleY); //масштабируем m.Matrix.Translate(-anchor.X, -anchor.Y); //возвращаем центр координат // Transform = m; }
/// <summary> /// Копирование геометрий выделенных фигур в свою геометрию /// </summary> private void GrabGeometry() { // захватываем геометрию выбранных фигур var path = new SerializableGraphicsPath(); foreach (var fig in _selected) { path.Path.SetMarkers(); path.Path.AddPath(fig.GetTransformedPath(), false); } // нарисовать рамку вокруг выбранных фигур if (IsFrameVisible) { var bounds = path.Path.GetBounds(); path.Path.AddRectangle(bounds); } // выбираем разрешённые операции // если выбрана только одна фигура - просто используем её AllowedOperations // иначе - разрешаем все операции var allowedOperations = _selected.Count == 1 ? _selected.First().Geometry.AllowedOperations : AllowedOperations.All; // присваиваем геометрию Geometry = new PrimitiveGeometry(path, allowedOperations); // сбрасываем преобразование в единичную матрицу Transform = new SerializableGraphicsMatrix(); }
/// <summary> /// Перенос фигур из списка /// </summary> /// <param name="offsetX">Смещение по горизонтали</param> /// <param name="offsetY">Смещение по вертикали</param> public void Translate(float offsetX, float offsetY) { var m = new SerializableGraphicsMatrix(); m.Matrix.Translate(offsetX, offsetY); // делаем на "чистой" матрице Transform = m; }
public override void PushTransform(Matrix matrix) { Transform.Matrix.Multiply(matrix, MatrixOrder.Append); foreach (var fig in _figures) { fig.Transform.Matrix.Multiply(Transform, MatrixOrder.Append); if (fig is Placeholder) { _placeHolder = fig.DeepClone(); } } Transform = new SerializableGraphicsMatrix(); }
/// <summary> /// Поворот /// </summary> /// <param name="angle">Угол поворота, в градусах</param> /// <param name="center">Координаты центра вращения (в мировых координатах)</param> public void Rotate(float angle, PointF center) { //можем вращать? var allowRotate = Geometry.AllowedOperations.HasFlag(AllowedOperations.Rotate); if (!allowRotate) { return; //не можем вращать } //вращаем относительно якоря var m = new SerializableGraphicsMatrix(); m.Matrix.RotateAt(angle, center); //вращаем // Transform = m; }
/// <summary> /// Поворот на четверть по часовой стрелке /// </summary> public static void Rotate90Cw(this Selection selection) { //можем вращать? var allowRotate = selection.Geometry.AllowedOperations.HasFlag(AllowedOperations.Rotate); if (!allowRotate) { return; //не можем вращать } var m = new SerializableGraphicsMatrix(); var anchor = selection.ToWorldCoordinates(new PointF(0.5f, 0.5f)); m.Matrix.Translate(anchor.X, anchor.Y); //переводим центр координат в якорь //отражаем по вертикали относительно якоря m.Matrix.Multiply(new Matrix(0, 1, -1, 0, 0, 0)); m.Matrix.Translate(-anchor.X, -anchor.Y); //возвращаем центр координат // selection.Transform = m; }
/// <summary> /// Искривление /// </summary> /// <param name="skewX">Коэффициент сдвига по горизонтали</param> /// <param name="skewY">Коэффициент сдвига по вертикали</param> /// <param name="anchor">Координаты "якоря" (в мировых координатах)</param> public void Skew(float skewX, float skewY, PointF anchor) { //можем искажать? var allowSkew = Geometry.AllowedOperations.HasFlag(AllowedOperations.Skew); if (!allowSkew) { return; //не можем искажать } //сдвигаем относительно якоря var m = new SerializableGraphicsMatrix(); m.Matrix.Translate(anchor.X, anchor.Y); //переводим центр координат в якорь m.Matrix.Shear(skewX, skewY); //сдвигаем m.Matrix.Translate(-anchor.X, -anchor.Y); //возвращаем центр координат // Transform = m; }
/// <summary> /// Конструктор фигуры для задания свойств по умолчанию /// </summary> public Figure() { Transform = new SerializableGraphicsMatrix(); Style = new Style.Style(); Renderer = new DefaultRenderer(); }