C# WinFrom 蜂巢类

 

 winform

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            honeycombBuilder.Space = new Point(3, 3);
            //honeycombBuilder.Offset = new Point(27, 27);


            // Create the ToolTip and associate with the Form container.
            

            // Set up the delays for the ToolTip.
            toolTip1.AutoPopDelay = 500000;
            toolTip1.InitialDelay = 0;
            toolTip1.ReshowDelay = 0;
            // Force the ToolTip text to be displayed whether or not the form is active.
            toolTip1.ShowAlways = true;

            // Set up the ToolTip text for the Button and Checkbox.
            this.BackColor = Color.FromArgb(255, 28, 62, 146);

        }
        ToolTip toolTip1 = new ToolTip();
        HoneycombBuilder honeycombBuilder = new HoneycombBuilder(26);

        private void button1_Click(object sender, EventArgs e)
        {

            using (var g = this.CreateGraphics())
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

                for (int x = 1; x < 8; x++)
                {
                    for (int y = 1; y < 20; y++)
                    {

                        using (var b = new SolidBrush(Color.FromArgb(255,21,51,136)))
                        {
                            using (var p = new Pen(b, 2))
                            {
                                var realpoint = honeycombBuilder.CellToPoint(x, y);
                                Point[] lppoint = honeycombBuilder.GetCellPoints(realpoint);
                                using (var fp = new Pen(Color.Black))
                                {
                                    g.DrawLines(fp, lppoint);
                                }
                                g.FillPolygon(b, lppoint);
                                using (var fb = new SolidBrush(Color.White))
                                {
                                    var loca = g.MeasureString($"{x},{y}", this.Font);
                                    realpoint.X = (Int32)(realpoint.X - loca.Width / 2f);
                                    realpoint.Y = (Int32)(realpoint.Y - loca.Height / 2f);
                                    g.DrawString($"{x},{y}", this.Font, fb, realpoint);
                                    
                                }

                            }
                        }
                    }
                }
            }
        }

        Point lastcell = new Point(0, 0);


        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {

        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            //通过坐标找到格子
            var cell = honeycombBuilder.PointToCell(e.Location);
            //通过坐标找到当前坐标所在格子中心点
            var realpoint = honeycombBuilder.GetCellCenter(e.Location);
            if (cell.X <= 0 || cell.Y <= 0 || (cell.X == lastcell.X && cell.Y == lastcell.Y))
            {
                return;
            }
            toolTip1.SetToolTip(this, $"{cell.X},{cell.Y}");
            using (var g = this.CreateGraphics())
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                using (var b = new SolidBrush(Color.FromArgb(255, 80, 80, 200)))
                {
                    Point[] lppoint = honeycombBuilder.GetCellPoints(realpoint);

                    using (var fp = new Pen(Color.Black))
                    {
                        g.DrawLines(fp, lppoint);
                    }

                    g.FillPolygon(b, lppoint);
                    using (var fb = new SolidBrush(Color.White))
                    {
                        var loca = g.MeasureString($"{cell.X},{cell.Y}", this.Font);
                        realpoint.X = (Int32)(realpoint.X - loca.Width / 2);
                        realpoint.Y = (Int32)(realpoint.Y - loca.Height / 2);
                        g.DrawString($"{cell.X},{cell.Y}", this.Font, fb, realpoint);
                    }
                }

                if (lastcell.X != 0 && lastcell.Y != 0)
                {
                    realpoint = honeycombBuilder.CellToPoint(lastcell);
                    using (var b = new SolidBrush(Color.FromArgb(255, 21, 51, 136)))
                    {
                        Point[] lppoint = honeycombBuilder.GetCellPoints(realpoint);
                        g.FillPolygon(b, lppoint);
                        using (var fb = new SolidBrush(Color.White))
                        {
                            var loca = g.MeasureString($"{lastcell.X},{lastcell.Y}", this.Font);
                            realpoint.X = (Int32)(realpoint.X - loca.Width / 2);
                            realpoint.Y = (Int32)(realpoint.Y - loca.Height / 2);
                            g.DrawString($"{lastcell.X},{lastcell.Y}", this.Font, fb, realpoint);
                        }
                    }
                }
            }

            lastcell = cell;







        }
    }
}

using System;
using System.Drawing;

namespace WindowsFormsApp1
{
    public class HoneycombBuilder
    {
        public HoneycombBuilder(Int32 dwsidelength = 40)
        {
            SideLength = dwsidelength;
            //二分之根号3 边长的平方,如果距离比它还小,就必然捕获
            g_MinDistance2 = dwsidelength * dwsidelength * 0.75;
        }

        private Double g_MinDistance2 { get; set; }

        /// <summary>
        /// 六边形的边长
        /// </summary>
        public Double SideLength { get; private set; }

        /// <summary>
        /// 每个格子的宽度
        /// </summary>
        public Double g_unitx
        {
            get
            {
                var cx = Math.Ceiling(SideLength * 1.8020508);
                cx += ((Int32)cx & 1);
                return cx;
            }
        }

        /// <summary>
        /// 格子之间的空间
        /// </summary>
        public Point Space { get; set; }

        /// <summary>
        /// 起始坐标偏移
        /// </summary>
        public Point Offset { get; set; }

        /// <summary>
        /// 每个格子的宽度
        /// sqr(3)/2=0.8660254
        /// </summary>
        public Double g_unity
        {
            get
            {
                var cy = Math.Ceiling(SideLength * 1.5f);
                cy += ((Int32)cy & 1);
                return cy;
            }
        }
        /// <summary>
        /// 坐标转格子
        /// </summary>
        /// <param name="lppoint"></param>
        /// <returns>格子的编号</returns>
        public Point PointToCell(Point lppoint)
        {
            return this.PointToCell(lppoint.X,lppoint.Y);
        }

        /// <summary>
        /// 坐标转格子
        /// </summary>
        /// <param name="xPos"></param>
        /// <param name="yPos"></param> 
        /// <returns>格子的编号</returns>
        public Point PointToCell(int xPos, int yPos)
        {
            var canter = this.GetCellCenter(xPos, yPos);
            var Y = canter.Y / (g_unity + Space.Y);
            var X = canter.X / (g_unitx + Space.X);
            return new Point((Int32)X, (Int32)Y);
        }

        /// <summary>
        /// 网格坐标转2d坐标中心点
        /// </summary>
        /// <param name="cell_x"></param>
        /// <param name="cell_y"></param>
        /// <returns></returns>
        public Point CellToPoint(Point cell)
        {
            return CellToPoint(cell.X, cell.Y);
        }
        /// <summary>
        /// 网格坐标转2d坐标中心点
        /// </summary>
        /// <param name="cell_x"></param>
        /// <param name="cell_y"></param>
        /// <returns></returns>
        public Point CellToPoint(int cell_x, int cell_y)
        {
            Point p = new Point();
            var offsetx = Math.Ceiling((g_unitx + Space.X) * (cell_y & 1) * 0.5f);
            p.X = (Int32)(cell_x * (g_unitx + Space.X) + offsetx);
            p.Y = (Int32)(cell_y * (g_unity + Space.Y));
            return p;
        }

        /// <summary>
        /// 求取两个点的距离平方
        /// </summary>
        /// <param name="x1"></param>
        /// <param name="y1"></param>
        /// <param name="x2"></param>
        /// <param name="y2"></param>
        /// <returns></returns>
        private int distance2(int x1, int y1, int x2, int y2)
        {
            return ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
        }

        /// <summary>
        /// 通过某一点坐标定位到坐标所在格子中心点
        /// </summary>
        /// <param name="lppoint"></param>
        /// <returns>返回被捕获六边形的中心坐标</returns>
        public Point GetCellCenter(Point lppoint)
        {
            return this.GetCellCenter(lppoint.X, lppoint.Y);
        }

        /// <summary>
        /// 通过某一点坐标定位到坐标所在格子中心点
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns>返回被捕获六边形的中心坐标</returns>
        public Point GetCellCenter(int x, int y)
        {
            //位于矩形网格边线上的三个CELL中心点
            Point[] points = new Point[3];
            //当前距离
            int dist;
            int mindist = (int)(g_MinDistance2 * 100); //一个非常大的值
            int i, index = 0;
            //index:被捕获的索引
            //计算出鼠标点位于哪一个矩形网格中
            int cx = (int)(x / (g_unitx + +Space.X));
            //int cy = (int)(y / g_unity);
            int cy = (Int32)(y / (g_unity + Space.Y));
            points[0].X = (int)((g_unitx + +Space.X) * cx);
            points[1].X = (int)((g_unitx + +Space.X) * (cx + 0.5));
            points[2].X = (int)((g_unitx + +Space.X) * (cx + 1));
            //根据cy是否是偶数,决定三个点的纵坐标
            if (cy % 2 == 0)
            {
                //偶数时,三个点组成倒立三角
                points[0].Y = points[2].Y = (int)((g_unity + Space.Y) * cy);
                points[1].Y = (int)((g_unity + Space.Y) * (cy + 1));
            }
            else
            {
                //奇数时,三个点组成正立三角
                points[0].Y = points[2].Y = (int)((g_unity + Space.Y) * (cy + 1));
                points[1].Y = (int)((g_unity + Space.Y) * cy);
            }

            //现在找出鼠标距离哪一个点最近
            for (i = 0; i < 3; i++)
            {
                //求出距离的平方
                dist = distance2(x, y, points[i].X, points[i].Y);

                //如果已经肯定被捕获
                if (dist < g_MinDistance2)
                {
                    index = i;
                    break;
                }

                //更新最小距离值和索引
                if (dist < mindist)
                {
                    mindist = dist;
                    index = i;
                }
            }

            //现在index 就是被捕获的结果
            return new Point(points[index].X, points[index].Y);
        }

        /// <summary>
        /// 输入格子中心坐标 返回格子的六个角
        /// </summary>
        /// <param name="center"></param>
        /// <returns></returns>
        public Point[] GetCellPoints(Point center)
        {
            return GetCellPoints(center.X, center.Y);
        }

        /// <summary>
        /// 输入格子中心坐标 返回格子的六个角
        /// </summary>
        /// <param name="centerx"></param>
        /// <param name="centery"></param>
        /// <param name="a"></param>
        /// <param name="lpPoints"></param>
        public Point[] GetCellPoints(int centerx, int centery)
        {
            var lpPoints = new Point[7];
            var a = g_unity / 1.5;// (Int32)this.SideLength;
            if (lpPoints == null || lpPoints.Length < 6) return null;
            //平
            var offsetx = Math.Ceiling(g_unitx * 0.5f);
            lpPoints[0].X = centerx;
            lpPoints[0].Y = (Int32)(centery - a);
            lpPoints[1].X = centerx + (int)offsetx;
            lpPoints[1].Y = (Int32)(centery - a / 2f);
            lpPoints[2].X = lpPoints[1].X;
            lpPoints[2].Y = (Int32)(centery + a / 2f);
            lpPoints[3].X = centerx;
            lpPoints[3].Y = (Int32)(centery + a);
            lpPoints[4].X = centerx - (int)offsetx;
            lpPoints[4].Y = (Int32)(centery + a / 2f);
            lpPoints[5].X = lpPoints[4].X;
            lpPoints[5].Y = (Int32)(centery - a / 2f);
            lpPoints[6].X = lpPoints[0].X;
            lpPoints[6].Y = lpPoints[0].Y;
            return lpPoints;
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值