winforms C#将图形路径内的多边形旋转45

x6492ojm  于 2022-12-14  发布在  C#
关注(0)|答案(1)|浏览(189)

首先,非常感谢回答这个问题的人How to drag and move shapes in C#,这一切都是基于这个问题。我才刚刚开始使用c#和WinForms,所以我真的很感激任何建议。
我有IShape接口和实现它的类(星星,Rhombus)。我需要在窗体上显示形状,并移动、旋转和缩放它们。到目前为止,我有这个。我可以选择和移动形状。我不知道如何使用矩阵旋转多边形,因为我的draw方法使用GetPath(),它在每次重绘图像时都会创建一个新的路径,我不能修改路径内的点。
我应该创建另一个图形路径从原来的一个和旋转它或做其他事情?任何帮助将不胜感激。

I形状

using System;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Threading.Tasks;
using System.Drawing.Drawing2D;
using System.Collections.Generic;

namespace GSC_LR4
{
    interface IShape
    {
        GraphicsPath GetPath();
        bool Selected(PointF p);
        void Draw(Graphics g);
        void Move(PointF m);
         PointF Min();
         PointF Max();
        PointF Center();

        //void Zoom(PointF z);
        //void Mirrored(PointF h);
        GraphicsPath GetRotatedPath();
        void GetBorders();
        //void Delete(PointF s);
        void VertexClear();
        void DrawSelection(Graphics e)
    }
}

"菱形“

using System;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Threading.Tasks;
using System.Drawing.Drawing2D;
using System.Collections.Generic;

namespace GSC_LR4
{
    class Rhombus : IShape
    {
        List<PointF> VertexList { get; set; }
        public PointF maxPoint;
        public PointF minPoint;
        public PointF center;
        public Color oColor { get; set; }

        public Rhombus(PointF p)
        {
            VertexList = new List<PointF>();
            maxPoint = new PointF();
            minPoint = new PointF();
            center = p;           
        }

        public Rhombus(List<PointF> vertexes, Color color)
        {
            VertexList = vertexes.ConvertAll(item => new PointF(item.X, item.Y));
            maxPoint = new PointF();
            minPoint = new PointF();
            oColor = color;
        }

        public Rhombus(Color Color)
        {
            center = new PointF(150, 150);
            oColor = Color;
        }

        public GraphicsPath GetPath()
        {
            var path = new GraphicsPath();
            PointF[] VertexRhomb = new PointF[4];
            VertexRhomb[0].X = center.X - 80;
            VertexRhomb[0].Y = center.Y;
            VertexRhomb[1].X = center.X;
            VertexRhomb[1].Y = center.Y - 100;
            VertexRhomb[2].X = center.X + 80;
            VertexRhomb[2].Y = center.Y;
            VertexRhomb[3].X = center.X;
            VertexRhomb[3].Y = center.Y + 100;
           // VertexList.AddRange(VertexRhomb.ToArray());
            path.AddPolygon(VertexRhomb.ToArray());
            return path;
        }

        public GraphicsPath GetRotatedPath()
        {
            var path = new GraphicsPath();
            List<PointF> temp = new List<PointF>();
            temp.AddRange(GetPath().PathPoints);
            path.AddPolygon(temp.ToArray());
            Matrix rotateMtx = new Matrix();
            //rotateMtx.Translate(center.X, center.Y);
            rotateMtx.RotateAt(45f, center);
            //rotateMtx.Translate(-center.X, -center.Y);
            path.Transform(rotateMtx);
            return path;
        }

        public void Draw(Graphics g)
        {
            using(var path = GetPath())
            using (var brush = new SolidBrush(oColor))
                g.FillPath(brush, path);
        }

        public void Move(PointF d)
        {
            center = new PointF(center.X + d.X, center.Y + d.Y);
        }

        public bool Selected(PointF p)
        {
            bool selected = false;
            using (var path = GetPath())
                selected = path.IsVisible(p);
            return selected;
        }

        public void GetBorders()
        {
            minPoint.X = VertexList.Min(item => item.X);
            minPoint.Y = VertexList.Min(item => item.Y);
            maxPoint.X = VertexList.Max(item => item.X);
            maxPoint.Y = VertexList.Max(item => item.Y);
        }

        public PointF Min()
        {
            PointF p = new PointF();
            p.X = GetPath().PathPoints.Min(item => item.X);
            p.Y = GetPath().PathPoints.Min(item => item.Y);
            //p.X = VertexList.Min(item => item.X);
            //p.Y = VertexList.Min(item => item.Y);
            return p;
        }

        public PointF Max()
        {
            PointF p = new PointF();
            //p.X = VertexList.Max(item => item.X);
            //p.Y = VertexList.Max(item => item.Y);
            p.X = GetPath().PathPoints.Max(item => item.X);
            p.Y = GetPath().PathPoints.Max(item => item.Y);
            return p;
        }

        public PointF Center()
        {
            PointF Pmin = Min();
            PointF Pmax = Max();
            return new PointF((Pmax.X + Pmin.X) / 2, (Pmax.Y + Pmin.Y) / 2);
        }

        public void VertexClear()
        {
            VertexList.Clear();
        }

        public void DrawSelection(Graphics e)
        {
            int Xmin = (int)Min().X,
                  Ymin = (int)Min().Y;
            int Xmax = (int)Max().X,
                Ymax = (int)Max().Y;

            Pen pen = new Pen(Color.Gray);
            pen.DashStyle = DashStyle.Dash; // штрихованная линия
            e.DrawRectangle(pen, new Rectangle(Xmin, Ymin, Xmax - Xmin, Ymax - Ymin));
        }

        //public void Rotate()
        //{
            //double cos = Math.Cos(45 * Math.PI / 180); //maybe refactor 
            //double sin = Math.Sin(45 * Math.PI / 180);
            //PointF[] VertexRhomb = new PointF[4];
            //for (int i = 0; i < GetPath().PointCount; i++) //sides = 6? 
            //{
            //    PointF p = new PointF();
            //    p.X = (float)((VertexRhomb[i].X - center.X) * cos - (VertexRhomb[i].Y - center.Y) * sin + center.X);
            //    p.Y = (float)((VertexRhomb[i].X - center.X) * sin + (VertexRhomb[i].Y - center.Y) * cos + center.Y);
            //    VertexRhomb[i] = new PointF(p.X, p.Y);
            //    //p.X = (float)(cos * ((GetPath().PathPoints[i].X) - Center().X) - sin * ((GetPath().PathPoints[i].Y) - Center().Y) + (Center().X));
            //    //p.Y = (float)(sin * ((GetPath().PathPoints[i].X) - Center().X) + cos * ((GetPath().PathPoints[i].Y) - Center().Y) + (Center().Y))

           //}
            //GetPath().AddPolygon(VertexRhomb.ToArray());
            //Matrix rotateMtx = new Matrix();
            //rotateMtx.Translate(center.X, center.Y);
            //rotateMtx.RotateAt(45f, center);
            //rotateMtx.Translate(-center.X, -center.Y);
            //using (var path = GetPath())
            //GetPath().Transform(rotateMtx);
        //}
    }
}

代码是混乱的,我很抱歉,但你可以看看我的尝试。

pw136qt2

pw136qt21#

使用一个方法来创建和返回GraphicsPath对象,并向接口或实现类(取决于形状)添加属性,这些属性定义了应该如何创建路径以及应该应用哪些转换和/或变换(如果有)。
由于任何形状都可以旋转、缩放和平移,因此IShape接口是为这些操作提供抽象属性的合适位置。

I形状

按要求在这里进行覆盖轮换。

public interface IShape
{
    GraphicsPath GetPath();
    float RotationAngle { get; set; }

    // ...etc.
}

"菱形“
的相关落实。

public class Rhombus : IShape
{
    //...

    public float RotationAngle { get; set; }

    public GraphicsPath GetPath()
    {
        var path = new GraphicsPath();
        var VertexRhomb = new[]
        {
            new PointF(center.X - 80, center.Y),
            new PointF(center.X, center.Y - 100),
            new PointF(center.X + 80, center.Y),
            new PointF(center.X, center.Y + 100)
        };
        path.AddPolygon(VertexRhomb.ToArray());

        if (RotationAngle != 0)
        {
            var mx = new Matrix();
            mx.RotateAt(RotationAngle, center);
            path.Transform(mx);
        }

        return path;
    }

    public void Draw(Graphics g)
    {
        using (var path = GetPath())
        using (var brush = new SolidBrush(oColor))
            g.FillPath(brush, path);
    }
}

设置新的旋转值时,不要忘记调用yourDrawingCanvas.Invalidate();

相关问题