本帖最后由 00ll00 于 2020-4-5 23:04 编辑
更精准的方块视线追踪
与更更精准的方块视线追踪
-1.这个方法已过时
这个方法虽然比较精确,但是大量使用实体,实用性能不强。空白白直接采用数学计算,可以精确到方块内部碰撞箱,而且很快:
[CBL|K_bai]解决你的一切射线追踪烦恼!超精准的射线追踪碰撞检测器[1.14.4+]
0.目前方法的缺陷
臆测目前大部分的CBer在遇到追踪玩家所指向的远处的方块时都会用如下方法:
- 以玩家的视线方向步进基准点
- 判断基准点处是否为空气
- 若是,则返回第一步
- 若不是,则当前方块即所求方块
但这个方法有很多缺陷:
在视线从方块边缘穿过方块时有极大的几率漏过:
而通常的解决方法是减小步长,这样不仅增大了游戏的负担,而且仍然难以解决这种刁钻的问题:
虽然一般来说这种情况的误差可以忽略,但若放在目前本人正在制作的绘图包中,就很容易因为穿透而出现漏墨的现象。因此需要一种更加精准的判定方法。
这是我目前使用的方法,仍发现了一些漏洞,但是已经够用了(应该)。详见2.更更精准的方法
- 以玩家的视线方向步进基准点
- 判断基准点处是否为空气
- 若不是,则当前方块即所求方块
- 若是,则继续判断基准点周围六个方块是否都为空气
- 若是,则返回第一步
- 若不是,则继续判断视线所指向方块为哪个方向的方块(X+,X-,Y+,Y-,Z+,Z-)
- 继续判断该方向的方块是否为空气
- 若是,则返回第一步
- 若不是,则指向的方块为所求方块
这一系列步骤中,最关键的一步就是第六步,判断视线所指向方块为哪个方向的方块了,接下来重点讲解。
首先我们简化一下问题,只考虑xz平面上的情况。
(以X+方向为0°,逆时针方向为正)
假设在当前基准点及水平视角如图
很容易看出视线指向了X+方向的方块,那么如何计算出这个结果呢
我们可以通过找出X+方向的临界值的方式来判断
只要视线角度在临界角度之间,我们就可以认为指向的是X+方向的方块。其他方向同理。
于是再简化一下,如图,因为视线角度在0°~90°内,我们只需要判断是指向了X+还是Z+,因为在这个范围内是不可能指向其他方向的,于是就只需要获取到一个临界值并进行比较。其他情况同理。
那么如何找出临界角?
我们可以分别在基准点位置和顶点处召唤两个Marker[O,T],然后用execute facing的方式使O看向T,这时O的视角即临界角。
通过测试,比较角度时只需要精确到十分位便可以在xz方向上拥有能与mc自带黑框相媲美的精确度。
接下来我们继续考虑y方向的问题,即视线是否是从Y+或Y-方向的方块穿出。这个判断要稍微麻烦一些,要用到一些初中数学知识。
还是沿用以上判断临界值的方法,并且我们已经能知道视线水平上指向了哪个方向,于是先考虑以下情况:
用以上的思维,由于仰角小于0°(mc内是这样的,抬头为负,低头为正),所以只需要判断是指向了X+还是Y+,于是需要在这个地方刷一个Marker来确定临界值
怎么刷呢
我们先忽视仰角,在视线前方一定距离处刷一个Marker[U],获取到U和O的坐标信息,然后分别计算出x1,x2,z1,由三角形相似可得z2=z1*x2/x1
于是,我们可以算出临界点的z坐标,又因为临界点是在方块的棱上,所以x,y都是整数化的,通过基于视线角的一些调整便能得到具体的值。
再通过相似的方法获取到仰角临界值并与视线的仰角进行比较,便可判断视线是从Y+还是侧面穿出。
通过测试,将角度放大10倍,坐标放大为128倍后进行运算能得到比较满意的结果。
2.更更精准的方法(只是补充)
在测试的过程中发现了一个非常刁钻的情况
图中视线方向为左下到右上,可以看出,视线本应指到红色混凝土,但前一个点处进行判断时四周都为空气,而下一个点时所指向的方向又并不是非空气方块,所以判定结果就是视线直接穿过了。
这种情况可以通过反向的穿透判定来解决,于是更更精准的方法为:
- 以玩家的视线方向步进基准点
- 判断基准点处是否为空气
- 若不是,则当前方块即所求方块
- 若是,则继续判断基准点周围六个方块是否都为空气
- 若是,则返回第一步
- 若不是,则继续判断视线所指向方块为哪个方向的方块(X+,X-,Y+,Y-,Z+,Z-)
- 继续判断该方向的方块是否为空气
- 若不是,则指向的方块为所求方块
- 若是,反转视线方向进行6~8步
- 若反向判定结果仍为空气,则返回第一步
- 若反向判定结果不为空气,则反向判定指向的方块为所求方块
3.感谢
感谢空白白,SPG,素学姐,如花等大佬的指点
这个教程过于简陋,也暂时没空做单独的数据包,后来做了看下面,感谢各位看了之后没把我打死
4.数据包
使用更更精准的方法,追踪距离为200m,应该能在所有1.14+版本使用(最近的几个快照渲染炸炸的,看起来可能有些奇怪)