`

纯底层实现缓冲区算法

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





然后,生成缓冲区如图:


具体代码如下,完美纯底层实现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#编写代码,可以使用在目前流行的瓦片地图API中。

    《深入理解计算机系统》3.38题解——缓冲区溢出攻击实例文档

    本文主要以《深入理解计算机》3.38题为例,详细地介绍了该题目的解题过程,主要目的是利用程序缓冲区溢出以达到改变程序的输出(攻击程序)。 要解决这类题目,需要对过程调用的栈帧变化、指令的作用有较深入的了解...

    FreeBSD操作系统设计与实现

    6.6.3 缓冲区管理的实现 6.7 可叠加的文件系统 6.7.1 简单的文件系统层 6.7.2 联合安装的文件系统 6.7.3 其他文件系统 6.8 复习题 6.9 参考文献 第7章 设备 7.1 设备概述 7.1.1 PC的I/O体系结构 7.1.2 FreeBSD海量...

    千万字肝翻Linux内核源码,对底层原理深耕深分析,从入门到入狱

    动态、缺页中断、Kfifo环形缓冲区、开发工具ARM-LInux-gcc安装、网络协议栈、构建嵌入式Lnux系 统、内存性能优化、核心知识CPU、内核编译、UDP收包率、反向映射机制、MMu-gather操作、进程 描述符、虚拟内存机制、...

    网络渗透技术

    2.4.1 熟悉PowerPC体系及其精简指令集计算 2.4.2 AIX PowerPC堆栈结构 2.4.3 学习如何攻击AIX PowerPC的溢出程序 2.5 Solaris SPARC平台缓冲区溢出利用技术 2.5.1 SPARC体系结构 2.5.2 Solaris SPARC堆栈结构及函数...

    精通并发与netty视频教程(2018)视频教程

    80_Netty复合缓冲区详解与3种缓冲区适用场景分析 81_Netty引用计数的实现机制与自旋锁的使用技巧 82_Netty引用计数原子更新揭秘与AtomicIntegerFieldUpdater深度剖析 83_AtomicIntegerFieldUpdater实例演练与...

    精通并发与 netty 视频教程(2018)视频教程

    76_Netty项目开发过程中常见且重要事项分析 77_Java NIO Buffer总结回顾与难点拓展 78_Netty数据容器ByteBuf底层数据结构深度剖析 79_Netty的ByteBuf底层实现大揭秘 80_Netty复合缓冲区详解与3种缓冲区适用场景分析 ...

    精通并发与netty 无加密视频

    第80讲:Netty复合缓冲区详解与3种缓冲区适用场景分析 第81讲:Netty引用计数的实现机制与自旋锁的使用技巧 第82讲:Netty引用计数原子更新揭秘与AtomicIntegerFieldUpdater深度剖析 第83讲:...

    Java 基础核心总结 +经典算法大全.rar

    缓冲区(Buffer)通道(Channel) 示例:文件拷贝案例 BIO 和 NIO 拷贝文件的区别操作系统的零拷贝 选择器(Selectors) 选择键(SelectionKey) 示例:简易的客户端服务器通信 集合 集合框架总览 -、Iterator Iterable ...

    基于stm32的12864oled图形库

    oled库说明: 该库只是一个绘图图形库,只能适用于stm32系列的12864oled屏,驱动芯片为ssd1306 ...oled_color.c:颜色控制 oled_buffer.c:屏幕缓冲区和临时缓冲区 oled_font.c:字体 oled_bmp.c:bmp取模图形存放位置

    HL340-CH341驱动程序及调试程序

    线程调度能力和USB实时性都比WINDOWS 2000/XP差,如果串口接收缓冲区较小, 那么在通讯波特率较高时,接收大量数据会导致串口缓冲区溢出而丢弃数据。 由于底层的USB是将多个字节组成数据包后安插到各个1mS帧中...

    湍流边界层多尺度相干结构的子波自相关辨识 (2005年)

    结果显示,相干结构在时空中呈多尺度分布,在对数区集中在较大尺度,在缓冲区扩展到较小尺度,越靠近黏性底层,拟序运动越明显,并向更小尺度发展;广泛存在的相关性很弱的小尺度涡成为数量巨大、含能很少的背景湍流...

    有趣的二进制:软件安全与逆向分析

    有趣的二进制:软件安全与逆向分析 ...本书涵盖的技术包括:汇编与反汇编、调试与反调试、缓冲区溢出攻击与底层安全、钩子与注入、Metasploit 等安全工具。本书适合对计算机原理、底层或计算机安全感兴趣的读者阅读。

    3G手机等嵌入式技术终端实现监控,视频会议,即时通讯的平台开发

    流畅的视频效果:佰锐科技针对手机平台特别优化了H.264视频编解码算法,提高了算法的效率,降低了因算法的复杂度而引入的延迟,同时特别针对3G网络进行了优化,采用环形缓冲区、向前纠错等特定的技术手段,加强了...

    基于密度的异常值检测算法:DDOutlier 的 MATLAB 版本-matlab开发

    ## 故事 一个名为 DDOutlier [4] 的 R 包包含许多基于密度的异常值检测算法。 我在寻找复杂的异常值检测方法时偶然发现了这个包。... 同时,DDOutlier 包中的缓冲区防止频繁搜索数据库。 它是自我维护的。 用户在操

    《VC++开发GIS系统》PDF电子书

    结合具体代码开发实现了矢量图形系统、数据库管理系统、矢量图形系统和数据库管理系统之间的连接、空间信息查询、图形几何关系计算、区域重叠分析、缓冲区分析、网络分析等功能,实现了一个基本gis。 本书是作者2000...

    API之网络函数---整理网络函数及功能

    GetFileVersionInfoSize 针对包含了版本资源的一个文件,判断容纳文件版本信息需要一个多大的缓冲区 GetFullPathName 获取指定文件的完整路径名 GetLogicalDrives 判断系统中存在哪些逻辑驱动器字母 ...

Global site tag (gtag.js) - Google Analytics