“贝赛尔曲线”是由法国数学家Pierre Bézier所发明,由此为计算机矢量图形学奠定了基础。它的主要意义在于无论是直线或曲线都能在数学上予以描述。贝塞尔曲线就是这样的一条曲线,它是依据四个位置任意的点坐标绘制出的一条光滑曲线。
线性公式
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
namespace TestDemo
{
unsafe class Bezier
{
Point PointCubicBezier(Point[] cp, float t)
{
float ax, bx, cx, ay, by, cy, tS, tC;
cx = 1.0f * (cp[1].X - cp[0].X);
bx = 3.0f * (cp[2].X - cp[1].X) - cx;
ax = cp[3].X - cp[0].X - cx - bx;
cy = 1.0f * (cp[1].Y - cp[0].Y);
by = 3.0f * (cp[2].Y - cp[1].Y) - cy;
ay = cp[3].X - cp[0].Y - cx - by;
tS = t * t;
tC = tS * t;
int x = (int)((ax * tC) + (bx * tS) + (cx * t) + cp[0].X);
int y = (int)((ay * tC) + (by * tS) + (cy * t) + cp[0].Y);
return new Point(x, y);
}
public Bitmap DrawBezier(Bitmap src, Point[] cp)
{
Bitmap a = new Bitmap(src);
int w = a.Width;
int h = a.Height;
BitmapData srcData = a.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte* p = (byte*)srcData.Scan0;
float k = 0;
k = 1.0f / (w - 1);
Point temp;
for (int i = 0; i < w; i++)
{
temp = PointCubicBezier(cp, (float)i * k);
p[temp.X * 3 + temp.Y * srcData.Stride] = 0;
p[temp.X * 3 + 1 + temp.Y * srcData.Stride] = 0;
p[temp.X * 3 + 2 + temp.Y * srcData.Stride] = 0;
}
a.UnlockBits(srcData);
return a;
}
}
}
2,主界面代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
namespace TestDemo
{
unsafe public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
string startupPath = System.Windows.Forms.Application.StartupPath;
curBitmap = new Bitmap(startupPath + @"\mask.png");
//初始化
pa = new Point(button1.Location.X - pictureBox1.Location.X + 13, button1.Location.Y - pictureBox1.Location.Y + 11);
pb = new Point(button2.Location.X - pictureBox1.Location.X + 13, button2.Location.Y - pictureBox1.Location.Y + 11);
pc = new Point(button3.Location.X - pictureBox1.Location.X + 13, button3.Location.Y - pictureBox1.Location.Y + 11);
pd = new Point(button4.Location.X - pictureBox1.Location.X + 13, button4.Location.Y - pictureBox1.Location.Y + 11);
pictureBox1.Image = (Image)bezier.DrawBezier(curBitmap, new Point[] { pa, pb, pc, pd });
}
#region 变量声明
//当前图像变量
private Bitmap curBitmap = null;
private bool pointMoveStart = false;
private Point movePoint;
private Point pa;
private Point pb;
private Point pc;
private Point pd;
private Bezier bezier = new Bezier();
#endregion
#region Response
#endregion
#region MouseClick
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (pictureBox1.Image != null)
{
label1.Text = "X:" + e.X;
label2.Text = "Y:" + e.Y;
}
}
private void button1_MouseDown(object sender, MouseEventArgs e)
{
pointMoveStart = true;
if (e.Button == MouseButtons.Left)
movePoint = e.Location;
}
private void button1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && pointMoveStart)
{
button1.Location = new Point(button1.Location.X + e.X - movePoint.X, button1.Location.Y + e.Y - movePoint.Y);
}
}
private void button1_MouseUp(object sender, MouseEventArgs e)
{
pointMoveStart = false;
pa = new Point(button1.Location.X - pictureBox1.Location.X + 13, button1.Location.Y - pictureBox1.Location.Y + 11);
pb = new Point(button2.Location.X - pictureBox1.Location.X + 13, button2.Location.Y - pictureBox1.Location.Y + 11);
pc = new Point(button3.Location.X - pictureBox1.Location.X + 13, button3.Location.Y - pictureBox1.Location.Y + 11);
pd = new Point(button4.Location.X - pictureBox1.Location.X + 13, button4.Location.Y - pictureBox1.Location.Y + 11);
pictureBox1.Image = (Image)bezier.DrawBezier(curBitmap, new Point[] {pa, pb, pc, pd });
}
private void button2_MouseDown(object sender, MouseEventArgs e)
{
pointMoveStart = true;
if (e.Button == MouseButtons.Left)
movePoint = e.Location;
}
private void button2_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && pointMoveStart)
{
button2.Location = new Point(button2.Location.X + e.X - movePoint.X, button2.Location.Y + e.Y - movePoint.Y);
}
}
private void button2_MouseUp(object sender, MouseEventArgs e)
{
pointMoveStart = false;
pa = new Point(button1.Location.X - pictureBox1.Location.X + 13, button1.Location.Y - pictureBox1.Location.Y + 11);
pb = new Point(button2.Location.X - pictureBox1.Location.X + 13, button2.Location.Y - pictureBox1.Location.Y + 11);
pc = new Point(button3.Location.X - pictureBox1.Location.X + 13, button3.Location.Y - pictureBox1.Location.Y + 11);
pd = new Point(button4.Location.X - pictureBox1.Location.X + 13, button4.Location.Y - pictureBox1.Location.Y + 11);
pictureBox1.Image = (Image)bezier.DrawBezier(curBitmap, new Point[] { pa, pb, pc, pd });
}
private void button3_MouseDown(object sender, MouseEventArgs e)
{
pointMoveStart = true;
if (e.Button == MouseButtons.Left)
movePoint = e.Location;
}
private void button3_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && pointMoveStart)
{
button3.Location = new Point(button3.Location.X + e.X - movePoint.X, button3.Location.Y + e.Y - movePoint.Y);
}
}
private void button3_MouseUp(object sender, MouseEventArgs e)
{
pointMoveStart = false;
pa = new Point(button1.Location.X - pictureBox1.Location.X + 13, button1.Location.Y - pictureBox1.Location.Y + 11);
pb = new Point(button2.Location.X - pictureBox1.Location.X + 13, button2.Location.Y - pictureBox1.Location.Y + 11);
pc = new Point(button3.Location.X - pictureBox1.Location.X + 13, button3.Location.Y - pictureBox1.Location.Y + 11);
pd = new Point(button4.Location.X - pictureBox1.Location.X + 13, button4.Location.Y - pictureBox1.Location.Y + 11);
pictureBox1.Image = (Image)bezier.DrawBezier(curBitmap, new Point[] { pa, pb, pc, pd });
}
private void button4_MouseDown(object sender, MouseEventArgs e)
{
pointMoveStart = true;
if (e.Button == MouseButtons.Left)
movePoint = e.Location;
}
private void button4_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && pointMoveStart)
{
button4.Location = new Point(button4.Location.X + e.X - movePoint.X, button4.Location.Y + e.Y - movePoint.Y);
}
}
private void button4_MouseUp(object sender, MouseEventArgs e)
{
pointMoveStart = false;
pa = new Point(button1.Location.X - pictureBox1.Location.X + 13, button1.Location.Y - pictureBox1.Location.Y + 11);
pb = new Point(button2.Location.X - pictureBox1.Location.X + 13, button2.Location.Y - pictureBox1.Location.Y + 11);
pc = new Point(button3.Location.X - pictureBox1.Location.X + 13, button3.Location.Y - pictureBox1.Location.Y + 11);
pd = new Point(button4.Location.X - pictureBox1.Location.X + 13, button4.Location.Y - pictureBox1.Location.Y + 11);
pictureBox1.Image = (Image)bezier.DrawBezier(curBitmap, new Point[] { pa, pb, pc, pd });
}
#endregion
}
}
结果图如下: