高效判断点是否在正六边形蜂窝内的方法

设计中,用到需要判断点是否在正六边形内,先是在网上搜了好几篇文章,发现都搞的挺复杂的,往往要使用向量运算计算面积夹角距离方向等,或者是射线法算交点,或者是切分三角形,这种思路通用于任意多边形。我考虑到正六边形的特殊性,发现这个问题其实可以很讨巧的超简单解决,而且算法简单到连小学生都能理解,核心只要比较两个线段的长度。

Bing搜了一下“判断点是否在正六边形内”,头两条都是关于此问题的,搜到的豆瓣和魅族论坛里的帖子,里面讨论到的方法都不够简洁。

常用蜂窝网格单元的排列方式有2种,一种是相对2个顶点在Y轴,另一种是相对2个顶点在X轴,判断方式是一样的。

下图以2个顶点在Y轴为例。

要判断点P是否在该正六边形(边长a)内,由于只需判断是否在内,与象限无关,所以先将点P坐标取绝对值x,y

1.首先判断P是否在正六边形的外包矩形内,若 y>=a || x>=(√3)a/2 则不在内部,否则继续下一步判断

2.若MP>MN则P在内部,否则不在内部,等于则在边线上。即判断 a-y>x/(√3)是否成立。


上述是判断指定点是否在指定正六边形内,实际开发者更常见的另一种是判断指定点在一组正六边形蜂窝结构的哪一个单元格中,也可以借鉴这个来判定。


  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
实现六边形蜂窝菜单,需要用到六边形坐标系。在六边形坐标系中,每个都可以表示为一个二元组 (q, r),其中 q 表示列坐标,r 表示行坐标。六边形坐标系的特是,相邻的六边形之间的距离是相等的。 具体实现方法如下: 1. 定义一个结构体,用于存储每个菜单项的坐标和内容。 ``` typedef struct { int q; // 列坐标 int r; // 行坐标 char *content; // 菜单项内容 } MenuItem; ``` 2. 定义一个函数,用于计算指定坐标的菜单项在屏幕上的位置。 ``` void get_screen_pos(int q, int r, int *x, int *y) { // 计算菜单项在屏幕上的 x, y 坐标 // ... } ``` 3. 定义一个函数,用于绘制菜单项。 ``` void draw_menu_item(MenuItem *item) { int x, y; get_screen_pos(item->q, item->r, &x, &y); // 在屏幕上绘制菜单项的内容 // ... } ``` 4. 定义一个函数,用于处理鼠标击事件。 ``` void handle_mouse_click(int x, int y) { // 根据屏幕坐标计算出对应的菜单项坐标 int q, r; // ... // 处理菜单项被击的情况 // ... } ``` 5. 在主函数中,定义一个菜单项数组,并初始化每个菜单项的坐标和内容。然后,在主循环中,循环绘制每个菜单项,并监听鼠标击事件。 ``` int main() { MenuItem items[NUM_ITEMS]; // 初始化菜单项 // ... while (1) { // 绘制每个菜单项 for (int i = 0; i < NUM_ITEMS; i++) { draw_menu_item(&items[i]); } // 监听鼠标击事件 int x, y; if (get_mouse_click(&x, &y)) { handle_mouse_click(x, y); } } return 0; } ``` 以上是一个简单的六边形蜂窝菜单的实现思路,具体的实现细节可能会根据实际情况有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值