重画方法中写:选中:获取鼠标点坐标point,以point为中心做一个类似缓冲区的东西,当单击鼠标时判断直
线是否穿过区域,如果是就把直线反色显示或者做别的标志,表示选中,也可以做一个
boundbox,把直线的边界现实出来。拉长,变形,随背景画面放大缩小:把直线坐标乘以Matrix就可以了。
线是否穿过区域,如果是就把直线反色显示或者做别的标志,表示选中,也可以做一个
boundbox,把直线的边界现实出来。拉长,变形,随背景画面放大缩小:把直线坐标乘以Matrix就可以了。
解决方案 »
- C#链接多种数据库
- 请问怎么这个XML怎么遍历?
- 关于线程堆栈和堆
- word中的特殊符合集合是什么,什么办法可以替换掉里面的所有特殊符合(如:括号,* 等,我知道可以用Replace(oldString,newString))
- winform的datagrid数据导出到excel中?
- 请问FlowLayoutPanel控件中当WrapContents=true,flowDirection=LeftToRight添加控件时怎么实现手动换行
- C#如何自定义word文档的文字颜色
- 菜鸟类型转换问题
- arraylist简单问题????????????????????????????
- C#中关于listview加载10000个图片,提示内存不足的问题
- 组件之间的通信是用消息好还是用接口好
- 一个超强的.net反编译器都来看看!
我的mail: [email protected]
其中需要说明一下:
这其实是一个非常通用的问题,一般做法如zhunter(xz) 所说,封装一个形状类,然后进行绘制,利用鼠标事件判断当前操作,然后对形状进行matrix变形即可。
在例子中,实现了移动和缩放,同样的方法可以实现扭曲和旋转,都一样,但在处理scale时,计算放缩倍比比较麻烦,所以偷了一个懒,直接用直线坐标代替了:)严格的做法,是要通过matrix进行!这过程如下
计算放缩(扭曲)倍比,定出中心点,然后
matrix.translate(centerpoint.x,centerpoint.y);
matrix.scale(x,y);
matrix.translate(-centerpoint.x,-centerpoint.y);
对于旋转则直接可以用matrix.roateat(angle,centerpoint)进行。另,在变形过程中,例子全部采用了invalidate方法,这样比较慢,如果比较正规,需要用到异或绘图绘制橡皮筋,可以参看在zC#中应用GDI Api相关函数的介绍。但愿能对你有所帮助:)using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing.Drawing2D;namespace SimpleSVG
{
public enum Operate
{
Scale,
Rotate,
Translate,
None
}
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
#region ..构造及消除
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null; public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
this.p1 = new PointF(50,50);
this.p2 = new PointF(300,300); //
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
} /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
} #region Windows Form Designer generated code
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(400, 349);
this.Name = "Form1";
this.Text = "Form1"; }
#endregion
#endregion
#region ..私有变量
bool check = false;
Operate operate = Operate.None;
PointF centerPoint = PointF.Empty;
Matrix transform = new Matrix();
PointF startpoint = PointF.Empty;
GraphicsPath reversePath = new GraphicsPath();
PointF p1 = PointF.Empty;
PointF p2 = PointF.Empty;
Size orisize = Size.Empty;
#endregion #region ..属性
bool Check
{
set
{
if(this.check != value)
{
this.check = value;
this.Invalidate();
}
}
} Matrix Transform
{
set
{
this.transform = value;
PointF[] ps = new PointF[]{p1,p2};
this.transform.TransformPoints(ps);
this.p1 = ps[0];
this.p2 = ps[1];
this.Invalidate();
}
}
#endregion #region ..重绘
protected override void OnPaint(PaintEventArgs e)
{
SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint,true);
GraphicsPath linepath = new GraphicsPath();
linepath.AddLine(p1,p2);
//选中绘制操作手柄
if(this.check)
{
linepath.AddRectangle(new RectangleF(p1.X - 2,p1.Y -2,4,4));
linepath.AddRectangle(new RectangleF(p2.X - 2,p2.Y -2,4,4));
} e.Graphics.FillPath(Brushes.White,linepath);
e.Graphics.DrawPath(Pens.Red,linepath); //绘制变形路径
e.Graphics.DrawPath(Pens.Blue,this.reversePath);
this.orisize = this.Size;
}
#endregion #region ..OnMouseDown
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
PointF p = new PointF(e.X,e.Y);
GraphicsPath linepath = new GraphicsPath();
linepath.AddLine(p1,p2);
this.Check = linepath.IsOutlineVisible(p,new Pen(Color.Black,2));
this.startpoint = new PointF(e.X,e.Y);
}
#endregion #region ..OnMouseMove
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
//鼠标移动时判断相对位置
if(e.Button == MouseButtons.None && this.check)
{
GraphicsPath path = new GraphicsPath();
path.AddRectangle(new RectangleF(p1.X - 2,p1.Y - 2,4,4));
GraphicsPath path1 = new GraphicsPath();
path1.AddRectangle(new RectangleF(p2.X - 2,p2.Y - 2,4,4));
GraphicsPath path2 = new GraphicsPath();
path2.AddLine(p1,p2);
if(path.IsVisible(new PointF(e.X,e.Y)) || path.IsOutlineVisible(new PointF(e.X,e.Y),new Pen(Color.Black,2)))
{
this.operate = Operate.Scale;
this.centerPoint = p2;
}
else if(path1.IsVisible(new PointF(e.X,e.Y)) || path1.IsOutlineVisible(new PointF(e.X,e.Y),new Pen(Color.Black,2)))
{
this.operate = Operate.Scale;
this.centerPoint = p1;
}
else if(path2.IsOutlineVisible(new PointF(e.X,e.Y),new Pen(Color.Black,2)))
this.operate = Operate.Translate;
else
this.operate = Operate.None;
} if(e.Button == MouseButtons.Left)
{
this.reversePath.Reset();
switch(this.operate)
{
case Operate.Translate:
this.reversePath.AddLine(p1,p2);
this.reversePath.Transform(new Matrix(1,0,0,1,e.X - this.startpoint.X,e.Y - this.startpoint.Y));
break;
case Operate.Scale:
if(this.centerPoint == this.p1)
this.reversePath.AddLine(this.p1,new PointF(e.X,e.Y));
else if(this.centerPoint == this.p2)
this.reversePath.AddLine(new PointF(e.X,e.Y),this.p2);
break;
}
this.Invalidate();
}
}
#endregion #region ..OnMouseUp
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
this.reversePath.Reset();
switch(this.operate)
{
case Operate.Translate:
this.Transform = new Matrix(1,0,0,1,e.X - this.startpoint.X,e.Y - this.startpoint.Y);
break;
case Operate.Scale:
if(this.centerPoint == this.p1)
this.p2 = new PointF(e.X,e.Y);
else if(this.centerPoint == this.p2)
this.p1 = new PointF(e.X,e.Y);
this.Invalidate();
break;
}
this.operate = Operate.None;
}
#endregion #region ..OnResize
protected override void OnResize(EventArgs e)
{
System.Drawing.Size size = this.Size;
this.Transform = new Matrix((float)size.Width / (float)this.orisize.Width,0,0,(float)size.Height / (float)this.orisize.Height,0,0);
base.OnResize(e);
}
#endregion
}
}