LocusAzzurro
本帖最后由 LocusAzzurro 于 2021-6-10 13:25 编辑


http://ww1.sinaimg.cn/mw690/0062Lzp6gw1eze0i4ri0aj30m80go778.jpg



使用表达式来生成任何你想要的东西!

大家好,这里Az,最近完成了对WorldEdit中//generate 指令的研究,在这里与大家分享一下获得的成果,发掘这个功能更多的潜能。


目录

I.指令简介
II.指令结构与使用方式
III.可用标示
IV.坐标范围
V.等式与不等式
VI.空心图形标示的使用
VII.逻辑门的使用与多面体
VIII.函数的使用
IX.源坐标的使用
X.移动后源坐标的使用
XI.例子-曲面
XII.例子-多面体
XIII.使用例子
XIV.相关资料与来源
XV.后记


阅读提示:你可能需要如下知识来理解本文并了解它的使用方式


注意本文内容与Perlin噪声研究文章所讨论内容并无关联,二者为WorldEdit下的不同功能

WorldEdit插件系列教程(作者 shengjing1): http://www.mcbbs.net/thread-68779-1-1.html
WorldEdit插件资源(作者 sjjklh): http://www.mcbbs.net/thread-68815-1-1.html
WorldEdit插件简短介绍:
WorldEdit是一个常用的地图编辑工具,玩家可以利用它进行许多建筑中的操作,加快施工速度,同时也提供了许多便捷的功能。




2015/12/27 18:54 GMT+1 一次施工完成
2015/12/27 19:21 GMT+1 二次施工完成
2020/09/08 19:32 GMT+1 图片重修复与纯文本流线化完成


LocusAzzurro
本帖最后由 LocusAzzurro 于 2020-9-8 15:36 编辑

I.指令简介

//generate 为WorldEdit中的一个指令,可简写为//gen或//g,作用是按照用户给出的一个表达式生成对应的形状。这个是WorldEdit一个非常强大的功能,理论上下可以生成任何使用表达式表示的物体,但实际使用有一个较大的限制,由于Minecraft单指令可以输入的最大字符数,过长的表达式无法输入,但就算如此,这个指令仍然可以用来完成一些复杂的操作,在Minecraft各个领域得到应用。在这里我将与各位讲解一下这个指令的使用方法,使用时的注意事项,以及我研究与找到的一些实际使用方法与例子,也希望各位如果有能力一起来完善对这个指令的研究,发掘出他更多的潜力。在正式开始之前,我们来看一个来自WorldEdit Wiki的例子来了解这个指令的强大效果。



http://ww2.sinaimg.cn/mw690/0062Lzp6gw1ezenpik0n0j311y0jlqg8.jpg
一个心形,仅使用了一个指令生成,虽然在这里我不会介绍如此复杂的使用方式,但从这里也不难看出这个指令的强大。用来生成它的指令为
  1. //g wool:red (z/2)^2+x^2+(5*y/4-sqrt(abs(x)))^2<0.6
复制代码
接下来,我们将会一一讲解这个指令的结构与使用方式。

LocusAzzurro
本帖最后由 LocusAzzurro 于 2020-9-8 15:40 编辑

II.指令结构与使用方式

让我们来看一下之前的指令
  1. //g wool:red (z/2)^2+x^2+(5*y/4-sqrt(abs(x)))^2<0.6
复制代码

这其中//g 为 //generate 指令的简写wool:red 为使用的方块ID,这里是红色羊毛,可以是数字ID(如1,2),可以是文字ID(如stone,grass)剩余的部分为生成使用的指令,例子中使用的是一个十分复杂的指令,因为并不是本文的重点,我们就不在这里深入研究了。
但这里要讲解一下表达式书写的方式与需要注意的地方首先让我们看一下表达式的写法,它的写法与Java相似:    WorldEdit Wiki http://wiki.sk89q.com/wiki/WorldEdit/Expression_syntax#Functions         (在下文的函数部分会有更多的介绍)
需要注意的地方有:与日常书写表达式不同,2x,3y等需要用乘号链接,即2*x, 3*y
最后但并不是最不重要的,WorldEdit中使用的是并不是等式,而是不等式,因为WorldEdit会将选区内的每个方块的位置带入计算,并将结果用方块反映出来,此处的结果只能是1,即有方块,或0,即无方块。如果使用等式的话,由于Minecraft为方块世界,精细度不能达到显示结果的程度,所以效果不佳。(等式无法使用的原因为笔者个人推测,如有错误请指出)但虽然不能使用等式,我们仍可以使用-h标示来达到接近的效果,这部分我们会在介绍标示时继续深入。

综上所述,这个指令的格式为
  1. //generate <ID> [-h/-r/-o] <表达式>
复制代码

-h, -r, -o 为这个指令可以使用的标示。
使用这个指令的时候需要选择一个选区,形状会在这个选择的选区中生成,注意选区的形状会影响到输出的形状,有时这个特性会造成一些麻烦,但有时可以使用这个来达到希望的效果,这一点我们接下来会讲到。
同时,就像刚才提到的,在使用这个指令时,我们可以使用一个或几个标示来改变指令的效果,来达到需要的结果。

LocusAzzurro
本帖最后由 LocusAzzurro 于 2020-9-8 15:42 编辑

III.可用标示[简介]

在使用指令时,我们可以添加一个或多个标示来改变指令的运行方式,添加标示的方法很简单,只需要将标示像添加参数一样的方式添加至指令中即可。如:
  1. //g 1 -h x>y
复制代码

可用的标示有三个,分别是-h,-r与-o。-h 会使生成的形状空心-r 会使生成时使用源坐标-o 会使生成时使用源坐标,同时将坐标系原点移动到玩家位置(或者玩家的第一选择点,如果使用了/toggleplace)
-r 与 -o 的效果冲突,因此-o的效果会覆盖掉-r的效果。-h 与 -r 或 -o二者之一可以同时使用
这里仅仅给出一个标示的基本介绍,在本文之后的章节中会一一介绍它们的效果,接下来我们首先来集中看一下不使用任何标示的情况。

LocusAzzurro
本帖最后由 LocusAzzurro 于 2020-9-8 15:51 编辑

IV.坐标范围

在不使用任何标示的情况下,WorldEdit会将当前的选区看做一个三维直角坐标系坐标系原点为选区中心
http://ww3.sinaimg.cn/mw690/0062Lzp6gw1ezdx52eq4yj311y0jltng.jpg

如图,我用羊毛标出了三条坐标轴,WorldEdit使用的坐标轴系统与Minecraft的相同,即从西(负)到东(正)为X轴(蓝),从下到上为Y轴(黄),从北到南为Z轴(红)。
这个坐标系三条轴的界限为 -1 与 +1 ,也可以说生成的范围为 [-1;+1] ,注意这个界限仅在不使用标示或仅使用-h标示时存在,-r 与 -o 的运行方式完全不同,我们在下文会分别看到他们的生成方式。http://ww1.sinaimg.cn/mw690/0062Lzp6gw1ezdx5m8uehj311y0jlqi6.jpg

如上图,我在坐标轴上用金块与钻石块标出了两个点,按照刚才我们讲到的,金块的坐标应为(0;0.5;5)即Y值为0.5,钻石块的坐标为(0.5;0;0)即X值为0.5
下面我们来试试使用几个简单的方程
http://ww4.sinaimg.cn/mw690/0062Lzp6gw1ezdx6g68uaj311y0jmncp.jpg

上图使用的是
  1. //g 95:0 y<0.5
复制代码
效果即为将所有Y值小于0.5的方块位置设置为白色玻璃方块
接下来我们来试试曲面http://ww1.sinaimg.cn/mw690/0062Lzp6gw1ezdx5y4rxrj311v0jldw9.jpg

这里使用了球体的公式
  1. //g 155 x^2+y^2+z^2<1
复制代码
生成出的就是半径为1的实心球体(如果你说这个球半径不是1建议重新阅读本章节)。

到这里可能各位都注意到了(什么?你说你没有?),这几次生成使用的选区都是一个正方体,这是因为只有这样生成出的形体才是比例正确的。那么如果选区不是正方体就不能生成了么?并不是,如果用来生成的选区不是正方体,生成的形状会被按照三轴之间的比例在三轴方向被拉伸或压缩,这还是因为选区的范围为从-1到+1造成的。那么如果我用一个长方体的选区生成就是异端了么?也并不是,这两种方式各有他们的用处,如需要生成一个比例正确的结构,像是一个球体,那么使用正方体选区就是正确的选择,如果要生成的是一个椭球,则可以直接选择一个长方体选区,这样球体就会被按照比例自动被拉伸成椭球,也省去了计算椭球表达式的麻烦。
如下图,选区的Y轴实际长度为X轴和Z轴的两倍,图中的金块的坐标依然为 (0;0.5;0) ,在这个情况下生成的形状在Y轴上就会被拉伸两倍。
http://ww2.sinaimg.cn/mw690/0062Lzp6gw1ezdx5hh0arj311y0jljy5.jpg

如果我们再次使用之前的
  1. //g 95:0 y<0.5
复制代码

http://ww2.sinaimg.cn/mw690/0062Lzp6gw1ezdx6iw4h1j311y0ji47b.jpg

可以看到填充的部分依然是选区下方的3/4 部分,但在Y轴上填充的高度变为了之前的2倍。
最后让我们再次使用一下之前的球体公式
http://ww2.sinaimg.cn/mw690/0062Lzp6gw1ezdx6d1e93j311y0jhgv3.jpg

可以看到,就如刚才所说,生成出的是一个椭球。

LocusAzzurro
本帖最后由 LocusAzzurro 于 2020-9-8 15:56 编辑

V.等式与不等式

刚才提到了WorldEdit使用的不等式而非等式,这里简单来讲解一下二者的区别(学霸可以跳过)。
下面的这个等式是一条直线
http://ww4.sinaimg.cn/mw690/0062Lzp6gw1ezdxjhmeywj30ts0d9aab.jpg

而不等式表达的是一个区域
http://ww2.sinaimg.cn/mw690/0062Lzp6gw1ezdxj41194j30ti0cw0t2.jpg


WorldEdit中使用的是不等式,来表达一个区域,这个区域中的方块位置便会被放置方块。

LocusAzzurro
本帖最后由 LocusAzzurro 于 2020-9-8 16:03 编辑

VI.空心图形标示的使用

刚才我们提到了生成时可以使用表示来改变命令的输出,首先我们来看一下空心图形标示,即 -h ,它的作用是可以使生成的图形“空心”,即只有图形边缘位置得方块会被生成,这个边缘的判定方式是“如果这个方块位置一方块单位周围的任何方块位置不属于这个图形,那么这个位置的方块就会被生成,反之则不生成。
首先我们来看一个例子
http://ww3.sinaimg.cn/mw690/0062Lzp6gw1ezdxt0qwk4j311y0jlk49.jpg

上图使用的指令是
  1. //g 95:0 x^2+y<1
复制代码
即一个抛物面的下方部分
如果使用相同的表达式,但是使用-h 标示,结果就会是这样的(下图红色玻璃部分为新指令输出,覆盖到白色玻璃的旧指令的输出上进行比较)。
http://ww4.sinaimg.cn/mw690/0062Lzp6gw1ezdxsxesh0j311y0jigz2.jpg

可以看到,只有抛物面最上方(也可以说只有抛物面本身)的位置生成了方块。上图使用的是
  1. //g 95:14 -h x^2+y<1
复制代码

就像我们刚刚看到的,使用这个方式也可以使不等式拥有类似等式的输出,接下来我们来看一下另一个例子。在本文开始的部分我们提到了球体内部的不等式
  1. x^2+y^2+z^2<1
复制代码
如果我们使用-h 标示,就可以生成空心的球体,即表达式为
  1. x^2+y^2+z^2=1
复制代码
的球面,虽然并不能达到完全准确,但也能达到**分。
那么,我们来看一下生成的效果:http://ww3.sinaimg.cn/mw690/0062Lzp6gw1ezdxtqc69wj311y0jm4at.jpg

上图使用的命令为
  1. //g 95:0 -h x^2+y^2+z^2<1
复制代码

可以看到使用空心图形标示的效果。
到现在为止,我们使用的例子都是简单的平面或曲面,那么各位可能会问了,像是正方体这种有棱有角的多面体可以生成吗?答案是肯定的,但生成多面体我们需要用到另一个功能,那就是逻辑门

LocusAzzurro
本帖最后由 LocusAzzurro 于 2020-9-8 16:18 编辑

VII.逻辑门的使用与多面体

在之前我们提到了在表达式中可以使用逻辑门,我们首先来回顾一下:&& 表示逻辑与门|| 表示逻辑或门! 加在一段表达式前表示逻辑非门
那么这些逻辑门有什么作用呢,我们来一个个看一下:
逻辑与门代表集合论中的交集,即同时属于两个或更多集合的元素,在几何中我们可以理解为同时满足多个不等式的部分
我们可以用一个例子来理解一下:如下图表示的是 y<0的区域指令
  1. //g 95:14 y<0
复制代码
http://ww3.sinaimg.cn/mw690/0062Lzp6gw1ezdxl9z6w4j311y0jlk3h.jpg

下图表示的是 x<0 的区域指令
  1. //g 95:11 x<0
复制代码

http://ww4.sinaimg.cn/mw690/0062Lzp6gw1ezdxl7b69ij311y0joqgt.jpg

那么如果我们使用逻辑与门将两个表达式连接,即
  1. y<0 && x<0
复制代码
我们表达的是两部分的交集(即y<0∩x<0),即同时满足两个不等式的区域,也可以说是两部分共有的区域。使用指令
  1. //g 95:10 y<0 && x<0
复制代码
我们会得到下面的结果:
http://ww2.sinaimg.cn/mw690/0062Lzp6gw1ezdxl16m7nj311y0jlwqc.jpg

这印证了我们刚才所说的,只有两部分(红色与蓝色的部分)共有的区域被生成了。
接下来是逻辑或门,它相当于集合论中的并集,如果我们依旧使用之前的两个不等式x<0 y<0但使用逻辑与门来连接,即
  1. x<0 || y<0
复制代码
我们表达的是两个不等式的并集(x<0∪y<0),即两个不等式的区域相加的结果,也可以说是所有包括在两个不等式的任何一个中或两个中的区域。使用指令:
  1. //g 95:10 y<0 || x<0
复制代码
我们得到的是下面的结果:
http://ww3.sinaimg.cn/mw690/0062Lzp6gw1ezdxl4i116j311y0jj4c4.jpg

可以看到,生成的区域包括了之前两个不等式所有的部分。

最后我们一起看一下逻辑非门以及多个逻辑门的使用。逻辑非门表示“不属于这个集合的部分”,即如果我们的集合是y<0,那么如果我们在它之前加上非门,即 !(y<0) (由于!符号的多种意义,建议在为需要使用非门的部分加上括号),我们表达的就是y>0 的部分(其实是y>=0,但WorldEdit不支持等式),即属于 y<0 的部分。多个逻辑门的使用即为使用多个逻辑门来表达一个特定的区域,这里需要注意的是,就像数学计算一样,先乘除后加减,先计算括号内部分,从左到右计算一样,逻辑运算也有它的规则:
同样,我们继续使用之前的两个不等式来举例,这一次我们表达的是:
  1. x<0 && !(y<0)
复制代码
表达的是x<0与非y<0的交集,我们知道我们首先需要计算非门,所以我们的表达式可以理解为:
  1. x<0 && y>0
复制代码
即为x<0 与 y>0的交集。整个表达式表达的是“x>0区域与非y<0区域共有的部分”。让我们把它写进命令里:
  1. //g 95:10 x<0 && !(y<0)
复制代码
会得到这个结果:
http://ww3.sinaimg.cn/mw690/0062Lzp6gw1ezdxkyb1n1j311y0jn153.jpg

就像我们刚才所说。
讲了那么多我们来看一个实际的例子,一个在选区中心,边长为1的正方体,我们需要先确定正方体6个面所属的平面,然后用不等式决定区域(这里需要有些3D分析能力),找到6个不等式然后将它们用 逻辑与门 && 连起来,意思就是找到这6个区域共有的区域,那个区域就是我们的正方体了

我们的正方体的8个顶点分别为:


它的六个面所属的六个平面将会分别为:

接下来将它们变为不等式


这6个不等式的空间区域的交集就是那个正方体了。我们用&&表示逻辑与门,就是交集,这样就可以把6个不等式连起来:
  1. x<0.5 && x>-0.5 && y<0.5 && y>-0.5 && z<0.5 && z>-0.5
复制代码

最后的指令就是:
  1. //g 155 x<0.5 && x>-0.5 && y<0.5 && y>-0.5 && z<0.5 && z>-0.5
复制代码

输入指令,成功生成了正方体:
http://ww1.sinaimg.cn/mw690/0062Lzp6gw1ezdxkpeo4qj311x0jo143.jpg

以上便是多面体的生成方式以及逻辑门的使用,接下来我们来通过几个例子看一看WorldEdit中函数的使用。

LocusAzzurro
本帖最后由 LocusAzzurro 于 2020-9-8 17:28 编辑

VIII.函数的使用

在表达式中我们可以使用一系列的函数,使用的方法与日常的写法相似,即函数(<输入值>),这里我们来使用几个常见的函数作为例子了解一下它们在表达式中的应用。
http://ww4.sinaimg.cn/mw690/0062Lzp6gw1ezdxnvtusaj311s0jcqiv.jpg

上图使用了
  1. //g 155 y<abs(x)
复制代码
其中abs(x)代表的便是x的绝对值
下面这个是正弦cos(x),同时使用了 -h 来仅生成正弦的曲线(什么?你想说说好的曲线呢?有两种可能,一是你没仔细看前面的,二是你三角函数没学好www)
http://ww3.sinaimg.cn/mw690/0062Lzp6gw1ezdxnylwc3j311i0jd4a0.jpg

上图使用的指令是
  1. //g 95:0 sin(x)<y
复制代码

那么为了更容易得看出曲线,我们可以对它进行一些压缩
http://ww3.sinaimg.cn/mw690/0062Lzp6gw1ezdxno5hi9j311y0jm4bm.jpg

这里我们使用了
  1. //g 95:0 sin(4*x)<y
复制代码

这样就能明显看出正弦的曲线了。
除了提到的这两个,生成时还可以使用许多其他的函数,各位可以参考前文给出的链接中的列表来了解
接下来,我们将会讲解生成时可以使用的另外两个标示,-r 与 -o 这两个标示的运作方式与之前提到的完全不同。

LocusAzzurro
本帖最后由 LocusAzzurro 于 2020-9-8 17:44 编辑

IX.源坐标的使用

现在我们来关注一下 -r 标示,它的作用是使生成时使用源坐标,简单来说,就是将整个地图视作一个巨大的立体直角坐标系,虽然生成的范围依旧会被限制在选区中,但使用指令时可以带入实际的坐标进行(即F3画面上的XYZ坐标)运算。
这样说起来可能不好理解,让我们来看一个例子吧:
http://ww2.sinaimg.cn/mw690/0062Lzp6gw1ezdxz8sdq0j311y0jgni9.jpg

我们的目标是建立一个以上图的玻璃方块位置为中心,半径为5的球体,首先我们需要得到这个玻璃方块的坐标,即(-167;30;324) (见上图左上角最后一行Looking at:)。
我们知道,三维球面的方程是(x-xc)2+(y-yc)2+(z-zc)2=r2
带入我们的中心点坐标,并加上半径5,就成了:
  1. (x+167)^2+(y-31)^2+(z-324)^2=25
复制代码
现在我们可以将它转化成不等式,来表达球体内部:
  1. (x+167)^2+(y-31)^2+(z-324)^2<25
复制代码
将其带入指令(不要忘记-r标示):
  1. //g 155 -r (x+167)^2+(y-31)^2+(z-324)^2<25
复制代码
输入指令,可以得到下面的结果:http://ww4.sinaimg.cn/mw690/0062Lzp6gw1ezdxzmkr4cj311y0jnkin.jpg

我们成功地在正确的位置生成了正确的球体(你说你弄这么一大堆就为跟我说个球?)
接着我们来看这个模式可能的另一个应用,使用三个点来生成一个平面:
http://ww1.sinaimg.cn/mw690/0062Lzp6gw1ezdxy14nu0j311y0joqb0.jpg

如上图,在空间里选择了三个点,使用羊毛标注,我们的目标是找到并生成这过这三个点的唯一平面(给出空间中三个不在同一直线的点,仅存在一个过这三点的平面)。
首先我们需要找到这三个点的坐标:
http://ww1.sinaimg.cn/mw690/0062Lzp6gw1ezdxy14nu0j311y0joqb0.jpg
http://ww1.sinaimg.cn/mw690/0062Lzp6gw1ezdyc3jl3mj311y0jj7lc.jpg
http://ww2.sinaimg.cn/mw690/0062Lzp6gw1ezdxyvpfouj311y0jmgtb.jpg



R(-177;23;230)B(-176;36;315)Y(-164;29;316)
通过计算,我们可以得到平面的方程为:
  1. -92x-181y-163z+41669=0
复制代码
接下来我们来将它带入指令
  1. //g 95:0 -r -h -92*x-181*y-163*z+41669<0
复制代码
可以看到等式转换成了不等式,并且使用了-h标示来仅生成平面,输入后我们得到的是:
http://ww2.sinaimg.cn/mw690/0062Lzp6gw1ezdxyz572pj311y0jmtsy.jpg

可以看到我们成功生成了过三点的平面,可以注意到只有这个平面在选区中的部分被生成了,也可以理解为生成了平面与选区范围的交集

LocusAzzurro
本帖最后由 LocusAzzurro 于 2020-9-8 17:43 编辑

X.移动后源坐标的使用

最后,我们来看一下-o 标示,移动过的源坐标,它与之前的-r 标示十分相似,也是使用实际地图坐标长度来进行运算,但二者的区别是-r 完完全全使用的是真实的方块坐标,但-o 模式会将玩家使用命令时所在的位置(或者玩家的第一个选择点,如果使用了/toggleplace),作为三维直角坐标系的原点
和刚才一样,我们来看一个例子:
http://ww3.sinaimg.cn/mw690/0062Lzp6gw1ezdyw7wm46j311y0jgtkv.jpg

这次我们的目标是生成一个以这个金块为中心的空心椭球,和刚才不同,我们不需要得到这个金块的坐标,而是将这个金块位置的坐标看做原点,即(0;0;0)
接着,我们在这个位置使用指令
  1. //g 95:0 -o -h x^2+(2*y)^2+z^2<100
复制代码

可以看到使用了-o 与 -h 标示,并且并没有对像刚才一样带入中心点的坐标,如此输入的结果是:
http://ww1.sinaimg.cn/mw690/0062Lzp6gw1ezdywpiwquj311y0jhqhw.jpg

从外面看的效果如下:
http://ww2.sinaimg.cn/mw690/0062Lzp6gw1ezdywks0s5j311y0jlwy5.jpg

成功生成了需要的椭球。

最后我们来看一个斜面:http://ww1.sinaimg.cn/mw690/0062Lzp6gw1ezdywxhk63j311y0jk7n9.jpg

如上图,我们在钻石块位置使用指令:
  1. //g 155 -o -h x<y
复制代码
因为x=y平面的特性,可以生成一个45度的斜面效果如下:
http://ww3.sinaimg.cn/mw690/0062Lzp6gw1ezdyx7w6ccj311y0jpwp0.jpg

整体效果:
http://ww4.sinaimg.cn/mw690/0062Lzp6gw1ezdyx4fu7sj311y0jnh0m.jpg

至此,对于指令本身的研究结束,接下来会展示一些本人收集到的一些实际的应用与实际操作例子(部分为个人研究,部分为在他人的研究之上进行的深入,部分为他人的研究)。

下一页 最后一页