纯底层实现缓冲区算法

首先,画线,如图:


[img]http://dl.iteye.com/upload/attachment/0071/2048/5f8823de-0961-3138-9109-37cd5057ff59.jpg[/img]

然后,生成缓冲区如图:

[img]http://dl.iteye.com/upload/attachment/0071/2038/e9c3074d-6ae8-349a-ad96-94f8eedea481.png[/img]
具体代码如下,完美纯底层实现arcgis的buffer功能


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;

namespace LineBuffer
{

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public Point Origin = new Point(0, 0);
public Point[] points = new Point[4];
public int Num = 0;
public Graphics g;
public Pen pen;
public double buffer=0;//缓冲区值

public bool m_bColor=false;
// PointF
private void Form1_Load(object sender, EventArgs e)
{
this.StartPosition = FormStartPosition.CenterScreen;
this.BackColor = Color.White; //设置窗体背景颜色
}

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (Num < 4)
{
Origin.X = e.X;
Origin.Y = e.Y;
points[Num] = Origin;
if (Num % 2 == 1)
{
g = this.CreateGraphics(); //创建Graphics对象实例
Pen p = new Pen(Color.Black, 1); //设置画笔颜色和宽度
g.DrawLine(p, points[Num - 1], points[Num]); //绘制直线
}

Num++;
}
}

private void button2_Click(object sender, EventArgs e)
{
g = this.CreateGraphics();
g.Clear(Color.White); //清空窗体背景
Num = 0;
}

private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text.Trim() == "" || textBox1.Text == null)
{
MessageBox.Show("请输入缓冲变量值!");
}
else if (Num == 4)
{
buffer = Convert.ToDouble(textBox1.Text);
DrawBuffer();
/*//单轨迹缓冲区
//处理绘制的点
StringBuilder strCoords = new StringBuilder();

for (int i = 0; i < 2; i++)
{
if (strCoords.Length > 0) strCoords.Append(";");
strCoords.Append(points[i].X.ToString() + "," + points[i].Y.ToString());
}

string strpoints=LineBuffer.PolylineBuffer.GetBufferEdgeCoords(strCoords.ToString(), buffer);

//if (strpoints.Trim().Length < 1) return "";
string[] strCoords1 = strpoints.Split(new char[] { ';' });


List<PointF> coords = new List<PointF>();

foreach (string coord in strCoords1)
{
string[] arcoord = coord.Split(new char[] { ',' });
PointF pf = new PointF();
pf.X =Convert.ToInt32( Convert.ToDouble(arcoord[0]));
pf.Y = Convert.ToInt32(Convert.ToDouble(arcoord[1]));
coords.Add(pf);
}



g = this.CreateGraphics(); //创建Graphics对象实例
Pen p = new Pen(Color.Red, 1); //设置画笔颜色和宽度


for(int i=1;i<coords.Count;i++)
{
g.DrawLine(p, coords[i-1],coords[i]);

}
*/

// g.DrawLine(p, points[Num - 1], points[Num]); //绘制直线


}
}

//获取扫描边界
public Point GetExtent()
{
Point extent=new Point(0,0);

for (int i = 0; i < points.Length; i++)
{
extent.X = Math.Max(points[i].X, extent.X);
extent.Y = Math.Max(points[i].Y, extent.Y);
}
extent.X +=(int)buffer + 1;
extent.Y += (int)buffer + 1;
return extent;
}

//像素扫描法画缓冲
public void DrawBuffer()
{
Point extent = GetExtent();

Point cPointTmp=new Point();
g = this.CreateGraphics();
double fLength1 =buffer + 0.5;
double fLength2 =buffer - 0.5;

double fDistanceToLine1;
double fDistanceToLine2;
if (false == m_bColor)
{
for (int x = 0; x <= extent.X; x++)
{
for (int y = 0; y <= extent.Y; y++)
{
cPointTmp.X = x;
cPointTmp.Y = y;
fDistanceToLine1 = DistanceLine(points[0], points[1], cPointTmp);
fDistanceToLine2 = DistanceLine(points[2], points[3], cPointTmp);
if (fLength1 >= fDistanceToLine1 && fLength2 < fDistanceToLine1)
{
if (fLength2 < DistanceLine(points[2], points[3], cPointTmp))
{
Bitmap bm = new Bitmap(1, 1); //这里调整点的大小
bm.SetPixel(0,0, Color.Red); //设置点的颜色
g.DrawImageUnscaled(bm, cPointTmp.X, cPointTmp.Y); //具体坐标
}

}
else if (fLength1 >= fDistanceToLine2 && fLength2 < fDistanceToLine2)
{
if (fLength2 < DistanceLine(points[0], points[1], cPointTmp))
{
Bitmap bm = new Bitmap(1, 1); //这里调整点的大小
bm.SetPixel(0, 0, Color.Red); //设置点的颜色
g.DrawImageUnscaled(bm, cPointTmp.X, cPointTmp.Y); //具体坐标
}
}
else
{
}
}
}
}
else
{
for (int x = 0; x <= extent.X; x++)
{
for (int y = 0; y <= extent.Y; y++)
{
cPointTmp.X = x;
cPointTmp.Y = y;
fDistanceToLine1 = DistanceLine(points[0], points[1], cPointTmp);
fDistanceToLine2 = DistanceLine(points[2], points[3], cPointTmp);
if (fLength1 >= fDistanceToLine1 && fLength2 < fDistanceToLine1)
{
if (fLength2 < DistanceLine(points[2], points[3], cPointTmp))
{
Bitmap bm = new Bitmap(1, 1); //这里调整点的大小
bm.SetPixel(0, 0, Color.Red); //设置点的颜色
g.DrawImageUnscaled(bm, cPointTmp.X, cPointTmp.Y); //具体坐标
}
//else if(fLength2 >= DistanceLine(szPoint[2],szPoint[3],cPointTmp))
// SetPixel(dc,cPointTmp.x,cPointTmp.y,RGB(255,0,255));
}
else if (fLength1 >= fDistanceToLine2 && fLength2 < fDistanceToLine2)
{
if (fLength2 < DistanceLine(points[0], points[1], cPointTmp))
{
Bitmap bm = new Bitmap(1, 1); //这里调整点的大小
bm.SetPixel(0, 0, Color.Red); //设置点的颜色
g.DrawImageUnscaled(bm, cPointTmp.X, cPointTmp.Y); //具体坐标
}
//else if(fLength2 >= DistanceLine(szPoint[0],szPoint[1],cPointTmp))
// SetPixel(dc,cPointTmp.x,cPointTmp.y,RGB(255,0,255));
}
else
{
}
if (0.5 > fDistanceToLine1 || 0.5 > fDistanceToLine2)
{

Bitmap bm = new Bitmap(1, 1); //这里调整点的大小
bm.SetPixel(0, 0, Color.Black); //设置点的颜色
g.DrawImageUnscaled(bm, cPointTmp.X, cPointTmp.Y); //具体坐标

continue;
}
if (fLength2 >= fDistanceToLine1 || fLength2 >= fDistanceToLine2)
{

Bitmap bm = new Bitmap(1, 1); //这里调整点的大小
bm.SetPixel(0, 0, Color.Yellow); //设置点的颜色
g.DrawImageUnscaled(bm, cPointTmp.X, cPointTmp.Y); //具体坐标

}
}
}
}


}


// 返回两点之间的距离
public double Distance(Point p1, Point p2)
{
double fDistance = Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y));
return fDistance;
}


//返回扫描点到指定线段的距离
public double DistanceLine(Point p1, Point p2, Point p)
{

double f = (p2.X-p1.X) * (p.X-p1.X) + (p2.Y-p1.Y) * (p.Y-p1.Y);

//p到直线p1p2的投影点不在线段p1p2上,而且离p1点最近
if (f < 0) return Distance(p1,p);

double d = (p2.X - p1.X) * (p2.X - p1.X) + (p2.Y - p1.Y) * (p2.Y - p1.Y);

//p到直线p1p2的投影点不在线段p1p2上,而且离p2点最近

if (f > d) return Distance(p2, p);

// p在p1p2线段上的投影点在线段p1p2上

f = f / d;

double fx = p1.X + f * (p2.X- p1.X);
double fy = p1.Y + f * (p2.Y -p1.Y);
double fDistance = Math.Sqrt((p.X - fx) * (p.X - fx) + (p.Y - fy) * (p.Y - fy));
return fDistance;
}

}
}