我正在观看此视频:Delaunay Triangulation我希望以同样的方式使用它来生成程序内容。我很难弄清楚如何使用DelaunayTriangulation
提供的LibGDX
类,但我想我终于明白了。
然而,我的问题是如何以简单的方式知道哪一点与哪个点相关?这就是我目前设置测试点的方法,这些点最终需要由生成的房间提供。
private void TriangleTest()
{
DelaunayTriangulator triangulator = new DelaunayTriangulator();
points = new float[8];
points[0] = 80;
points[1] = 30;
points[2] = 40;
points[3] = 45;
points[4] = 0;
points[5] = 10;
points[6] = -100;
points[7] = 100;
indices = triangulator.computeTriangles(points, false);
System.out.println(indices);
//Output [1, 0, 2, 1, 2, 3]
}
这就是我绘制点和线/三角形的方式,仅用于可视化和理解。
private void DrawTriangles()
{
//Draw points
for (int i = 0; i < points.length / 2; i++)
{
DebugHelper.DrawDebugPoint(new Vector2(points[i * 2], points[i * 2 + 1]), camera.combined);
}
//Draw lines
for (int i = 0; i < indices.size / 3; i++)
{
Vector2 v1 = new Vector2(points[indices.get(i * 3) * 2],
points[indices.get(i * 3) * 2 + 1]);
Vector2 v2 = new Vector2(points[indices.get(i * 3 + 1) * 2],
points[indices.get(i * 3 + 1) * 2 + 1]);
Vector2 v3 = new Vector2(points[indices.get(i * 3 + 2) * 2],
points[indices.get(i * 3 + 2) * 2 + 1]);
DebugHelper.DrawDebugLine(v1, v2, camera.combined);
DebugHelper.DrawDebugLine(v2, v3, camera.combined);
DebugHelper.DrawDebugLine(v3, v1, camera.combined);
}
}
假设我正确使用此功能(正确绘制了点和三角形)我正在绘制双线:
[1, 0, 2] //1st indices (2nd point connects to 1st point)
[1, 2, 3] //2nd indices (1st point connects to 2nd point)
那么有什么方法可以过滤掉这些吗?因为我只对连接感兴趣而不是实际上并排绘制三角形来生成网格。
此外,在the video I mentioned on top中你注意到有一些线被删除,以便在电影中50秒内有一些死亡结束。这是怎么计算的?有些也变色了,它留下了死胡同和循环的混合物。我很想知道如何实现这一目标。
答案 0 :(得分:2)
我是原始问题中链接的视频的作者。视频中演示的源代码可在此处找到:https://bitbucket.org/NathisGreen/pcgdungeons
这是我大学最后一年的一部分,所以我有一份详细的报告,解释了整个过程的工作原理,可以在这里阅读: http://www.nathanmwilliams.com/files/AnInvestigationIntoDungeonGeneration.pdf
第2.3.2节和第4.1节涉及这里讨论的Delaunay三角剖分。
但基本上所有发生创建最终图形的事情,都是找到由三角剖分产生的图形的最小生成树,然后将原始图形中的一些边缘随机地添加到最小生成树图形中。 / p>
答案 1 :(得分:1)
您似乎只想计算生成三角形的边集。因此,您只需创建一个Edge
类,其中包含两个特殊属性:
equals
方法返回true
即使要比较的边缘的顶点被交换(这样边缘(2,1)
将被视为与边缘{{“相等”{ 1}})(1,2)
方法的实施方式与此hashCode
实施方式一致,如Object#hashCode文档中所述:
如果两个对象根据equals(Object)方法相等,则对两个对象中的每个对象调用hashCode方法必须生成相同的整数结果。
equals
对象可以简单地放入Edge
,Set
将处理其余的:即使添加了“重复”边,该集最终也会包含每个边缘只有一次。
Set
上述程序将打印
import java.util.LinkedHashSet;
import java.util.Set;
public class DelaunayEdges
{
public static void main(String[] args)
{
int triangleIndices[] = new int[] { 1, 0, 2, 1, 2, 3 };
Set<Edge> edges = computeEdges(triangleIndices);
System.out.println("Edges: "+edges);
}
static class Edge
{
private final int vertex0;
private final int vertex1;
public Edge(int vertex0, int vertex1)
{
this.vertex0 = vertex0;
this.vertex1 = vertex1;
}
@Override
public String toString()
{
return "("+vertex0+","+vertex1+")";
}
@Override
public int hashCode()
{
return vertex0 ^ vertex1;
}
@Override
public boolean equals(Object object)
{
if (this == object)
{
return true;
}
if (object == null)
{
return false;
}
if (getClass() != object.getClass())
{
return false;
}
Edge that = (Edge) object;
return
(this.vertex0 == that.vertex0 &&
this.vertex1 == that.vertex1) ||
(this.vertex0 == that.vertex1 &&
this.vertex1 == that.vertex0);
}
}
private static Set<Edge> computeEdges(int triangleIndices[])
{
Set<Edge> edges = new LinkedHashSet<Edge>();
for (int i=0; i<triangleIndices.length; i+=3)
{
int i0 = triangleIndices[i+0];
int i1 = triangleIndices[i+1];
int i2 = triangleIndices[i+2];
edges.add(new Edge(i0, i1));
edges.add(new Edge(i1, i2));
edges.add(new Edge(i2, i0));
}
return edges;
}
}
因此,省略边Edges: [(1,0), (0,2), (2,1), (2,3), (3,1)]
,因为它被认为等于边(1,2)
。
(当然,人们可以将这个集合转换回普通的(2,1)
边缘索引数组,但这不是问题的重点)
答案 2 :(得分:0)
IMO无法知道何时没有解释或示例代码。但是可以使用轮廓线作为迷宫。以下是如何将其与最小生成树(https://twitter.com/nathanpie/status/435558377964318720)一起使用的说明。 BTW。 delaunay三角剖分是最小生成树的超集。