佛罗伦萨飓风的12月消息经常提到
外部浅滩 -北卡罗莱纳州沿海的一系列隔离岛:
障壁岛是由波浪形成的平坦或块状的沙块,沿着与大陆海岸平行的方向冲浪。 它们通常采用长链的形式,可以延伸数十英里。 屏障岛通常被小潮汐通道隔开,并可能在这些岛与大陆之间形成泻湖。
根据
Wikipedia的介绍 ,障碍岛可以覆盖多达15%的海岸,因此您可以期望在大多数幻想地图上看到它们,但实际上它们很少见。 由于噪声的性质,它们几乎永远不会发生在使用噪声创建地形的程序生成的地图上。
要了解为什么会这样,让我们看一下岛上的香草地图:
实际上,这是一个圆,由于添加了少量低频噪声而使圆分裂,从而使圆变形。 现在,让我们尝试使用噪声来破坏海岸并形成沿海岛屿。 这是一个包含低频噪声的孤岛:
它有海湾和海角。 由于我使用的低频噪声变化缓慢,因此浮雕元件相当大。 但是,噪音不足以产生孤岛。 让我们推一下:
现在我们已经创建了几个岛屿,但是它们本质上是圆形的斑点,不一定沿着海岸伸展。 您可以添加高频噪声:
这会给我们非常破碎的海岸线和沿海岸的小岛,但没有什么像隔离岛。
这样做的唯一原因是,噪声在x和y中不匹配,因此尽管噪声通常不是随机的,但它创建的形状是随机的:
在某些方面,这很好,但不适用于创建特定形式,例如,沿海岛屿。
与其他情况一样,当我需要生成特定形状或区域时,有必要创建所需形状的蒙版,然后使用蒙版内部的噪声。 (您也可以使用噪声使蒙版变形并赋予其更自然的形状。)实际上,隔离岛是从海岸偏移的细长区域。 因此,让我们创建这种形状的蒙版。
首先,我们将设置障碍岛所在的海岸部分。 可以通过选择海岸上的一个随机点和第二个下点来完成,这些点在图中用右上角的红线标记:
要开始创建屏障岛,我只需在这两点之间画一条直线,然后将其稍微向外投射到水中即可。 这会给我一个非常笔直且看起来不自然的岛,但是您可以扭曲它的形状以隐藏它。 真正的问题是该岛不会跟随海岸线。 对于大多数直接的沿海地区来说,它看起来可能是正常的,但是在蜿蜒的海岸上,它似乎很奇怪。 最好复制海岸线并将其作为岛屿形状的基础。
为此,我需要创建海岸线的副本,然后将其投影到垂直于海岸线的海洋中。 因为我意识到
手写线 ,所以我已经有了一个计算折线的垂直线(法线)的过程,并且海岸线总是沿相同的方向移动,因此非常简单:
或者
看起来很简单。 让我们看看如果我在海岸线的较不光滑的部分上将海岸线向外侧进一步投影(以创建岛的蒙版的另一面)会发生什么情况:
投影线的两个线段彼此相交,并在多边形上创建了一个令人恐惧的“八”字形。 这就是所谓的
平行曲线问题 。 我们不能仅仅将海岸移开一段距离,还必须解决由于尖锐的内外角而引起的问题。
我一直在寻找Javascript代码来解决此问题,但即使在相当简单的示例上,(
从这里开始 )发现的唯一示例也令人惊讶地崩溃。 所以我写了我自己的。 通常,解决方案是沿法线移动每个点,然后检查新点是否创建了一条与任何现有线相交的线。 如果是这样,则我们切断循环并插入由交点和新点组成的新线。 在我测试的测试用例中,该系统可以很好地满足我的要求。
现在,我可以为这些岛生成简单的蒙版了(没有循环):
这太均匀了,所以我会扭曲轮廓:
轮廓线可能在某些点接触海岸,但这是正常现象;通常在障碍岛上发现。
下一步是用土地填充轮廓,但是在执行此操作之前,我想使这些岛变长,并增加在同一海岸线上创建多个障碍岛的情况下避免相交的岛的逻辑。
现在,让我们尝试添加一些土地。 为此,我将提高海拔以上任何陆地位置(即Delaunay三角形)的高度:
有两个方面值得注意。 首先,在左上角有一个相当成功的屏障岛。 但是,该岛似乎并未很好地填满垃圾填埋场。 由于多边形内部存在许多中心三角形,因此它们处于“打开”状态。 这为岛的形状增加了随机性。 其次,人们可以注意到其他两个岛屿离海岸如此近,以至于它们只是与海岸融为一体。 由于我想在这里创建岛屿,所以我不需要经常这样做,所以我将设置一代以在海岸线和岛屿之间增加水位。 (稍后我将添加检查以防止这种情况发生。)
关于陆地不规则三角形的一件好事是,它们自然地形成了屏障岛特有的潮汐管道。 关于它们的坏处是它们通常会创建斑点岛,看起来像是一串扭曲的珍珠。 它们与障碍岛不太相似,如果您使用很多单个三角形,它们看起来会很不自然。
如果我增加岛屿的宽度,两种影响都会消失,我会获得更多的自然岛屿,但没有潮汐通道:
但是我想学习如何产生非常狭窄的岛屿。 另一种方法是(显着)增加世界上的位置数量以提高分辨率:
这样我们就可以得到令人印象深刻的细小岛,但它显着增加了创建地图所需的时间和内存。
在这两种方法中,岛上的某些部分很有可能会非常不平坦:
发生这种情况是因为路径与基础Delaunay三角形的两个边(有时是所有三个边)相交。 这是在地图生成中使用Delaunay三角剖分的固有问题,但是由于某些原因,他们很少讨论它! 在我的游戏中,这种情况很少发生在海岸线上,因为为了减少此类情况的发生,我故意添加了平滑阶段,但是此阶段往往会破坏狭窄的岛屿。 潜在的解决方案是创建稍微宽一些的岛并使用抗锯齿功能-如果设置正确,则可以得到较薄的岛,而不会出现很多三角形伪像:
但是,使用这种方法,岛的狭窄程度仍然存在限制。 此外,这意味着我们永远不会获得真正的分形海岸线。
有时,平滑算法会导致将长的障碍岛分割成几个小的障碍岛(如上图的左下角所示),但是拥有一个可以强制执行此操作的选项将很方便:
剩下的唯一一件事就是给这些岛起个名字并映射它们。 这里唯一微妙的方面是,我不想为障碍岛链中的所有岛屿取名字。 在障碍岛的真实链条中,各个岛屿通常都有名称,这会导致地图上的混乱:
因此,在创建障碍岛时,我会考虑整个弧并为其添加一个名称,即使结果是这一代将弧分成几个岛:
通常,障碍岛被称为“堤岸”或“竖井”(条形),因此这些词可在变体名称中找到。
此示例显示了潜在的障碍岛问题:
这里的屏障岛是在海湾内部创建的。 这是不合逻辑的(此外,导致名称的交集)。 为了避免这种情况,我可以使用
海湾识别逻辑 ,并跳过海岸线的这些部分。 此方法可能无法防止傻瓜,但是此卡非常有效: