`

纯底层实现缓冲区算法

阅读更多
首先,画线,如图:





然后,生成缓冲区如图:


具体代码如下,完美纯底层实现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;
        }
  
    }
}
  • 大小: 8.1 KB
  • 大小: 8.4 KB
  • 大小: 17 KB
0
8
分享到:
评论
1 楼 BigBird2012 2012-07-23  
美女强人,Java、C#都通啊

相关推荐

    点和线多边形缓冲区 c#算法

    C#中实现点和线的缓冲区算法,主要涉及以下步骤: 1. 创建几何对象:首先,我们需要用System.Windows.Shapes或System.Drawing.Point等类创建点和线的几何表示。例如,点可以用Point类表示,线可用LineSegment或...

    操作系统课程设计有限缓冲区问题的实现

    ### 操作系统课程设计有限缓冲区问题的实现 #### 一、问题背景及目标 在计算机科学领域,有限缓冲区问题通常被称为生产者-消费者问题,这是一个经典的进程间通信问题,用于研究同步机制。该问题涉及到两个进程或...

    Linux内核缓冲区管理

    本文将深入探讨Linux内核缓冲区管理的原理、设计和实现,以及它对系统性能的影响。 首先,理解缓冲区(Buffer)的基本概念至关重要。在计算机系统中,缓冲区是一种临时存储区域,用于存放数据,以便在不同速度的...

    基于linux用户态可自控缓冲区管理设计与实现.pdf

    相关工作的研究主要集中在TCP/IP等底层协议栈的缓冲区优化,如滑动窗口协议和拥塞控制算法等。这些工作虽然在一定程度上改善了网络性能,但并未解决用户态下自适应、动态的缓冲区管理问题。刘青昆和王佳的研究弥补了...

    环形缓冲区(RingBuffer)源码

    通过分析和研究`RingBufferSourceCode`这个源码文件,我们可以深入理解环形缓冲区的内部实现,包括如何处理边界条件、如何进行线程安全的读写操作,以及如何优化性能等。这不仅可以提升编程技能,还有助于理解底层...

    得到缓冲区的密码的例子

    3. **源码分析**:在"源码"标签的上下文中,我们可能需要查看和理解代码实现,了解如何从缓冲区获取密码的逻辑。这可能涉及解析内存结构,查找特定数据类型或标识符,以及理解解密算法。 4. **控件**:在用户界面...

    网络攻击与防范之缓冲区溢出实验

    《网络攻击与防范之缓冲区溢出实验》 在信息技术领域,网络安全是至关重要的一环,而缓冲区溢出则是其中一种常见的攻击手段。本实验旨在深入理解缓冲区溢出的原理,通过实战演练来学习如何利用war-ftpd的缓冲区溢出...

    CSAPP缓冲区溢出实验

    《CSAPP缓冲区溢出实验》是计算机科学与编程领域中的一个重要实验,主要涉及的是《计算机系统:一种程序员的视角》(Computer Systems: A Programmer's Perspective,简称CSAPP)一书中的第五个实验,该书由Randal E....

    ha256算法的 实验纯python实现_python代码_下载

    1. **初始化消息字典**:首先,SHA-256算法会用一组特定的常数值初始化一个512位的消息字典(也称为中间哈希或工作缓冲区)。 2. **填充消息**:原始消息会被“填充”到一个特定的长度,使其长度是512位的倍数。...

    纯C语言实现的软件渲染器

    开发者可能使用了自定义的数据结构和算法来优化计算效率,例如使用向量和矩阵运算来处理几何变换,以及使用位操作来加速颜色和深度缓冲区的更新。 在游戏开发中,软件渲染器与硬件加速的GPU渲染不同,它不依赖于...

    JAVA高手MD5加密算法底层源码完美实现

    1. **初始化:** MD5算法有四个32位的中间变量A、B、C、D,以及一个128位的消息缓冲区,由64个32位的块组成。 2. **预处理:** 对输入信息进行填充,使其长度达到512的倍数,最后添加一个128位的标记,表示原始信息...

    SHA1加密算法(c语言实现).zip

    C语言是一种底层、高效且通用的编程语言,非常适合实现这样的底层算法。 SHA1全称为Secure Hash Algorithm 1,是美国国家安全局(NSA)设计的一种散列函数。它将任意长度的输入(也叫做预映射或消息)转换为固定...

    网络游戏-网络交换机中的缓冲区空间的有效使用.zip

    网络交换机中的缓冲区空间管理是确保数据包传输不丢失、减少拥塞的关键环节。本资料"网络游戏-网络交换机中的缓冲区空间的有效使用.pdf"将深入探讨如何优化这一环节,以提升网络游戏的性能和玩家体验。 缓冲区在...

    Java中缓冲区读者与缓冲区写者.pdf

    当使用BufferedReader时,数据会被一次性读取到缓冲区中,而不是每次读取一个字符,这样可以减少对底层物理设备的访问次数,从而提升性能。例如,我们通常会用以下方式创建一个BufferedReader对象,从键盘读取输入:...

    Hash-MD5算法(C语言实现,附带Hash验证工具)

    1. 初始化:MD5算法包含四个32位的中间变量A、B、C和D,以及一个128位的消息缓冲区。初始化这些变量为预设值,如0x67452301、0xefcdab89、0x98badcfe和0x10325476。 2. 扩展:将输入的数据块(512位)进行一系列...

    I/O缓冲池演示程序

    2. 缓冲区管理:实现缓冲区的分配、回收和替换策略,确保高效地利用内存资源。 3. I/O操作封装:使用C++的流机制或Windows API,将底层I/O操作包装成用户友好的接口。 4. 请求调度:根据I/O请求的优先级和缓冲区的...

    C经典数据结构算法及底层编程

    4. 队列:先进先出(FIFO)结构,适用于任务调度和缓冲区管理。 5. 树:如二叉树、平衡树(AVL、红黑树),用于搜索、排序和索引。 6. 图:用于表示网络结构,支持路径查找和最短路径算法。 7. 哈希表:提供快速查找...

    waveInXXX 底层WINDOWS 语音 API实现录音与播放

    在Windows操作系统中,声音处理是通过Windows Audio Subsystem (WAS) 实现的,它提供了一套底层API供开发者使用,这些API被称为Waveform Audio API(简称Wave API)。本篇文章将深入探讨如何利用`waveInXXX`系列函数...

Global site tag (gtag.js) - Google Analytics