要达到测试形状,您不需要线性代数。您可以
GraphicsPath为您的形状创建,然后使用
GraphicsPath.IsVisible或
GraphicsPath.IsOutlineVisible方法执行命中测试。
要检查路径中是否有点,例如填充的形状,请使用
IsVisible
。要测试线条,曲线或空的形状,可以使用
IsOutlineVisible
。
例如,您可以创建一个基本
IShape接口,其中包含用于命中测试,绘图和移动的方法。然后在类中实现这些方法。您还可以创建一个
DrawingSurface控件,该控件可以处理命中测试,绘图和移动
IShape对象。
在下面的示例中,我们创建
IShape接口
Line和
Circle类。我们也创建一个
DrawingSurface控件。为了测试该示例,它足以将
DrawingSurface控件放在a上
Form并处理
Load表单事件并添加一些形状,然后运行应用程序并尝试移动形状。
形状
该接口包含一些有用的方法,如果有任何类可以实现这些方法,则可以将它们用于绘图,命中测试和移动。在本示例的最后,您可以看到一个
DrawingSurface可以
IShape简单地与实现一起使用的控件:
public interface IShape{ GraphicsPath GetPath(); bool HitTest(Point p); void Draw(Graphics g); void Move(Point d);}
线
这是实现
IShape接口的线类。在点击测试时,如果您单击行,则
HitTest返回true。另外,为了让您更简单地选择行,我为命中测试添加了2分:
public class Line : IShape{ public Line() { LineWidth = 2; LineColor = Color.Black; } public int LineWidth { get; set; } public Color LineColor { get; set; } public Point Point1 { get; set; } public Point Point2 { get; set; } public GraphicsPath GetPath() { var path = new GraphicsPath(); path.AddLine(Point1, Point2); return path; } public bool HitTest(Point p) { var result = false; using (var path = GetPath()) using (var pen = new Pen(LineColor, LineWidth + 2)) result = path.IsOutlineVisible(p, pen); return result; } public void Draw(Graphics g) { using (var path = GetPath()) using (var pen = new Pen(LineColor, LineWidth)) g.DrawPath(pen, path); } public void Move(Point d) { Point1 = new Point(Point1.X + d.X, Point1.Y + d.Y); Point2 = new Point(Point2.X + d.X, Point2.Y + d.Y); }}
圈
这是一个实现
IShape接口的圈子类。如果您单击圆圈,则进行命中测试时,
HitTest返回true:
public class Circle : IShape{ public Circle() { FillColor = Color.Black; } public Color FillColor { get; set; } public Point Center { get; set; } public int Radious { get; set; } public GraphicsPath GetPath() { var path = new GraphicsPath(); var p = Center; p.Offset(-Radious, -Radious); path.AddEllipse(p.X, p.Y, 2 * Radious, 2 * Radious); return path; } public bool HitTest(Point p) { var result = false; using (var path = GetPath()) result = path.IsVisible(p); return result; } public void Draw(Graphics g) { using (var path = GetPath()) using (var brush = new SolidBrush(FillColor)) g.FillPath(brush, path); } public void Move(Point d) { Center = new Point(Center.X + d.X, Center.Y + d.Y); }}
图纸表面
该控件绘制形状列表。此外,它还会执行命中测试,
MouseDown并在拖动时移动形状。您应该添加一些形状,例如
Line或添加
Circle到
Shapes控件集合中。
public class DrawingSurface : Control{ public List<IShape> Shapes { get; private set; } IShape selectedShape; bool moving; Point previousPoint = Point.Empty; public DrawingSurface() { DoubleBuffered = true; Shapes = new List<IShape>(); } protected override void onMouseDown(MouseEventArgs e) { for (var i = Shapes.Count - 1; i >= 0; i--) if (Shapes[i].HitTest(e.Location)) { selectedShape = Shapes[i]; break; } if (selectedShape != null) { moving = true; previousPoint = e.Location; } base.onMouseDown(e); } protected override void onMouseMove(MouseEventArgs e) { if (moving) { var d = new Point(e.X - previousPoint.X, e.Y - previousPoint.Y); selectedShape.Move(d); previousPoint = e.Location; this.Invalidate(); } base.onMouseMove(e); } protected override void onMouseUp(MouseEventArgs e) { if (moving) { selectedShape = null; moving = false; } base.onMouseUp(e); } protected override void onPaint(PaintEventArgs e) { e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; foreach (var shape in Shapes) shape.Draw(e.Graphics); }}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)