首先,非常感谢回答这个问题的人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);
//}
}
}
代码是混乱的,我很抱歉,但你可以看看我的尝试。
1条答案
按热度按时间pw136qt21#
使用一个方法来创建和返回
GraphicsPath
对象,并向接口或实现类(取决于形状)添加属性,这些属性定义了应该如何创建路径以及应该应用哪些转换和/或变换(如果有)。由于任何形状都可以旋转、缩放和平移,因此
IShape
接口是为这些操作提供抽象属性的合适位置。I形状
按要求在这里进行覆盖轮换。
"菱形“
的相关落实。
设置新的旋转值时,不要忘记调用
yourDrawingCanvas.Invalidate();
。