想做一个类似于以下代码生成的一个橡皮筋,但是不知道怎么改,求高手指教。把箭头放到起点处。谢谢!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;//包含这个高级二维图形命名空间namespace ReverseLines
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent(); //激活双缓冲技术
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
} private Point[][] tranGroup = new Point[1000][];//变换组
private int tranNumb = 0;//变换序号
private int pushNumb = 0;//左键按下情况:0为开始画变换,1为结束
private Point curP;//存储变换时鼠标的当前点
private Point startP, oldP;//变换的起点和鼠标移动时的当前点
private Graphics g0,g3;//窗口绘图面和采用双缓冲时的临时绘图面
private Point endPoint;//存储右键按下时放弃绘制相连变换的鼠标点
private Color clr,clr1;//获取窗体背景色和反转背景色
private Pen p;//重画变换时所用的笔
private Bitmap bitmap = null;//双缓冲时用的位图 private void Form1_Paint(object sender, PaintEventArgs e)
{
g0 = e.Graphics; bitmap = new Bitmap(ClientSize.Width, ClientSize.Height);//创建临时位图
g3 = Graphics.FromImage(bitmap);//从位图创建绘图面
g3.Clear(this.BackColor);//清除背景色
g3.SmoothingMode = SmoothingMode.AntiAlias;//设置抗锯齿平滑模式 //在临时位图上重画变换,抗锯齿,带线冒
for (int i = 0; i < tranNumb; i++)
{
g3.DrawLine(p, tranGroup[i][0], tranGroup[i][1]);
} //把临时位图拷贝到窗体绘图面
g0.DrawImage(bitmap, 0, 0);
} private void Form1_Load(object sender, EventArgs e)
{
clr = this.BackColor;//获取窗体背景色
clr1 = Color.FromArgb(clr.A, 255 - clr.R, 255 - clr.G, 255 - clr.B);//反转背景色
p = new Pen(clr1, 1);//定义鼠标左键按下并移动时绘制变换所用的笔 //自定义线冒
AdjustableArrowCap cap = new AdjustableArrowCap(3, 3);
cap.WidthScale = 3;
cap.BaseCap = LineCap.Square;
cap.Height = 3;
p.CustomEndCap = cap; //循环绘制变换组中的变换
for (int i = 0; i < 1000; i++)
{
tranGroup[i] = new Point[2];
}
} private void Form1_MouseDown(object sender, MouseEventArgs e)
{
Graphics g2 = CreateGraphics(); //判断变换数
if (tranNumb >= 999)
{
pushNumb = 0;
Capture = false;
return;
} //左键按下
if (e.Button == MouseButtons.Left)
{
if (pushNumb == 0)//判断是否是折线的开始
{
if (endPoint.X != e.X || endPoint.Y != e.Y)
{
pushNumb++; startP.X = e.X;
startP.Y = e.Y;
oldP.X = e.X;
oldP.Y = e.Y; Capture = true;//捕获鼠标
} }
else if (pushNumb == 1)//如果不是一段新的折线的开始
{
ControlPaint.DrawReversibleLine(PointToScreen(startP), PointToScreen(new Point(e.X, e.Y)), clr);
ControlPaint.DrawReversibleLine(PointToScreen(startP), PointToScreen(new Point(e.X, e.Y)), clr);
//把变换存入变换组中
curP.X = e.X;
curP.Y = e.Y;
tranGroup[tranNumb][0] = startP;
tranGroup[tranNumb][1] = curP;
tranNumb++;
startP.X = e.X;
startP.Y = e.Y; //存储一段折线的最后一个点的坐标
endPoint.X = e.X;
endPoint.Y = e.Y;
}
} //右键按下
if (e.Button == MouseButtons.Right)
{
//变换数超过变换组最大限度
if (pushNumb == 0)
return; //变换数没有超过变换组最大限度
pushNumb = 0;//一段折线结束
Capture = false;//释放鼠标 //绘制最后一个变换
ControlPaint.DrawReversibleLine(PointToScreen(startP), PointToScreen(new Point(e.X, e.Y)), clr);
} //失效重画,为抗锯齿
Invalidate();
g2.Dispose();
} private void Form1_MouseMove(object sender, MouseEventArgs e)
{
Graphics g1 = CreateGraphics(); //左键按下并移动鼠标
if (pushNumb == 1)
{
if (oldP.X != e.X || oldP.Y != e.Y)
{
//在屏幕上指定的起始点和结束点内绘制具有指定背景色的可逆线
//再次绘制同一条线会逆转该方法的结果。使用该方法绘制线类似于反转屏幕的一个区域,
//不过它提供了更好的性能适用于更广泛的颜色。 ControlPaint.DrawReversibleLine(PointToScreen(startP), PointToScreen(oldP), clr);
ControlPaint.DrawReversibleLine(PointToScreen(startP), PointToScreen(new Point(e.X, e.Y)), clr);
//存储一个变换的终点,作为下一变换的起点
oldP.X = e.X;
oldP.Y = e.Y;
} }
g1.Dispose();
}
//释放资源
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
g3.Dispose();
bitmap.Dispose();
g0.Dispose();
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;//包含这个高级二维图形命名空间namespace ReverseLines
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent(); //激活双缓冲技术
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
} private Point[][] tranGroup = new Point[1000][];//变换组
private int tranNumb = 0;//变换序号
private int pushNumb = 0;//左键按下情况:0为开始画变换,1为结束
private Point curP;//存储变换时鼠标的当前点
private Point startP, oldP;//变换的起点和鼠标移动时的当前点
private Graphics g0,g3;//窗口绘图面和采用双缓冲时的临时绘图面
private Point endPoint;//存储右键按下时放弃绘制相连变换的鼠标点
private Color clr,clr1;//获取窗体背景色和反转背景色
private Pen p;//重画变换时所用的笔
private Bitmap bitmap = null;//双缓冲时用的位图 private void Form1_Paint(object sender, PaintEventArgs e)
{
g0 = e.Graphics; bitmap = new Bitmap(ClientSize.Width, ClientSize.Height);//创建临时位图
g3 = Graphics.FromImage(bitmap);//从位图创建绘图面
g3.Clear(this.BackColor);//清除背景色
g3.SmoothingMode = SmoothingMode.AntiAlias;//设置抗锯齿平滑模式 //在临时位图上重画变换,抗锯齿,带线冒
for (int i = 0; i < tranNumb; i++)
{
g3.DrawLine(p, tranGroup[i][0], tranGroup[i][1]);
} //把临时位图拷贝到窗体绘图面
g0.DrawImage(bitmap, 0, 0);
} private void Form1_Load(object sender, EventArgs e)
{
clr = this.BackColor;//获取窗体背景色
clr1 = Color.FromArgb(clr.A, 255 - clr.R, 255 - clr.G, 255 - clr.B);//反转背景色
p = new Pen(clr1, 1);//定义鼠标左键按下并移动时绘制变换所用的笔 //自定义线冒
AdjustableArrowCap cap = new AdjustableArrowCap(3, 3);
cap.WidthScale = 3;
cap.BaseCap = LineCap.Square;
cap.Height = 3;
p.CustomEndCap = cap; //循环绘制变换组中的变换
for (int i = 0; i < 1000; i++)
{
tranGroup[i] = new Point[2];
}
} private void Form1_MouseDown(object sender, MouseEventArgs e)
{
Graphics g2 = CreateGraphics(); //判断变换数
if (tranNumb >= 999)
{
pushNumb = 0;
Capture = false;
return;
} //左键按下
if (e.Button == MouseButtons.Left)
{
if (pushNumb == 0)//判断是否是折线的开始
{
if (endPoint.X != e.X || endPoint.Y != e.Y)
{
pushNumb++; startP.X = e.X;
startP.Y = e.Y;
oldP.X = e.X;
oldP.Y = e.Y; Capture = true;//捕获鼠标
} }
else if (pushNumb == 1)//如果不是一段新的折线的开始
{
ControlPaint.DrawReversibleLine(PointToScreen(startP), PointToScreen(new Point(e.X, e.Y)), clr);
ControlPaint.DrawReversibleLine(PointToScreen(startP), PointToScreen(new Point(e.X, e.Y)), clr);
//把变换存入变换组中
curP.X = e.X;
curP.Y = e.Y;
tranGroup[tranNumb][0] = startP;
tranGroup[tranNumb][1] = curP;
tranNumb++;
startP.X = e.X;
startP.Y = e.Y; //存储一段折线的最后一个点的坐标
endPoint.X = e.X;
endPoint.Y = e.Y;
}
} //右键按下
if (e.Button == MouseButtons.Right)
{
//变换数超过变换组最大限度
if (pushNumb == 0)
return; //变换数没有超过变换组最大限度
pushNumb = 0;//一段折线结束
Capture = false;//释放鼠标 //绘制最后一个变换
ControlPaint.DrawReversibleLine(PointToScreen(startP), PointToScreen(new Point(e.X, e.Y)), clr);
} //失效重画,为抗锯齿
Invalidate();
g2.Dispose();
} private void Form1_MouseMove(object sender, MouseEventArgs e)
{
Graphics g1 = CreateGraphics(); //左键按下并移动鼠标
if (pushNumb == 1)
{
if (oldP.X != e.X || oldP.Y != e.Y)
{
//在屏幕上指定的起始点和结束点内绘制具有指定背景色的可逆线
//再次绘制同一条线会逆转该方法的结果。使用该方法绘制线类似于反转屏幕的一个区域,
//不过它提供了更好的性能适用于更广泛的颜色。 ControlPaint.DrawReversibleLine(PointToScreen(startP), PointToScreen(oldP), clr);
ControlPaint.DrawReversibleLine(PointToScreen(startP), PointToScreen(new Point(e.X, e.Y)), clr);
//存储一个变换的终点,作为下一变换的起点
oldP.X = e.X;
oldP.Y = e.Y;
} }
g1.Dispose();
}
//释放资源
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
g3.Dispose();
bitmap.Dispose();
g0.Dispose();
}
}
}
p.CustomStartCap = cap; //加入绘制直线起点的箭帽
p.CustomEndCap = cap;