好吧,我正在尝试优化我在这里所做的工作(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),但是我想我将拥有相同的无知感。
任何指南将不胜感激。我可以使用哪种算法绘制带有“图层”的路径?
答案 0 :(得分:1)
Following some of the information here,您也许可以使用“向内/向外多边形偏移”(也称为“多边形缓冲”)来获得您感兴趣的结果。
诸如Clipper之类的工具可以提供帮助。
一旦可以向外偏移形状,请执行以下操作:
首先,绘制外形(下面的黑色区域),然后向外偏移内部形状,直到达到需要为止,然后使用适当的噪点/颜色将其绘制在外形顶部(下面的棕色区域)方案:
然后,应用较小的偏移,然后使用其他噪声/颜色方案(在下面的橙色区域)在顶部绘制该形状。
重复操作,直到您拥有所需的渐变为止:
最后,绘制其内部形状,使其噪声/配色方案没有任何偏移: