0 → Top Left
1 → Bottom Left
2 → Top Right
3 → Bottom Right
4 → Top Left
5 → Bottom Left
6 → Top Right
7 → Внизу справа
...
Каждая группа состоит из 4 прямоугольников с последовательными показателями, начиная с кратных 4 (то есть, индексы 0–3, 4–7, 8–11 и т. Д.).
Роли, назначенные индексом % 4, повторяйте в каждой группе. Несмотря на то, что сама роль определяется исключительно по индексу, фактическая позиция прямоугольника, как ожидается, будет визуально соответствовать этой роли (например, прямоугольный прямолинейный взгляд на верхнюю левую в своей группе). < /P>
Последняя группа может содержать менее 4 прямоугольников, если длина списка не делится на 4. Это не рассматривается по ошибке, пока все еще не будет осмотрительно. Это исключение относится только к окончательной группе на основе длины списка ввода. < /P>
шаблон повторяется каждые 4 элемента. Однако прямоугольники в сборе ввода уже могут быть неправильно расположены. Верхний левый прямоугольник помещается там, где должен быть прямоугольный прямоугольник). < /P>
Допустимый диапазон движения каждого прямоугольника определяется не только путем предотвращения прямого перекрытия с соседями, но также и дополнительным правилом:
не должно пересекать линии расширенной оси (x-ax-ax ax ax ax ax. < /P>
horizontal mails): < /p>
horizontal mails). Горизонтально, пока он не пересекает вертикальные граничные линии своих горизонтальных соседей: < /p>
Слева: она не должна пересекать вертикальную линию, простирающуюся от правого края левого соседа. < /p>
Право: не должна пересекать версическую линию, выходящую от левого края правого соседа. (Ось Y):
прямоугольник может двигаться вертикально только до тех пор, пока он не пересекает горизонтальные граничные линии своей вертикальной пары (верхняя /нижняя пара): < /p>
Движение вниз: она не должна пересекать горизонтальную линию, расширяющуюся от верхней части нижней пары. его верхняя пара. < /p>
Другими словами, прямоугольник никогда не должен пересекать воображаемые границы, выравниваемые осью, даже если сами прямоугольники не касаются физически. Ограничение: не может пересечь горизонтальную ось, простирающуюся от края пары.
прямоугольники могут варьироваться по размеру, они не обязаны быть равномерными. Это учитывается в логике: все валидация положения основана на краях и ограничениях, выравниваемых осью (не фиксированными измерениями). Прямоугольник считается недействительным, только если он пересекает расширенные граничные линии соседа, независимо от его размера. < /P>
Я пишу приведенный ниже код. В настоящее время моя функция идентифицирует, когда два прямоугольника нарушают ограничение оси (например, один перекрывает другой вдоль x или y). Но в таких случаях он помечает оба прямоугольника - тот, который остался в правильном положении, и тот, который фактически перемещался в пространство другого. < /P>
Однако это поведение не идеально. Я хотел бы просто пометить прямоугольник, который вторгся в зону оси другого. < /P>
Код: Выделить всё
public List GetInvalidRectIndexes(List rects)
{
List invalidIndexes = new List();
for (int i = 0; i < rects.Count; i++)
{
if (!IsValidPosition(i, rects))
invalidIndexes.Add(i);
}
return invalidIndexes;
}
private bool IsValidPosition(int index, List rects)
{
var rect = rects[index];
int role = index % 4;
var pos = GetEdges(rect);
RectModel leftNeighbor = (index - 2 >= 0) ? rects[index - 2] : null;
RectModel rightNeighbor = (index + 2 < rects.Count) ? rects[index + 2] : null;
int pairIndex = (role == 0 || role == 2) ? index + 1 : index - 1;
RectModel pair = (pairIndex >= 0 && pairIndex < rects.Count) ? rects[pairIndex] : null;
// X constraint
if (leftNeighbor != null)
{
var left = GetEdges(leftNeighbor);
if (pos.Left < left.Right)
return false;
}
if (rightNeighbor != null)
{
var right = GetEdges(rightNeighbor);
if (pos.Right > right.Left)
return false;
}
// Y constraint
if (pair != null)
{
var pairPos = GetEdges(pair);
if (role == 0 || role == 2) // Top*
{
if (pos.Bottom > pairPos.Top)
return false;
}
else if (role == 1 || role == 3) // Bottom*
{
if (pos.Top < pairPos.Bottom)
return false;
}
}
return true;
}
private class Edges
{
public double Left, Right, Top, Bottom;
}
private Edges GetEdges(RectModel rect)
{
var x = rect.X;
var y = rect.Y;
var w = rect.Width;
var h = rect.Height;
return new Edges
{
Left = x,
Right = x + w,
Top = y,
Bottom = y + h
};
}
private List _rectangles = new();
public List Rectangles
{
get => _rectangles;
set { _rectangles = value; }
}
public class RectModel : ViewModelBase
{
private double _x, _y, _width, _height;
private SolidColorBrush _color;
private int _index;
public int Index
{
get => _index;
set { _index = value; OnPropertyChanged(nameof(X)); }
}
public double X
{
get => _x;
set { _x = value; OnPropertyChanged(nameof(X)); }
}
public double Y
{
get => _y;
set { _y = value; OnPropertyChanged(nameof(Y)); }
}
public double Width
{
get => _width;
set { _width = value; OnPropertyChanged(nameof(Width)); }
}
public double Height
{
get => _height;
set { _height = value; OnPropertyChanged(nameof(Height)); }
}
public SolidColorBrush Color
{
get => _color;
set { _color = value; OnPropertyChanged(nameof(Color)); }
}
}
var invalidIndices = GetInvalidRectIndexes(Rectangles);
for (int i = 0; i < Rectangles.Count; i++)
{
Rectangles[i].Color = invalidIndices.Contains(i) ? Brushes.Red : Brushes.Green;
}
< /code>
Вот 2 тестовых входа для метода.
Этот первый - пример, показывающий, как входные прямоугольники выглядят, когда они правильно расположены. Это просто ссылка на понимание того, каким будет компоновка, когда все прямоугольники находятся в их допустимых позициях. < /P>
var validRectangles = new List
{
new RectModel { X = 80, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 80, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 250, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 250, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 460, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 460, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 640, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 640, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 830, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 830, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 1000, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 1000, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 1220, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 1220, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 1380, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 1380, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 1580, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 1580, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 1730, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 1730, Y = 720, Width = 130, Height = 150 }
};
, на основе Logic, с приведенным ниже примером. 11 < /p>
Причины: < /p>
Индекс 2 скрещивается влево над осью правого края своего левого соседа (то есть, он нарушает вертикальную границу левого соседа). < /P>
Индексы 1 и 14 заменяются - их позиции - это то, где, как следует, то, где, как следует, то, где, то есть, то, где, то, что нужно, то есть, что нужно, то вершина ». BE, и наоборот). < /p>
Индекс 6 пересекается вправо над осью левого края своего правого соседа (то есть, он нарушает левую вертикальную границу правого соседа). < /p>
Индексы 15 и 11 разбиваются, нарушая ожидаемый циклический порядок.var testRectangles = new List
{
new RectModel { X = 80, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 1380, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 100, Y = 55, Width = 130, Height = 150 },
new RectModel { X = 250, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 460, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 460, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 740, Y = 475, Width = 130, Height = 150 },
new RectModel { X = 640, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 830, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 830, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 1000, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 1380, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 1220, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 1220, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 80, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 1000, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 1580, Y = 275, Width = 130, Height = 150 },
new RectModel { X = 1580, Y = 720, Width = 130, Height = 150 },
new RectModel { X = 1730, Y = 275, Width = 130, Height = 150 }
};
< /code>
Визуально с неверными прямыми:
Как я могу улучшить логику, чтобы отметить только то, что прямое, что например, что -то, если это то, что правильно, - это то, что правильно, - это то, что правильно, - это то, что правильно, - это то, что правильно, - это то, что правильно, и то, что она нарушает? B пересекается в область A, только B должен быть помечен, а не оба. макет - а затем только отмечает неправильный? Благодарность.
Подробнее здесь: https://stackoverflow.com/questions/796 ... axis-based