六边形算法:

  我把六边形铺满的分布图进行了切分,切分为矩形,每个矩形中有一个六边形、4个三角形、两个小长方形,依次计算。边界判断上,采用主流的MP>MN的方式(M为上边界对称点,N为与六边形的交点,p为要判断的点,如下图)。

实际效果(双色对比):

拾取效果:

代码:

 /// <summary>
/// 根据参数获得六边形索引
/// </summary>
/// <param name="width">页面宽度</param>
/// <param name="height">页面长度</param>
/// <param name="r">六边形边长</param>
/// <param name="thickness">六边形上下拓扑半间距</param>
/// <param name="flat">扁平化程度(由于计算过程中,thickness在侧向拓扑中作用减小,故增加了这个系数)</param>
/// <param name="x">横坐标</param>
/// <param name="y">纵坐标</param>
/// <param name="transparent">透明度设置,一般位置为正常值;如果是六边形边界位置的过渡色,减半</param>
/// <returns></returns>
public static int[] GetHexGridIndex(int width, int height, int r, int thickness, int flat, int x, int y, ref byte transparent)
{
//中心点索引(长方形中的六边形的索引)
int indexX = (x / ) / r * ;
int indexY = (int)((int)(y / Math.Sqrt()) / r + indexX / ); //中心点坐标
int centerX = r + (int)(1.5 * r * indexX);
int centerY = (int)(Math.Sqrt() * 0.5 * r * ( + * indexY - indexX)); //位于六边外框之外
if (x > (centerX + r))
{
if (y > centerY + thickness)//右下
{
indexX++;
indexY++;
}
else if (y < centerY - thickness)//右上
{
indexX++;
}
else//中间部分以及外延部分
{
indexX = -;
indexY = -;
}
}
else//六边外框之内
{
if (x > centerX + r / )//右半区
{
if (y > centerY)//右下
{
var M = Math.Sqrt() / * r + centerY;//上边界点
var N = (centerX + r - x) * Math.Sqrt() + centerY;//六边形边界点
var MP = (int)(M - y);
var MN = (int)(M - N);
if (MP > (MN + thickness * flat))//六边形内部
{
//索引不变
}
else if (MP < (MN - thickness * flat))//六边形外部
{
indexX++;
indexY++;
}
else//交界区
{
if (MP == MN + thickness * flat)//紧靠内部
{
transparent = (byte)(transparent / );
////去除右侧尖尖
if (x == centerX + r - thickness)
{
indexX = -;
indexY = -;
}
}
else if (MP == MN - thickness * flat)//紧靠外部
{
indexX++;
indexY++;
transparent = (byte)(transparent / );
}
else//中间区
{
indexX = -;
indexY = -;
}
}
}
else//右上
{
var M = centerY - Math.Sqrt() / * r;
var N = centerY - (centerX + r - x) * Math.Sqrt();
var MP = (int)(y - M);
var MN = (int)(N - M);
if (MP > (MN + thickness * flat))//内部
{
////索引不变,但是要去除右侧尖尖
if (x == centerX + r - thickness)
{
indexX = -;
indexY = -;
}
}
else if (MP < (MN - thickness * flat))//外部,索引单变
{
indexX++;
}
else
{
if (MP == MN + thickness * flat)//里侧
{
transparent = (byte)(transparent / );
if (x == centerX + r - thickness - )////去除右侧尖尖
{
indexX = -;
indexY = -;
}
}
else if (MP == MN - thickness * flat)//外侧
{
indexX++;
transparent = (byte)(transparent / );
}
else
{
indexX = -;
indexY = -;
}
}
}
}
else if (x < centerX - r / )//左半区
{
if (y < centerY)//左上
{
var M = centerY - Math.Sqrt() / * r;
var N = centerY + (centerX - r - x) * Math.Sqrt();
var MP = (int)(y - M);
var MN = (int)(N - M);
if (MP > (MN + thickness * flat))
{
//索引不变
}
else if (MP < (MN - thickness * flat))//索引单变
{
indexX--;
indexY--;
}
else
{
if (MP == MN + thickness * flat)//里侧
{
transparent = (byte)(transparent / );
if (x == centerX - r + thickness + )
{
indexX = -;
indexY = -;
}
}
else if (MP == MN - thickness * flat)//外侧
{
indexX--;
indexY--;
transparent = (byte)(transparent / );
}
else
{
indexX = -;
indexY = -;
}
}
}
else//左下
{
var M = centerY + Math.Sqrt() / * r;
var N = centerY - (centerX - r - x) * Math.Sqrt();
var MP = (int)(M - y);
var MN = (int)(M - N);
if (MP > (MN + thickness * flat))//内部
{
if (x == centerX - r + thickness + )//索引不变,但是要清除突兀部分
{
indexX = -;
indexY = -;
}
}
else if (MP < (MN - thickness * flat))//索引单变
{
indexX--;
}
else//隔离带
{
if (MP == MN + thickness * flat)//里侧
{
transparent = (byte)(transparent / );
if (x < centerX - r + thickness * flat - )
{
indexX = -;
indexY = -;
}
}
else if (MP == MN - thickness * flat)//外侧
{
indexX--;
transparent = (byte)(transparent / );
}
else
{
indexX = -;
indexY = -;
}
}
}
}
else//六边形竖条内部
{
var step = (int)Math.Round(Math.Sqrt() * r);
var remainder = y % step; if (remainder <= thickness)//上缓冲
{
indexX = -;
indexY = -;
}
else if (step - remainder - <= thickness)//下缓冲
{
indexX = -;
indexY = -;
} if ((remainder - == thickness) || (step - remainder - == thickness))//六边形上下四圆角控制(分为上下半身)
{
//去除四点
var first = (int)(centerX - r / );
var second = (int)Math.Ceiling((double)centerX - r / );
var third = (int)(centerX + r / );
var fourth = (int)Math.Ceiling((double)centerX + r / ); if (x == first || x == second || x == third || x == fourth)
{
indexX = -;
indexY = -;
}
}
}
} //right超出界面的设置
var rightIndex = Math.Floor(Convert.ToDouble(width - r - r) / ( * Convert.ToDouble(r) / ));
bool xx = indexX > rightIndex;
if (indexX > rightIndex)
{
indexX = -;
indexY = -;
} //bottom超出界面的设置
var bottomIndex = Math.Floor(height / (r * Math.Sqrt())) - ;
//基础位置为(0,bottomIndex+1)
if (indexY > bottomIndex)//&&((indexX-0)%(indexY-(bottomIndex+1))==0))
{
//下分三种情况,第一种是首索引
var isOrNotFirstIndex = indexX == && (indexY == bottomIndex + );
//与首索引同行位置的索引
var isOrNotFirstLineIndex = indexX == (indexY - (bottomIndex + )) * ;
//侧移索引
var isOrNotSideSwayIndex = (indexX + ) == (indexY - (bottomIndex + )) * ; if (isOrNotFirstIndex || isOrNotFirstLineIndex || isOrNotSideSwayIndex)
{
indexX = -;
indexY = -;
}
} return new int[] { indexX, indexY };
}

六边形算法

基于LBS的六边形热力图算法的更多相关文章

  1. 一种O(n)时间复杂度的计数排序算法和Top N热词算法

    排序算法是研究非常广泛且超级经典的算法,主流排序算法的时间复杂度基本都在O(nlogn). 今天就介绍一种以hash表为基础的,时间复杂度能够达到O(n)的排序算法--计数排序: 同时基于它的思想,完 ...

  2. 基于DFA敏感词查询的算法简析

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 项目中需要对敏感词做一个过滤,首先有几个方案可以选择: a.直 ...

  3. <<一种基于δ函数的图象边缘检测算法>>一文算法的实现。

    原始论文下载: 一种基于δ函数的图象边缘检测算法. 这篇论文读起来感觉不像现在的很多论文,废话一大堆,而是直入主题,反倒使人觉得文章的前后跳跃有点大,不过算法的原理已经讲的清晰了.     一.原理 ...

  4. 【CityHunter】基于LBS的AR体感游戏设计理念

    本人目前还不是游戏行业的圈内人士,并不懂得,游戏行业的生态圈,也不懂得,所谓的什么“中国市场环境”.所以不敢发表关于这方面的见解,不过我在这里想要插一句话,就是我认为啊,行业内,人与人之间还是有分层次 ...

  5. 在做基于LBS应用的一些随笔

    公司做了一个基于LBS的APP,在做服务端的时候出现了一些注意事项,还是记录下把. 首先是关于坐标: 弧长公式:L=nπr/180°或l=|α|r.地球半径大致是6400千米.以纬度0.000001为 ...

  6. 基于SNMP的路由拓扑发现算法收集

    一.三层(网络层)发现 算法来源:王娟娟.基于SNMP的网络拓扑发现算法研究.武汉科技大学硕士学位论文,2008 数据结构: 待检路由设备网关链表:存放指定深度内待检路由设备的网关信息,处理后删除. ...

  7. SVD++:推荐系统的基于矩阵分解的协同过滤算法的提高

    1.背景知识 在讲SVD++之前,我还是想先回到基于物品相似的协同过滤算法.这个算法基本思想是找出一个用户有过正反馈的物品的相似的物品来给其作为推荐.其公式为:

  8. 基于LBS的地理位置附近的搜索以及由近及远的排序

    Nosql学习之Redis资料(一) http://redis.io/download 目前基于LBS地理位置的搜索已经应用非常广了,的确是个很方便的东西. 我们做程序的就是要考虑如何通过这些功能,来 ...

  9. 基于mapreduce的大规模连通图寻找算法

    基于mapreduce的大规模连通图寻找算法 当我们想要知道哪些账号是一个人的时候往往可以通过业务得到两个账号之间有联系,但是这种联系如何传播呢? 问题 已知每个账号之间的联系 如: A B B C ...

随机推荐

  1. redis 主从配置,主从切换

    只需修改从配置文件 # slaveof <masterip> <masterport> slaveof 127.0.0.1 6379 # masterauth <mast ...

  2. ASP.NET Core Web API 与 SSL

    SSL 一直没有真正研究过SSL,不知道下面的理解是否正确. SSL是Secure Sockets Layer的缩写,它用来保护服务器和客户端之前的通信.它是基于信任+加密的概念. 在介绍SSL的原理 ...

  3. python传入不确定个数参数

    Python3自带的一个函数为 zip ,使用方式如下: In: print zip([1, 2],[3, 4]) Out: [(1, 3), (2, 4)] In: print zip([1, 2] ...

  4. BBS论坛(三十)

    30.显示评论和添加评论功能完成 (1)apps/models.py class CommentModel(db.Model): __tablename__='comment' id=db.Colum ...

  5. vue组件如何被其他项目引用

    自己写的vue组件怎么才能让其他人引用呢,或者是共用组件如何让其他项目引用.本文就粗细的介绍下,如有疑问欢迎共同讨论.在这里你能了解下如下知识点: 1. 如何发布一个包到npmjs仓库上 2.如何引用 ...

  6. IdentityServer4之Implicit(隐式许可) —— oidc-client-js前后端分离

    IdentityServer4之Implicit(隐式许可) —— oidc-client-js前后端分离 参考 官方文档:oidc-client-js:oidc-client是一个JavaScrip ...

  7. I-think-2

    最近自己的压力的确很大,对自己近期思想情况做一个总结. 本来假期都自己的未来已经做了一个详细的规划:其中近期的目标就是考上一所自己心仪的大学去读研究生,并且自己也选好了大学,作为自己研究生的目标--- ...

  8. String str=null; 和String str=""的区别

    1.最大的区别在于String str=null没有分配内存,String str=""分配了内存 2.String str=null   这个引用指向了一个null ,没有地址没 ...

  9. 通过Python、BeautifulSoup爬取Gitee热门开源项目

    一.安装 1.通过requests 对响应内容进行处理,requests.get()方法会返回一个Response对象 pip install requests 2.beautifulSoup对网页解 ...

  10. Kafka监控系统Kafka Eagle剖析

    1.概述 最近有同学留言反馈了使用Kafka监控工具Kafka Eagle的一些问题,这里笔者特意整理了这些问题.并且希望通过这篇博客来解答这些同学的在使用Kafka Eagle的时候遇到的一些困惑, ...