我已经搜索了一段时间,无法找到任何令人满意的答案。
目前我有一个tile列表(一个表示tile id的int数组),width和height(在tiles中)。当我渲染它时,所有的瓷砖都正确放置,等等。但我真正的问题是我无法找出一个算法来从内到外计算给定半径(相对于另一个瓷砖)内的瓷砖。我打算用它来进行照明计算。这就是为什么我需要从内到外计算(对于渐变)。我不能在x和y上使用+和 - 来进行静态计算,因为我打算使用可变半径大小。有谁知道这样做的好方法?
编辑:“从内到外”是指照明布局的方式,在光源附近,照明应该比远处的照明更加强烈。使用以下ASCII格式我打算用肉眼显示:0 0 0 0 0 0 0
0 0 --------- 0 0
0 | * + * | 0
0 | + x + | 0
0 | * + * | 0
0 0 --------- 0 0
0 0 0 0 0 0 0
提前致谢:)
答案 0 :(得分:1)
关于如何实施这一点的细节当然有很多不同的选择。你没有确切地告诉你如何代表你的“瓷砖”(例如关于接口)。但这是一种方法,也许它已经有所帮助:
我们的想法是将瓷砖的坐标存储为Point
个对象的列表。 (将这些点转换为1D索引是可能的,但应该完全独立于实际问题)。
这些点是通过沿着所讨论区域的“边缘”行走来计算的:
dx=0, dy=-1
)dx=-1, dy=0
)dx=0, dy=1
)dx=1, dy=0
)所有这些点都放入一个列表中,然后按逆时针顺序包含所有对中心点有Manhattan Distance的点。
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
public class TileDistances
{
public static void main(String[] args)
{
int sizeX = 11;
int sizeY = 11;
int centerX = 5;
int centerY = 5;
for (int radius=1; radius<5; radius++)
{
System.out.println(
"Radius "+radius+" around "+centerX+","+centerY);
List<Point> points = coordinates(centerX, centerY, radius);
char c = (char)('0'+radius);
System.out.println(createString(points, sizeX, sizeY, c));
}
}
private static String createString(
List<Point> points, int sizeX, int sizeY, char c)
{
StringBuffer sb = new StringBuffer();
for (int y=0; y<sizeY; y++)
{
for (int x=0; x<sizeX; x++)
{
Point p = new Point(x,y);
if (points.contains(p))
{
sb.append(c);
}
else
{
sb.append(".");
}
}
sb.append("\n");
}
return sb.toString();
}
private static List<Point> coordinates(
int cx, int cy, int r)
{
List<Point> coordinates = new ArrayList<Point>();
int steps = r + r;
addAll(cx + r, cy + r, 0, -1, steps, coordinates);
addAll(cx + r, cy - r, -1, 0, steps, coordinates);
addAll(cx - r, cy - r, 0, 1, steps, coordinates);
addAll(cx - r, cy + r, 1, 0, steps, coordinates);
return coordinates;
}
private static void addAll(
int x0, int y0, int dx, int dy, int steps,
List<Point> coordinates)
{
int x = x0;
int y = y0;
for (int i=0; i<steps; i++)
{
coordinates.add(new Point(x,y));
x += dx;
y += dy;
}
}
}
在此示例中,将打印半径1到4,例如:
Radius 3 around 5,5
...........
...........
..3333333..
..3.....3..
..3.....3..
..3.....3..
..3.....3..
..3.....3..
..3333333..
...........
...........
(可能会有更高效和/或更优雅的解决方案,具体取决于瓷砖的确切表示方式,但我认为这个很容易理解并且通用,因为它只提供一组坐标,并且不对基础数据结构做出假设。