Рисование точек вдоль пути по спирали
Ну, я пытаюсь оптимизировать то, что я сделал здесь ( сглаживание шумов с разными амплитудами (часть 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;
}
}
}
}
Это реализация алгоритма Брезенхэма.
Эта реализация лучше, потому что я снизил количество итераций с 280 КБ до 6 КБ, но есть проблема, как вы можете видеть, что это неточно...
Сначала это работает, получая перпендикуляр каждого сегмента фигуры (зеленые пиксели), а затем рисуя линии между начальной и конечной точкой этого сегмента. Сегменты получают с использованием алгоритма Рамера-Дугласа-Пекера.
Вот я и подумала нарисовать "оранжевый" путь по спирали. Я не знаю, как объяснить это, в основном, получая тот же путь, но со шкалой ( перевод / преобразование? Список точек из его центра со смещением / расстоянием), но я думаю, что у меня будет такая же неточность.
Любое руководство будет оценено. Какой алгоритм я мог бы использовать, чтобы нарисовать путь со "слоями"?
0 ответов
Следуя некоторой информации, приведенной здесь, вы можете использовать "смещение полигонов внутрь / наружу" (также называемое "буферизация полигонов"), чтобы получить интересующий вас результат.
Может помочь такой инструмент, как Clipper.
Как только у вас появится способ сместить внешнюю форму, сделайте следующее:
Сначала нарисуйте внешнюю форму (черная область снизу), затем сместите внутреннюю форму наружу настолько, насколько вам нужно, и нарисуйте ее поверх внешней формы (коричневая область ниже), используя соответствующую схему шума / цвета:
Затем примените меньшее смещение, затем нарисуйте эту форму сверху, используя другую схему шума / цвета (оранжевая область ниже).
Повторяйте, пока у вас не будет столько градиентов, сколько вам нужно:
Наконец, нарисуйте внутреннюю форму без какого-либо смещения с помощью шумовой / цветовой схемы: