六边形算法:

  我把六边形铺满的分布图进行了切分,切分为矩形,每个矩形中有一个六边形、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. 【RL-TCPnet网络教程】第33章 SMTP简单邮件传输协议基础知识

    第33章      SMTP简单邮件传输协议基础知识 本章节为大家讲解SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)的基础知识,方便后面章节的实战操作. (本 ...

  2. Spring使用支付宝扫码支付

    前一段一直在研究支付宝的扫码支付,不得不说,支付宝的文档写的真是一个烂(起码在下刚开始看的时候是mengbi的).文档上面的示例和demo里面的示例长的完全不一样.往往文档上面的例子很简单,而demo ...

  3. Java的几种设计模式

    java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式. 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模 ...

  4. [Swift]LeetCode338. 比特位计数 | Counting Bits

    Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the ...

  5. [Swift]LeetCode347. 前K个高频元素 | Top K Frequent Elements

    Given a non-empty array of integers, return the k most frequent elements. Example 1: Input: nums = [ ...

  6. 起底区块链人脸识别黑马,一个没有人像的人脸识别:iFace Chain(爱妃链)

    近几年来,人脸识别技术可谓在移动互联网中得到了空前广泛应用,从银行APP免密转账,人脸快捷支付到证券人脸开户,人脸识别技术已经应用到了移动互联的诸多应用场景.互联网无处不在的今天,便捷与安全貌似是一个 ...

  7. 使用ML.NET实现德州扑克牌型分类器

    导读:ML.NET系列文章 本文将基于ML.NET v0.2预览版,重点介绍提取特征的思路和方法,实现德州扑克牌型分类器. 先介绍一下德州扑克的基本牌型,一手完整的牌共有五张扑克,10种牌型分别是: ...

  8. redis 系列9 对象类型(字符串,哈希,列表,集合,有序集合)与数据结构关系

    一.概述 在前面章节中,主要了解了 Redis用到的主要数据结构,包括:简单动态字符串.链表(双端链表).字典.跳跃表. 整数集合.压缩列表(后面再了解).Redis没有直接使用这些数据结构来实现键值 ...

  9. Lucene 05 - 使用Lucene的Java API实现分页查询

    目录 1 Lucene的分页查询 2 代码示例 3 分页查询结果 1 Lucene的分页查询 搜索内容过多时, 需要考虑分页显示, 像这样: 说明: Lucene的分页查询是在内存中实现的. 2 代码 ...

  10. RAID磁盘阵列是什么(一看就懂)

    在单机时代,采用单块磁盘进行数据存储和读写的方式,由于寻址和读写的时间消耗,导致I/O性能非常低,且存储容量还会受到限制.另外,单块磁盘极其容易出现物理故障,经常导致数据的丢失.因此大家就在想,有没有 ...