ShiChunAn
本帖最后由 ShiChunAn 于 2020-2-12 13:08 编辑

第一次发帖,希望大家包涵其中的不足之处。
本主题已于2018.08.05晚更新,更新内容请见下一页
注意:如果你是Minecraft JAVA版玩家并且你认为原附件中的程序以及能够帮你解决定位要塞的问题,你可以忽略此次更新如果你是Minecraft基岩版玩家或原附件没能帮你很好地解决定位要塞问题,你可以尝试下载此次更新并仔细阅读此次更新的具体内容(位于下一页)

一、前言
有兴趣者可以看看

二、基本原理
伸手党也建议阅读其中的第2条

三、理论计算(两次末影之眼)
伸手党可跳过此部分


四、一个小验证
      因为种种原因,验证的图片我实在是找不到了,但可以简单地阐述一下验证步骤与结果:



五、从两个末影之眼到多个末影之眼

伸手党可跳过此部分





六、源代码(多个末影之眼
本人比较熟悉C语言,故用的C语言(在C++环境下编译)编写的程序,可使用G++编译器编译,本人使用的软件为dev c++


七、基于程序的操作验证(图文
建议仔细观看



八、程序下载&使用方法(2018.8.5更新)
新附件(2018.8.5更新)
要塞计算2018.8.5更新.zip (340.72 KB, 下载次数: 2962)
以下使用方法已经附在压缩文件内,同时内含Stronghold.exe(程序,可能误报有病毒,不过源代码已经附上了不用担心)以及Stronghold.cpp(源代码):坛友@lintx 已经用javascript语言重制并上传到github,使用地址:https://lintx.github.io/minecraft/calc.html;原贴地址:http://www.mcbbs.net/thread-821626-1-1.html。网页运行比程序运行方便,感谢坛友的辛勤付出!

如果你是首次阅读本帖,请先阅读第九部分——误差分析。
新附件更新内容:增加程序Stronghold_BE.exe及其配套的源代码、使用说明,请在第二页查看使用方法
九、误差分析
务必认真阅读


十、写在最后
      快速寻找要塞的方法很多,这只是其中一种。希望大家能够回帖表示支持或指出其中的不足、可优化之处,在此万分感谢!

bilibili UP主小泠君丶在视屏中详细阐述了该方法改进后的一个新的手段,值得借鉴。
https://www.bilibili.com/blackboard/newplayer.html?playlist=false&crossDomain=1&aid=83724814&page=1

2021.12 数据,可能有更多内容第一次发帖,希望大家包涵其中的不足之处。本主题已于2018.08.05晚更新,更新内容请见下一页注意:如果你是Minecraft JAVA版玩家并且你认为原附件中的程序以及能够帮你解决定位要塞的问题,你可以忽略此次更新如果你是Minecraft基岩版玩家或原附件没能帮你很好地解决定位要塞问题,你可以尝试下载此次更新并仔细阅读此次更新的具体内容(位于下一页)
一、前言有兴趣者可以看看Minecraft中生存模式且非作弊的条件下,主世界要塞是通往末地并击杀末影龙的唯一途径,且其内部有丰富的宝藏。这意味着要塞在Minecraft玩家梦寐以求之地。而Minecraft的道具末影之眼会为我们指向最近的要塞方向,这位我们寻找要塞提供了极大的便利。但是每次抛出的末影之眼都有1/6概率遭到破坏。而事实上,寻找要塞的只需两个末影之眼表明方向即可。当然,多抛几次有利于减小误差。这类教程可能之前已经有坛友发过,而这次会将这个方法讲得更细致,这里将简要地探讨利用两次(或更多)末影之眼方向的数据来直接定位要塞坐标的方法。
二、基本原理伸手党也建议阅读其中的第2条    1.坐标在数字上反映了玩家在主世界中的位置。坐标基于一个由三条交于一点(即原点)的坐标轴而形成的网格。玩家会出生在距离原点数百方块的位置上。x轴反映了玩家距离原点在东(+)西(-)方向上的距离;z轴反映了玩家距离原点在南(+)北(-)方向上的距离。(粘贴自wiki)。    2.调试屏幕F3键呼出,显示区块缓存、内存使用、各种参数、玩家的当前坐标和当前游戏帧率图表(粘贴自wiki)。在“两点”法寻找要塞的过程中,我们需要关注调试屏幕中的三个数据:X坐标①Z坐标②当前朝向Facing中的一个参数。如下图所示:
    3.平面上两条非平行线交于一点    这是一个很直观的结论,事实上这是平行线定义的逆否命题。
三、理论计算(两次末影之眼)伸手党可跳过此部分    在Minecraft中,x轴的正方向为正东方向,z轴的正方向为正南方向,而第二版块中所表示的值(-180.0~180.0)表示一个角度,其以z轴正方向为始边,顺时针方向为正方向。基于以上原理,两次末影之眼确定要塞的原理大致如下图所示:
  其中,A点B点为末影之眼的抛出点,它们共同指向要塞S点。我们不难发现,如果这两条直线不平行,那么我们可以确定要塞的准确位置。下面,我们将来推导这一个要塞的坐标公式:(由于涉及到公式编辑,下只能用图片的形式展示)
  于是,S点的坐标得以导出,第二版块中的①,②,③分别对应式中的x,z,θ。


四、一个小验证   因为种种原因,验证的图片我实在是找不到了,但可以简单地阐述一下验证步骤与结果:
   步骤:
   1.在某一点抛出末影之眼,准星指向末影之眼悬停处,记录第二版块中的①②③三项数据;
   2.以与1中方向接近90°的锐角方向行走约120米,再重复步骤1;
   3.带入第三板块中的计算式,求得要塞坐标;
   4.tp至理论坐标,以旁观者模式观测地下构造。
  结果:
   发现要塞结构(新版本的末影之眼不再指向末地传送门,而是指向要塞结构)位于距脚下5m左右(水平距离)。


五、从两个末影之眼到多个末影之眼


伸手党可跳过此部分
   从第四版块的验证中我们不难发现,我们的算法基本正确,但仍有些许误差。事实上,由于在调试屏幕中表示朝向的角度只保留了1位小数,而要塞的距离一般距离玩家较远使得角度之差较小(一般都只有8°左右),因此导致的误差可能不小。我们可以用多抛几次末影之眼的方法来进行修正。
  修正算法:
   1.在多处不同的地点抛出末影之眼(注意确保这些末影之眼指向同一个要塞),记录对应数据,如记录了n组数据;
   2.若这n条直线两两相交,则一共有n*(n+1)/2个交点;
   3.求出覆盖这n*(n+1)/2个点的最小圆圆心,以此圆心作为要塞的基准点,而此圆的半径可用于衡量误差。
  最小覆盖圆算法:
   这个博客已经较为清楚的阐明,此处不再赘述(链接链至CSDN博客)。


六、源代码(多个末影之眼
本人比较熟悉C语言,故用的C语言(在C++环境下编译)编写的程序,可使用G++编译器编译,本人使用的软件为dev c++


代码:

  1. #include<cstdio>
  2. #include<cmath>
  3. #include<cstdlib>
  4. #include<algorithm>
  5. #define MAXN 101
  6. using namespace std;
  7. struct coordinate{
  8.   double x,z;
  9. }loc[MAXN],res[MAXN*(MAXN-1)/2],circle;
  10. double f[MAXN],radius=0;
  11. int n,cnt;
  12. const double pai=3.141592653589793;
  13. coordinate calc(int i,int j){
  14.   coordinate result;
  15.   result.x=(loc.x*cos(f)*sin(f[j])-loc[j].x*sin(f)*cos(f[j])+(loc.z-loc[j].z)*sin(f)*sin(f[j]))/sin(f[j]-f);
  16.   result.z=(loc[j].z*cos(f)*sin(f[j])-loc.z*sin(f)*cos(f[j])-(loc.x-loc[j].x)*cos(f)*cos(f[j]))/sin(f[j]-f);
  17.   return result;
  18. }
  19. double get_distance(coordinate a,coordinate b){
  20.   return sqrt(pow(a.x-b.x,2)+pow(a.z-b.z,2));
  21. }
  22. bool In_Cir(coordinate point){
  23.   return get_distance(point,circle)<=radius+0.001;
  24. }
  25. coordinate solve(double A1,double B1,double C1,double A2,double B2,double C2){
  26.   if(A1*B2-A2*B1==0) return circle;
  27.   return (coordinate){(C1*B2-C2*B1)/(A1*B2-A2*B1),(A1*C2-A2*C1)/(A1*B2-A2*B1)};
  28. }
  29. void get_MinCir(){
  30.   double temp;
  31.   for(int i=1;i<=cnt;i++)
  32.     if(!In_Cir(res)){
  33.    circle.x=res.x,circle.z=res.z,radius=0;
  34.    for(int j=1;j<i;j++)
  35.   if(!In_Cir(res[j])){
  36.     circle.x=(res.x+res[j].x)/2.0,circle.z=(res.z+res[j].z)/2,radius=get_distance(res,circle);
  37.     for(int k=1;k<j;k++)
  38.    if(!In_Cir(res[k])){
  39.   circle=solve(2*(res[j].x-res.x),2*(res[j].z-res.z),pow(res[j].x,2)+pow(res[j].z,2)-pow(res.x,2)-pow(res.z,2),
  40.   2*(res[k].x-res[j].x),2*(res[k].z-res[j].z),pow(res[k].x,2)+pow(res[k].z,2)-pow(res[j].x,2)-pow(res[j].z,2));
  41.   radius=get_distance(circle,res[k]);
  42.    }
  43.    
  44.   }
  45.     }
  46.  
  47. }
  48. int main(){
  49.   //freopen("stronghold.txt","r",stdin);
  50.   scanf("%d",&n);
  51.   for(int i=1;i<=n;i++){
  52.     scanf("%lf%lf%lf",&loc.x,&loc.z,&f);
  53.     f*=pai/180.0;
  54.   }
  55.   for(int i=1;i<=n;i++)
  56.     for(int j=1;j<i;j++){
  57.    if(f==f[j]) continue;
  58.    res[++cnt]=calc(i,j);
  59.     }
  60.   for(int i=1;i<=cnt;i++)
  61.     printf("x=%.3lf,z=%.3lf\n",res.x,res.z);
  62.   random_shuffle(res+1,res+cnt+1);
  63.   get_MinCir();
  64.   printf("\nThe final result is:\n");
  65.   printf("x=%.3lf,z=%.3lf\nr=%.3lf\n",circle.x,circle.z,radius);
  66.   system("pause");
  67. }



七、基于程序的操作验证(图文
建议仔细观看
首先,我抛出了4个末影之眼,记录的数据分别如下:
(截图时末影之眼已开始掉落)



接下来,把这4个数据输入我们的程序(为方便起见,这里已经改为使用文件输入,输入的顺序可能与图片顺序略有不同),输出结果如下:

输出结果中,前6行表示这四条直线两两相交所形成的6个交点的坐标,最后的x,z,r代表着这6个点最小覆盖圆的坐标以及半径。
从输出结果来看,最小覆盖圆的半径只有约10m,当然在我们所理想的误差范围内,下面我们tp至目标点(也就是最小覆盖圆的圆心,x=-494,z=817)进行验证,如下图:

我们不难发现:我们的正下方便是要塞,由此我们可以在相近的位置抛少量的末影之眼便可确定要塞位置(新版本的末影之眼已经不再指向末地传送门而是指向要塞结构,LZ使用的版本为1.12.2)。


八、程序下载&amp;使用方法(2018.8.5更新)
新附件(2018.8.5更新)

以下使用方法已经附在压缩文件内,同时内含Stronghold.exe(程序,可能误报有病毒,不过源代码已经附上了不用担心)以及Stronghold.cpp(源代码):坛友@lintx 已经用javascript语言重制并上传到github,使用地址:https://lintx.github.io/minecraft/calc.html;原贴地址:http://www.mcbbs.net/thread-821626-1-1.html。网页运行比程序运行方便,感谢坛友的辛勤付出!
双击Stronghold.exe打开程序,为一个空白界面,接下来需要您输入数据。


输入格式:
第一行为一个整数n,表示你要输入n个末影之眼的数据,请务必确保n不小于2且不大于100
接下来n行每行包括3个浮点数(小数),依次表示抛出点的x坐标,z坐标,以及朝向角度。
输入完成后,程序会进行计算并输出,
输出内容含义如下:
首先有至多n*(n+1)/2行,每行表示其中某两个末影之眼所解出的要塞坐标数据
接下来有一个The final result is: 其后的x= ,z= 表示上述点的最小覆盖圆圆心,最后一行r=表示最小覆盖圆半径。


#####务必注意#####
1. n的取值一定是不小于2且不大于100的整数,否则将极易出现程序崩溃(程序中未在此处设置保护)。
2. 请尽量确保输入数据中不要存在两个末影之眼数据的角度值相同(即平行),尽管程序已经写了保护代码。
3. 本程序仍处于测试阶段,如您发现任何BUG请速与作者联系。


如果你是首次阅读本帖,请先阅读第九部分——误差分析。
新附件更新内容:增加程序Stronghold_BE.exe及其配套的源代码、使用说明,请在第二页查看使用方法
九、误差分析
务必认真阅读
以下操作可能导致严重的误差,请务必避免:
1. 抛出的末影之眼中可能存在两个或更多指向不同要塞。这在程序中的表现为最小覆盖圆的半径可能很大,保证不同末影之眼的抛出点相距不太远即可;
2. 抛出的末影之眼中可能存在两个或更多指向角度相同或极其接近。解决方法见下文的第一点。


以下操作有助于减小误差
由于角度数据中,调试屏幕只保留了一位小数,而最大的误差往往来自于角度之差,因此要使角度之差尽量的大。
1. 抛出一个末影之眼后,与其方向呈接近90度的一个锐角前进,在前进相同距离的情况下大体上可保证角度最大;
2. 前进的距离可大致控制在80~180格,太小可能使角度差值不大,太大可能导致末影之眼指向不同的要塞;
3. 多抛几个末影之眼,建议抛(不同位置)3~4个,由此定位的误差相对较小。


到达理论点后:
因为这只是一个大致位置,要塞可能在该点附近而不在该点上。因此可以向下挖后再向旁边挖挖。如果你愿意,也可以使用透视观察。


十、写在最后
   快速寻找要塞的方法很多,这只是其中一种。希望大家能够回帖表示支持或指出其中的不足、可优化之处,在此万分感谢!


bilibili UP主小泠君丶在视屏中详细阐述了该方法改进后的一个新的手段,值得借鉴。
https://www.bilibili.com/video/av83724814



2018.8.5更新:
本次更新是考虑到Minecraft基岩版无法获得角色朝向角度,而采用通过另一种手段定位要塞。通俗的讲,就是从原本的定点+倾斜角确定直线 改为 两定点确定直线


注意:本页内容于2018.08.05新建,如果您还没有阅读过前一页,请您先阅读前一页 如果你Minecraft JAVA版玩家并且认为第一页原附件中的程序已经能够帮你较好地解决定位要塞的问题,你可以忽略此次更新。值得注意的是,本页所讨论的方法依然适用于JAVA版本。

    之所以没有将此更新发到基岩版,是因为在测试时因为基岩版本身机制的问题(正文中将提及)导致定位精度明显不足,不具备如同JAVA版的方便与普适性。而JAVA版此方法依然可以保证较高精度的定位(使用此方法的误差来源主要是偶然误差而非前一页的系统误差,因此并不能绝对地比较孰优孰劣),因此通过编辑原贴的方式更新。
    由于第一页所讲的方法对于JAVA版而言应该可以说是最好的方法,因为对于JAVA版的玩家,本页的方法误差相对于前一页的更小,但操作起来却要复杂更多,而前一页方法的误差已经可以接受,“性价比”还是前一种方法更高。所以本页的方法建议JAVA版对原程序不够满意的玩家以及基岩版有意尝试采用两次末影之眼快速定位要塞的玩家阅读。


〇、发一下小牢骚(不阅读此部分完全不影响阅读本页内容,请务必深思熟虑后再点开)    由于在矿工茶馆版及新闻版中与@AZWorld 大大(恕我冒昧at一下)添加了Xbox好友。楼主本来很少玩基岩版,但今天楼主偶然间登录Xbox发现这位比我小一两岁并对计算机技术如此痴迷的大大坛友在玩Minecraft Win10版,让我想到了我先前忽略了大量基岩版玩家群体并且我原来发布的寻找定位的方法不适用于基岩版,因此发布了这个主题,楼主不才,这顺便也作为与结识@AZWorld 的见面礼。当然,根本目的依然是探讨适用于基岩版的快速定位要塞的方法。一、前言    在Minecraft的JAVA版本中,我们运用了多个末影之眼的抛出点坐标以及对应调试屏幕中能获得的角色朝向角度信息较为容易地获得了要塞坐标,且总体而言,该方法的误差在可接受范围以内,正确操作的情况下误差随当前位置与要塞距离的增大而小幅增大。但是,Minecraft基岩版由于缺少了调试屏幕,我们不能直接获取角色朝向这一信息,这使得JAVA版本中快速定位要塞的方法在基岩版中失效,本主题将在JAVA版本快速定位要塞方法的基础上探讨适用于基岩版的快速定位要塞的方法。注意:本方法依旧适用于JAVA版且在JAVA版中使用此方法误差与基岩版相比更小,但在生存模式下原方法误差小且性价比高,因此建议JAVA版玩家在不得已的情况下(原方法定位精度超过可接受范围时)再尝试使用此方法。。但是,由于基岩版在不作弊的情况下坐标只能精确到整数,使得基岩版使用本方**出现较大的误差。
二、原理    从JAVA版本的方法出发,该方法需要使用基岩版无法直接获取的角色朝向信息来确定直线。概括一下便是:  平面坐标系内一个点与一个相对角度确定一条直线;    不过,平面坐标系内确定一条直线的方法当然不止上述一种,还有一个更为直观的公理可以确定直线:  两个定点确定一条直线。    特别地,在平面上时,上述命题依然成立。而基岩版中,打开“显示坐标”按钮能够获得角色当前位置的坐标(保留整数),因此我们可以采用此方法确定直线。角色抛出末影之眼所站立的位置A点与末影之眼掉落后的落点B点(暂时如此定义)能够轻松得到。大致如下图所示,注意Minecraft坐标系中x轴正方向为东,z轴正方向为南:

    下面,我们将推导由两条根据确定了“两点”坐标的直线的交点坐标。理论上,交点坐标即为要塞坐标。JAVA版本的方法因为采用的是定点+角度,因此当时采用了参数方程的解法。而这里是给定了两个点,则直接写出直线方程来得更快。由于涉及到公式编辑,下面用图片的形式展示:



    为了方便楼主编写程序,这里使用了矩阵与行列式。如果希望手算出结果而且不知道行列式的坛友可以参考最后一排的公式。
    而事实上,我们可能不止抛两个末影之眼,对于抛了多个末影之眼的修正算法,我们仍然沿用JAVA版定位要塞中的处理方式——求这些直线两两相交所得的所有交点的最小覆盖圆。最小覆盖圆的算法依然见这个博客(CSDN博客)。最小覆盖圆的圆心表示修正得到的要塞坐标,最小覆盖圆的半径用于衡量点的离散程度,也能体现出误差


三、程序源代码    在发JAVA版本的方法时不少坛友就看出了我是一个C++的OIer(不过我也只是省一过一点的水平),因此还是用我最擅长的C++语言写代码吧:

代码:

  1. #include<cstdio>
  2. #include<cmath>
  3. #include<cstdlib>
  4. #include<algorithm>
  5. #define MAXN 101
  6. using namespace std;
  7. struct coordinate{
  8.   double x,z;
  9. }loc[MAXN][2],res[MAXN*(MAXN-1)/2],circle;
  10. double radius=0,matrix[3][3];
  11. int n,cnt;
  12. coordinate calc(){
  13.   matrix[0][1]=matrix[1][0]*matrix[2][2]-matrix[2][0]*matrix[1][2];
  14.   matrix[0][2]=matrix[1][1]*matrix[2][0]-matrix[2][1]*matrix[1][0];
  15.   return (coordinate){matrix[0][1]/matrix[0][0],matrix[0][2]/matrix[0][0]};
  16. }
  17. double get_distance(coordinate a,coordinate b){
  18.   return sqrt(pow(a.x-b.x,2)+pow(a.z-b.z,2));
  19. }
  20. bool In_Cir(coordinate point){
  21.   return get_distance(point,circle)<=radius+0.001;
  22. }
  23. coordinate solve(double A1,double B1,double C1,double A2,double B2,double C2){
  24.   if(A1*B2-A2*B1==0) return circle;
  25.   return (coordinate){(C1*B2-C2*B1)/(A1*B2-A2*B1),(A1*C2-A2*C1)/(A1*B2-A2*B1)};
  26. }
  27. void get_MinCir(){
  28.   double temp;
  29.   for(int i=1;i<=cnt;i++)
  30.     if(!In_Cir(res)){
  31.    circle.x=res.x,circle.z=res.z,radius=0;
  32.    for(int j=1;j<i;j++)
  33.   if(!In_Cir(res[j])){
  34.     circle.x=(res.x+res[j].x)/2.0,circle.z=(res.z+res[j].z)/2.0,radius=get_distance(res,circle);
  35.     for(int k=1;k<j;k++)
  36.    if(!In_Cir(res[k])){
  37.   circle=solve(2*(res[j].x-res.x),2*(res[j].z-res.z),pow(res[j].x,2)+pow(res[j].z,2)-pow(res.x,2)-pow(res.z,2),
  38.   2*(res[k].x-res[j].x),2*(res[k].z-res[j].z),pow(res[k].x,2)+pow(res[k].z,2)-pow(res[j].x,2)-pow(res[j].z,2));
  39.   radius=get_distance(circle,res[k]);
  40.    }
  41.    
  42.   }
  43.     }
  44.  
  45. }
  46. int main(){
  47.   //freopen("stronghold.txt","r",stdin);
  48.   scanf("%d",&n);
  49.   for(int i=1;i<=n;i++)
  50.     scanf("%lf%lf%lf%lf",&loc[0].x,&loc[0].z,&loc[1].x,&loc[1].z);
  51.   for(int i=1;i<=n;i++)
  52.     for(int j=1;j<i;j++){
  53.    matrix[1][1]=loc[0].z-loc[1].z;
  54.    matrix[1][2]=loc[1].x-loc[0].x;
  55.    matrix[2][1]=loc[j][0].z-loc[j][1].z;
  56.    matrix[2][2]=loc[j][1].x-loc[j][0].x;
  57.    matrix[1][0]=loc[1].x*loc[0].z-loc[0].x*loc[1].z;
  58.    matrix[2][0]=loc[j][1].x*loc[j][0].z-loc[j][0].x*loc[j][1].z;
  59.    matrix[0][0]=matrix[1][1]*matrix[2][2]-matrix[1][2]*matrix[2][1];
  60.    if(matrix[0][0]==0)continue;
  61.    res[++cnt]=calc();
  62.     }
  63.   for(int i=1;i<=cnt;i++)
  64.     printf("x=%.3lf,z=%.3lf\n",res.x,res.z);
  65.   random_shuffle(res+1,res+cnt+1);
  66.   get_MinCir();
  67.   printf("\nThe final result is:\n");
  68.   printf("x=%.3lf,z=%.3lf\nr=%.3lf\n",circle.x,circle.z,radius);
  69.   system("pause");
  70. }
四、操作步骤&amp;误差分析
    前面已经说到,基岩版不作弊的情况下所获取到的坐标只是保留整数的情况(使用/tp ~ ~ ~指令可以精确到两位小数,这两位小数的精度将极大地误差。你也可以使用这个指令确定坐标,不过能使用这个指令已经表示你开启了作弊,还不如用/locate指令来得直接,这个看自己),而保留整数这一过程为定位要塞的过程造成了极大的误差,这也是此方法本身不对基岩版特别友好的根本原因。为了尽可能地减小误差,请务必仔细阅读这一部分!    0. 读坐标(读数)注意事项&amp;估读:(JAVA版玩家忽略此部分)  之所以归为第0步,是因为这并不是一个步骤,而是在步骤中将可能采用到的方法。估读是中学知识。这里为什么会提到估读?由于坐标保留小数大大提高了误差,这使得估读变得很有必要。当然你也可以选择不估读,采用一些适当的技巧也能在一定程度上减小误差。在保留整数的情况下,如果你站在一个方块的正中心,你的实际坐标是x,z轴的代数值加上0.5。比如你站在一个方块的中心,显示的坐标是-25 62 7,那么你实际的坐标是-24.5 62 7.5。你可以以此为基准进行小数点后一位的估读,比如你目测你的位置是-24.7 64 7.3。你也可以不估读,直接目测是更接近方块中心还是边缘(x轴坐标数值向东增加;z轴坐标数值向南增加),决定是直接取整还是取多少.5。    1. 确定玩家抛出点的坐标:(JAVA版玩家忽略此部分正文)  这一步本身不困难,按照第0步的方法确定坐标。比如我不想估读,那我就尽可能地靠近方块中心。  下图是JAVA版中的抛出点坐标: 

    2. 根据抛出末影之眼的轨迹确定对应的第二个坐标:
  这里提供三种方法,每种方法都有自己的优缺点,请结合自己生存中的实际情况来确定使用哪一种方法,或者各位坛友有更有效的方法欢迎回复(毕竟我还是一个基岩版的小白):
  方法一:根据末影之眼的落点确定坐标
   注意:末影之眼有小概率不掉落,即使掉落你也会发现它会向旁边偏移一小段位移(就像你挖方块,爆出来的掉落物会往旁边偏离一样,不会掉在正中间),注意在读数时尽量修正这个偏移。
   优点:耗材少,操作简单。
   缺点:抛出点与落点距离略近,且偏移修正较难,误差较大。
   建议JAVA版可尝试采用;基岩版除非你有极其好的目测能力,否则不推荐使用此方法。  方法二:十字准星对准末影之眼悬停点,然后朝该方向射箭,根据箭的落点确定坐标
   注意:如果箭射到了方块的侧面或底面则依然不能得到较为精确地得到坐标。
   优点:耗材少,且箭的落点离抛出点不太近能够降低最终误差,只要箭射到方块顶部就可以很方便地读数,误差较小。
   缺点:如果箭未射到方块顶部则会造成较大误差(建议重射),并且有可能找不到自己的箭。
   建议基岩版推荐使用此方法,尽量在空旷处抛末影之眼并射箭,便于使箭射到方块顶部且容易被找到。蓄力可以不用蓄满,否则很难找到射出的箭。JAVA版可尝试采用。
  方法三:十字准星对准末影之眼悬停点,然后朝该方向抛末影珍珠,根据瞬移位置确定坐标
   注意:瞬移成功后一定不要走动,进行读数时一定要看清楚自己落在方块上的位置(中心还是靠边)。
   优点:确定坐标方便,误差较小。
   缺点:耗材较大,毕竟大家多数都是缺末影珍珠而不缺烈焰粉。并且往回走才能回收末影之眼。
   建议如果缺少末影之眼不建议使用此方法。
  总评:JAVA版玩家因为坐标保留了三位小数,因此方法三精度极高,方法一、二精度也差强人意,操作都毕竟简便;而基岩版由于坐标都只能保留整数,三种方法误差都不容小觑,这也是基岩版使用此方法往往定位精度极低的原因。  下图是采用方法三确定的第二个点的坐标:

  3. 重复步骤1&amp;2至少一次(推荐两次):   完成步骤1,2后,我们已经可以确定一条直线了。但是我们需要至少两条直线才能确定交点。考虑到此方法操作较为繁琐,建议再重复两次(一共进行3次为宜)。到达理论位置后(JAVA版位置多数情况下相当精确,基岩版位置可能不太精确),如果不放心可以如@393575404 所言,再进行一次操作,这样就几乎没问题了。   不过重复步骤1,2时注意要在不同位置进行,尽量确保不同直线间的夹角尽量地大,具体操作见第一页第九部分——误差分析。   下面是我重复两次步骤1,2所得到的4个坐标:   第一次重复抛出点:   
   第一次重复末影珍珠落地点:   
   第二次重复抛出点:   
   第二次重复落地点:   
五、程序使用  经过第四部分,我们已经搜集了不少的坐标数据,下面我们需要输入程序来求解:   新附件(2018.8.5更新)     以下使用方法已经附在压缩文件内,同时内含Stronghold_BE.exe(程序,可能误报有病毒)以及Stronghold_BE.cpp(源代码),当然,原来的程序也在压缩包内:
双击Stronghold_BE.exe打开程序,为一个空白界面,接下来需要您输入数据。
输入格式:
第一行为一个整数n,表示你要输入n个末影之眼的数据,请务必确保n不小于2且不大于100
接下来n行每行包括4个浮点数(小数),前两个浮点数依次表示抛出点的x,z坐标;后两个浮点数依次表示落地点(第二个点)的x,z坐标。
输入完成后,程序会进行计算并输出,
输出内容含义如下:
首先有至多n*(n+1)/2行,每行表示其中某两个末影之眼所解出的要塞坐标数据
接下来有一个The final result is: 其后的x= ,z= 表示上述点的最小覆盖圆圆心,最后一行r=表示最小覆盖圆半径。


#####务必注意#####
1. n的取值一定是不小于2且不大于100的整数,否则将极易出现程序崩溃(程序中未在此处设置保护)。
2. 请尽量确保输入数据中不要存在两个末影之眼数据的解出的直线平行,尽管程序已经写了保护代码。
3. 本程序仍处于测试阶段,如您发现任何BUG请速与作者联系。
    按照输入输出格式,我们将上面6个图的坐标输入程序:

    按下回车键计算,得到:
    最小覆盖圆半径有50多格,说明误差还是不算小,传送过去的情况:

    我们可以看到要塞,但是离我们脚下还是有一段明显的距离。不过再重复第四部分中第1~3步就可以找到要塞。    而把这些数据带到我们第一页中最开始的程序中来,会发生什么(注意:这里只用到了3个抛出点的数据,也就是只用了那6个图中的3张不在海里面的图):

    emmm...原来版本的误差要小得多。看来楼主还是不太适合实际操作,抛末影珍珠的时候手有点抖,而且末影珍珠的弹道还会受外界条件的影响。
六、最后    总的来讲就是系统误差与偶然误差的区别,如果各位在读数时把握得当,那么这个新的方法就很不错了,就看大家各自的喜好了。另外,这个方法适用于基岩版(尽管最小覆盖圆的半径往往突破300),但到达理论点后再重复操作就基本没问题了,总的来讲,个体还是更喜欢第一页根据角度确定直线的方法。



skyliye
数学大佬,佩服佩服啊

提尔兰特
哇参数方程,高中狗表示刚学完,刚好看得懂

ShiChunAn
回不去的光 发表于 2018-6-16 17:05
哇参数方程,高中狗表示刚学完,刚好看得懂

不错不错。只是因为这里z轴的正方向和y轴的正方向相反,并且那个角度与数学上的角度有很大不同,所以正负号和sin与cos有所变化,不知您发现了没有(免得因为我的贴考试的时候用错了很尴尬

ShiChunAn
skyliye 发表于 2018-6-16 15:08
数学大佬,佩服佩服啊

只是高中知识,也没有那么厉害

2759159258
初三数渣看不懂系列....QWQ

丢人素学姐
本帖最后由 Vinogradov 于 2018-6-16 21:32 编辑

总结地不错。
我有个建议,或者说想法,就是如果能把这套东西做成一个用来辅助寻找要塞的client端mod就更方便了。玩家只管扔,由mod来计算预期的要塞位置。也许过一阵子我会试着做做看。

另外你用的就是C++语言而不是C语言。看你的头文件就知道这是C++的STL。

提尔兰特
ShiChunAn 发表于 2018-6-16 19:01
不错不错。只是因为这里z轴的正方向和y轴的正方向相反,并且那个角度与数学上的角度有很大不同,所以正负 ...

这个我注意到了啊,还纳闷怎么正负号不一样的,原来是这样啊,而且放心考试绝对还是按自己学的知识为准的233

ShiChunAn
Vinogradov 发表于 2018-6-16 21:31
总结地不错。
我有个建议,或者说想法,就是如果能把这套东西做成一个用来辅助寻找要塞的client端mod就更方 ...

好吧 只是输入输出不用cin和cout而已了

ShiChunAn
Vinogradov 发表于 2018-6-16 21:31
总结地不错。
我有个建议,或者说想法,就是如果能把这套东西做成一个用来辅助寻找要塞的client端mod就更方 ...

做出来的话也是相当不错的,而且技术上应该也不难实现。期待您的作品

buhuichongfu
三角函数忘光了,早就想到这种方法,但不会算。

最后灵机一动,三角板+量角器+铅笔……嗯,两颗珠子找到了2333

excit
大佬大佬,我连函数都没学

ShiChunAn
buhuichongfu 发表于 2018-6-17 12:20
三角函数忘光了,早就想到这种方法,但不会算。

最后灵机一动,三角板+量角器+铅笔……嗯,两颗珠子找到了 ...

这个方法6

Deing
我倒是觉得一般不太容易指到两个不同的要塞吧,第一个末影之眼用完后走出几百格也是可以的。
不过也许只是我正好没有遇到过指到两个不同要塞的情况吧

ShiChunAn
Deing 发表于 2018-6-18 18:14
我倒是觉得一般不太容易指到两个不同的要塞吧,第一个末影之眼用完后走出几百格也是可以的。
不过也许只是 ...

理论上几百格一般没什么问题,但还是要以防万一才好

10161616
数学大佬。。。

2606891869
靠我初中数学还算看懂,如果手动计算,等到计算出来别人都找到了呢。。。。

2606891869
ShiChunAn 发表于 2018-6-19 23:42
理论上几百格一般没什么问题,但还是要以防万一才好

万一要是见鬼了,这时候我们就要/seed

ShiChunAn
2606891869 发表于 2018-6-27 20:17
靠我初中数学还算看懂,如果手动计算,等到计算出来别人都找到了呢。。。。 ...

所以懒惰而聪明的人们发明了计算机

1278563252
试用了一下 真的好用 佩服佩服

1278563252
试用了一下 真的好用 佩服佩服

ShiChunAn
1278563252 发表于 2018-7-5 18:41
试用了一下 真的好用 佩服佩服

层主手抖不小心发了两个,感谢支持!

dkrsfgdr
。。。。。。。。。。。。

l1ll5
标准Oier代码(逃

纸鹿君_L33
数学大佬 然而对于我只能拼珍珠数量了23333333

ShiChunAn
l1ll5 发表于 2018-7-7 14:08
标准Oier代码(逃

被看穿了吗

EIDS
学了高中三年数学只在找要塞时用过还行。

l8976849
特别厉害,不过感觉没什么用了现在

yikalous
做mod实现起来还是挺简单的,就是需要先把那个算法用java重写一下

fengziqing
楼主是个数学兼计算机大佬
厉害厉害

1351897370
结合自己玩的1.10到1.12的极限生存来说,要塞的xz坐标绝对值普遍会在1000-3000,扔第一个珠子跟着走个几百格或者一千格再扔第二次,这样找不会超过4个(毕竟珠子也不难获得)。回归正题,楼主的这个方法总结的不错,刚考完高考一下子又把参数方程的知识捡回来了

黄狗dalao
感谢楼主,我终于可以少抛末影之眼了

77882243344
前排学习。

ShiChunAn
1351897370 发表于 2018-7-8 14:43
结合自己玩的1.10到1.12的极限生存来说,要塞的xz坐标绝对值普遍会在1000-3000,扔第一个珠子跟着走个几百 ...

其实LZ我也是刚刚高考结束...

ShiChunAn
yikalous 发表于 2018-7-8 13:55
做mod实现起来还是挺简单的,就是需要先把那个算法用java重写一下

算法很简单啊,可惜我没学JAVA(高三才毕业)

翻车:滑稽
哈哈,不愁找要塞了,谢谢lz

ShiChunAn
fgdfgrtr 发表于 2018-7-8 17:37
哈哈,不愁找要塞了,谢谢lz

感谢支持!

ShiChunAn
黄狗dalao 发表于 2018-7-8 14:44
感谢楼主,我终于可以少抛末影之眼了

在浪费了无数小黑眼后痛定思痛想得此法

interesting5319
以前怎么没注意!看到标题我tm灵光一闪‘直线交点’!如果你要当我马后炮也无话可说

l1ll5

顺便大括号换行差评

黄狗dalao
ShiChunAn 发表于 2018-7-8 18:22
在浪费了无数小黑眼后痛定思痛想得此法

XD楼主老哥
实际上我是来水帖的

ShiChunAn
interesting5319 发表于 2018-7-8 18:34
以前怎么没注意!看到标题我tm灵光一闪‘直线交点’!如果你要当我马后炮也无话可说 ...

那我当你炮后马吧【手动滑稽】

ShiChunAn
interesting5319 发表于 2018-7-8 18:34
以前怎么没注意!看到标题我tm灵光一闪‘直线交点’!如果你要当我马后炮也无话可说 ...

抛砖引玉

风扇滑翔翼
/seed+种子预览器即可
但在服务器是个好方法
其实我有个同样的疑问 海贼王要找到4个到位置交叉点才能找到拉德鲁夫 但知道要连线的2个 顺着中间那根线不就能找到了 省去一半工程量

interesting5319

只是说明我没动脑子,思维被其他玩家的视频固化了,

1351897370
ShiChunAn 发表于 2018-7-8 16:38
其实LZ我也是刚刚高考结束...

哈哈有缘人

QAQda
MCBBS有你更精彩!

天空氏老方
厉害、但还是有点愣

SteveJobshjc
万能语言:cpp

SteveJobshjc
顶顶顶顶顶顶顶顶顶顶

下一页 最后一页