【发布时间】:2019-05-02 16:29:28
【问题描述】:
好吧,我正在尝试优化我在这里所做的事情 (Smoothing noises with different amplitudes (Part 2))。
由于这个原因,我从头开始(https://youtu.be/o7pVEXhh3TI)做了一个新的实现来绘制路径:
private void Start()
{
Polygon pol = File.ReadAllText(PolyPath).Deserialize<Polygon>();
// Create tex object
var list = pol.Vertices.AsEnumerable();
tex = list.CreateTextureObject(pol.Position, offset);
exampleTexture = new Texture2D(tex.Width, tex.Height);
exampleTexture.SetPixels32(new Color32[tex.Width * tex.Height]);
exampleTexture.Apply();
vertices = pol.Vertices.Select(v => (v - pol.Position) + offset).Clone().ToList();
_ss = new List<Segment>(pol.Segments.Select(s => new Segment((s.start + pol.Center - pol.Position) + offset, (s.end + pol.Center - pol.Position) + offset)));
foreach (Segment curSeg in _ss)
for (int i = -effectDistance; i < effectDistance; ++i)
{
Vector2 perp = Vector2.Perpendicular(((Vector2)curSeg.start - (Vector2)curSeg.end)).normalized;
segments.Add((Vector2)curSeg.start + perp * i);
F.DrawLine((Vector2)curSeg.start + perp * i, (Vector2)curSeg.end + perp * i, (x, y) => layers.Add(new Point(x, y)));
}
Debug.Log("Layer Count: " + layers.Count);
drawPath = true;
}
private void OnGUI()
{
if (exampleTexture == null)
return;
GUI.DrawTexture(new Rect((Screen.width - tex.Width) / 2, (Screen.height - tex.Height) / 2, tex.Width, tex.Height), exampleTexture);
if (drawPath)
{
{
Point? cur = layers.Count > 0 ? (Point?)layers.First() : null;
if (cur.HasValue)
{
exampleTexture.SetPixel(cur.Value.x, cur.Value.y, new Color32(170, 0, 0, 255));
exampleTexture.Apply();
layers.Remove(cur.Value);
}
}
{
Point? cur = segments.Count > 0 ? (Point?)segments.First() : null;
if (cur.HasValue)
{
exampleTexture.SetPixel(cur.Value.x, cur.Value.y, new Color32(0, 170, 0, 255));
exampleTexture.Apply();
segments.Remove(cur.Value);
}
}
{
Point? cur = vertices.Count > 0 ? (Point?)vertices.First() : null;
//Debug.Log(cur);
if (cur.HasValue)
{
exampleTexture.SetPixel(cur.Value.x, cur.Value.y, new Color32(255, 128, 0, 255));
exampleTexture.Apply();
vertices.Remove(cur.Value);
}
}
if (vertices.Count == 0 && segments.Count == 0 && layers.Count == 0)
drawPath = false;
}
}
这就是 DrawLines 的实际作用:
public static class F
{
public static void DrawLine(Point p1, Point p2, Action<int, int> action)
{
DrawLine(p1.x, p1.y, p2.x, p2.y, action);
}
public static void DrawLine(int x0, int y0, int x1, int y1, Action<int, int> action)
{
int sx = 0,
sy = 0;
int dx = Mathf.Abs(x1 - x0),
dy = Mathf.Abs(y1 - y0);
if (x0 < x1) { sx = 1; } else { sx = -1; }
if (y0 < y1) { sy = 1; } else { sy = -1; }
int err = dx - dy,
e2 = 0;
while (true)
{
action?.Invoke(x0, y0);
if ((x0 == x1) && (y0 == y1))
break;
e2 = 2 * err;
if (e2 > -dy)
{
err = err - dy;
x0 = x0 + sx;
}
if (e2 < dx)
{
err = err + dx;
y0 = y0 + sy;
}
}
}
}
这是Bresenham algorithm 的实现。
这个实现更好,因为我将迭代次数从 280k 降低到了 6k,但是有一个问题,你可以看到这是不准确的......
首先工作的方法是获取形状上每个线段的垂直线(绿色像素),然后在该线段的起点和终点之间画线。使用Ramer-Douglas-Peucker algorithm 获取分段。
所以我正在考虑以螺旋方式绘制“橙色”路径。我不知道如何解释这一点,基本上,获得了相同的路径,但是有一个规模(Translating/transforming? list of points from its center with an offset/distance),但我认为我会有同样的错误。
任何指南将不胜感激。我可以使用什么算法来绘制带有“层”的路径?
【问题讨论】:
-
尝试用它来绘制一个膨胀的形状 N 次,随着膨胀程度的降低,然后绘制原始形状。然后,您将拥有一个从原始形状向外的 N 步渐变。
-
我想我喜欢 Clipper,这和我之前的问题给出的结果相同:i.gyazo.com/a33f553d79aba52811b08986d8bcc784.png 我会调试它以知道它做了多少次迭代。
-
好吧,多边形偏移比我的方法更有效一点...但是:i.gyazo.com/4899a6278d3f002f148179cc844f7c21.png
-
@Ruzihm 有问题。现在,我需要一个与 Unity3D 的 AddPath 和 FilPath(来自 Graphics2D)相同的方法......
标签: c# unity3d computational-geometry bresenham douglas-peucker