【发布时间】:2016-03-06 20:35:10
【问题描述】:
我正在创建一个高度图绘制工具,它使用样条线绘制高度图,其值从 0 到 1。样条线由几个点组成,每个点都有不同的厚度(大小/宽度),并且会被插值。该工具在高度图上绘制路径的投影,其厚度由用户指定,乘以每个点的大小和用户指定的羽化。到目前为止,我已经设法实现了一切,我的实现是这样的:
取两个点(i 和 i+1)(http://i.imgur.com/PToj9ws.jpg)
找到与 (points[i+1].position-points[i].position) 的垂直线 (http://i.imgur.com/9imeDNU.jpg)
使用羽毛填充由垂直线 (http://i.imgur.com/QFfcR89.jpg) 的起点和终点定义的矩形。
为了填充这些矩形,我使用 Bresenham 线算法的变体绘制了多条线:
public void drawLine(Point fromPoint, Point toPoint, float fromValue, float toValue, ref float[,] grid)
{
int x0 = fromPoint.x, y0 = fromPoint.y, x1 = toPoint.x, y1 = toPoint.y;
int dx = Mathf.Abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
int dy = -Mathf.Abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
int err = dx + dy, e2;
int x = x0, y = y0;
Vector2 target = new Vector2(x1 - x0, y1 - y0);
while(true)
{
Vector2 current = new Vector2(x - x0, y - y0);
float addValue = Mathf.Lerp(fromValue, toValue, current.magnitude / target.magnitude);
plot(x, y, addValue, 1f, ref grid);
if (sample) grid[x, y] = supersample(x, y, ref grid);
if (x == x1 && y == y1) break;
e2 = 2 * err;
if (e2 > dy)
{
err += dy;
x += sx;
} else if (e2 < dx)
{
err += dx;
y += sy;
}
}
}
到目前为止一切顺利!然而,当样条曲线上的一个点与其他点的大小不同时,就会出现问题。由于该算法不绘制抗锯齿线,因此绘制的形状开始看起来参差不齐。发生这种情况是因为我为较大点的垂线的每个像素画了一条线,并将它们的端点映射到较小点的垂线。所以基本上线开始在更窄的点周围相互重叠。 我试图绘制一个图形来可视化问题:
所以我的最终结果是这样的:
您可以看到羽毛部分非常锯齿。
我尝试使用 Xiaolin Wu 的线条算法来绘制线条,但导致像素之间出现间隙,并且填充变得不一致。 到目前为止,仅应用高斯模糊会使事情看起来更好,但它并不能完全解决问题而且它很重,所以我也放弃了这个选项。
我确实需要在不使用任何库的情况下实现这一点,因此非常欢迎任何有关如何解决此问题的建议。谢谢!
【问题讨论】:
-
你的目标是什么:Winforms? WPF? ASP? ...?? 总是相应地标记您的问题!
-
@TaW 这是一个 Unity 项目。我正在将值写入 float[,] 数组。
标签: c# algorithm unity3d spline heightmap