http://www.redblobgames.com/articles/visibility/
这是第一部分:
计算墙壁开始或结束的角度。
沿着每个角度从中心投射光线。
填写由这些光线生成的三角形。
我正在做这样的事情:
vector<float> angles;
for(int i = 0; i < polygonCoordinates.size(); i++)
{
for(int j = 0; i < polygonCoordinates[i].size(); j++)
{
angles.push_back(AngleBetweenPoints(LIGHT_POSITION, polygonCoordinates[i][j]));
}
}
其中polygonCoordinates是一个2D矢量,基本上每个多边形都是Point2D结构的矢量,所有多边形都在一个更大的矢量内。所以我找到角度之后,我该如何进行?为什么我需要光线投射?这将如何帮助我生成“浅多边形”?
答案 0 :(得分:6)
首先要做的事情:将角度及其对应的顶点从最小到最大排序。
从你的观众'瞄准'开始向左开始,并在tmpPoint或类似的地方存储最近的可见点(恰好在墙上)。
然后,浏览您计算的角度列表。您将顺时针扫描整个屏幕区域(通过迭代排序角度列表来执行此操作)。您正在测试的第一条光线是小矩形的左下角(它具有您计算的最小角度)。最近的可见点位于左侧墙壁的某处。您可见的三角形列表,添加查看器形成的三角形,tmpPoint和您刚刚找到的点。 (见图) 最后,将该点存储在tmpPoint中。
我们检查的下一个点是小矩形的左上角。这是我们真正需要检查可见性的地方。最近的点是可见的点。 (见图)然后,添加你的三角形(再次由刚刚找到的点,观察者和tmpPoint组成)。只需反复重复此过程,您最终将使用代表可见性的三角形填充整个屏幕。
我希望这会有所帮助。我做了一些不错的伪代码,但我做错了,所以这里只是图形。 :P
编辑:
所以你计算出你的垂直数组,并且通过计算我的意思是光线的可见性。你做的是几乎像这样的事情:
for(int i = 0; i < calculatedVertices.size()-1; i++) {
triangle t = triangle(
calculatedVertices[i],
calculatedVertices[i+1],
centerViewer);
triangleArray.add(t);
}
//the loop above misses one triangle, so just add the last one
triangle final = triangle(
calculatedVertices[0]
calculatedVertices[calculatedVertices.size()-1],
centerViewer);
triangleArray.add(final);
除了一个可怕的问题外,这几乎完全有效:
你看,当你有一个远墙投射三角形时,交叉点应该出现在墙上,但是当你将三角形投射到矩形时,交叉点应该出现在矩形本身上。如果交叉点不以这种方式发生,则会发生这种情况:
我不完全确定这是否是一个实际问题,或者它只是我正在考虑的问题,但是你能解决它的一种方法是向你的另一个顶点添加一个轻微的偏差(你的交叉点检测) , 如果你明白我的意思。这应该解决这个问题。