绘制简单地图
我正在尝试绘制一张泥土的地图。我使用了Python和Graphviz,得到了像这样的东西:
http://img23.imageshack.us/img23/5222/arrasz.png
你可以看到,我们有一些地点,向北、南、西、东、上、下移动就能到达其他地点。
请问,使用Graphviz能否绘制出这样的地图,让北方的地点在上面,东方的地点在西方地点的右边?
我想要的效果是这样的:
some --- E ---> some
location <--- W --- location 2
.
/ \ |
| |
N S
| |
\ /
`
some location 3
或者,也许有比Graphviz更好的工具可以自动绘制这个地图?
4 个回答
你可以使用 节点等级 来强制每个节点的垂直位置。这可以确保节点在南北方向上是按正确的顺序排列的。你需要先处理一下MUD地图,以确定每个节点的等级。你可以把一组节点标记为“同一”等级。接着,你要分析MUD地图,找出哪些房间节点在南北方向上处于同一水平线上。举个例子:
R1 R2
| |
R3 -- R4--R5
对于这个地图,你可以这样做:
digraph M {
R1->R3;
R2->R4;
R3->R1;
R3->R4;
R4->R2;
R4->R5;
{rank=same;R1;R2}
{rank=same;R3;R4;R5}
}
不过,我找不到强制水平排列的方法。这意味着东西方向的节点可能还是不能正确对齐。一旦你设置好了等级,其他房间会提供一些上下文,这样大约90%的情况下会有效。
我觉得子图(可以参考dotguide第23页)和等级属性(可以参考dotguide第17页)可能是更好地组织图形的方法。
以下是一些可能替代Graphviz的工具:
http://gephi.org/提供了一些python接口,更新的版本甚至支持在应用程序内使用python作为脚本语言。
http://ubietylab.net/ubigraph/index.html可以生成漂亮的3D图形,并且可以通过python进行控制。
之前有人问过关于改进Graphviz布局的问题,但我觉得在这里使用Graphviz有点过于复杂了。
如果你有一个标准的MUD布局,比如下面这个:
那么你就有一些相当严格的限制,关于房间的位置。Graphviz并不知道这些限制,所以它的效果可能不如一个简单的算法,比如:
- 在网格上选择一个起始位置
- 使用例如深度优先遍历的方法遍历每个房间
- 每到一个新房间,就向北、南、东或西移动一个单位
如果你不想写可视化的代码,你可以(也许)把上述方法作为Graphviz的预处理步骤,利用它来为每个房间分配等级。然后(希望)Graphviz就能生成正确的输出。
编辑:比如,下面是一些伪代码:
visit(initialRoom, 0, 0)
def visit(curRoom, curX, curY)
if curRoom == null return
print "in room " + curRoom + " at location " + curX + ", " + curY
visit(curRoom.northNeighbor, curX, curY-1)
visit(curRoom.southNeighbor, curX, curY+1)
visit(curRoom.westNeighbor, curX-1, curY)
visit(curRoom.eastNeighbor, curX+1, curY)