Координаты относительно других координат
Хочу получить массив, где нулевой элемент это Абсолютные координаты, а следующие это координаты относительно предыдущих. Изменяя координаты в одной ячейке должны изменятся все следующие.
| Хранятся в массиве | Считывается из массива |
|---|---|
| [10:5][1:1][2:4][2:2] | [10:5][11:6][13:10][15:12] |
Как мне написать структуру координаты что бы такое было возможно?
Мой псевдокод
struct Coordinats
{
int x,y;
ref относительноКоординат;
public int X
{
get => относительноКоординат is null? x : x + относительноКоординат.X;
set => x = value;
}
public int Y
{
get => относительноКоординат is null? y : y + относительноКоординат.Y;
set => y = value;
}
public Coordinats(int x, int y)
{
this.x = x;
this.y = y;
}
public Coordinats(int x, int y, ref относительноКоординат)
{
this.x = x;
this.y = y;
this.относительноКоординат = относительноКоординат;
}
}
Ответы (1 шт):
С ref struct такое вряд ли получится реализовать. Потому что видимость экземпляров этих структур оказывается больше области (scope) их определения - вы же собираетесь хранить их в массиве (коллекции).
Тут нужно либо на классы переходить. Либо создать специальную коллекцию с желаемым поведением.
Навскидку код может быть таким:
public readonly struct Coordinate
{
public int X { get; }
public int Y { get; }
public Coordinate(int x, int y)
{
X = x;
Y = y;
}
}
public class Coordinates : IEnumerable<Coordinate>
{
private readonly List<Coordinate> _items;
public Coordinates(params Coordinate[] items)
{
_items = new List<Coordinate>();
foreach (var item in items)
_items.Add(item);
}
public IEnumerator<Coordinate> GetEnumerator()
{
yield return _items[0];
int x = _items[0].X;
int y = _items[0].Y;
for (int i = 1; i < _items.Count; i++)
{
x += _items[i].X;
y += _items[i].Y;
yield return new Coordinate(x, y);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Можно реализовать IList, ICollection или любой другой подходящий интерфейс.
Все проверки входных параметров и количества элементов опущены ради краткости.
var coordinates = new Coordinates(
new Coordinate(10, 5), new Coordinate(1, 1), new Coordinate(2, 4), new Coordinate(2, 2)
);
foreach (var coord in coordinates)
Console.WriteLine(coord.X + " " + coord.Y);
Можно добавить свойство начальную координату:
public class Coordinates : IEnumerable<Coordinate>
{
private readonly List<Coordinate> _items;
public Coordinate Origin { get; set; }
public Coordinates(params Coordinate[] items)
{
_items = new List<Coordinate>();
foreach (var item in items)
_items.Add(item);
}
public IEnumerator<Coordinate> GetEnumerator()
{
yield return Origin;
int x = Origin.X;
int y = Origin.Y;
for (int i = 0; i < _items.Count; i++)
{
x += _items[i].X;
y += _items[i].Y;
yield return new Coordinate(x, y);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
var coordinates = new Coordinates(
new Coordinate(1, 1), new Coordinate(2, 4), new Coordinate(2, 2)
);
coordinates.Origin = new Coordinate(10, 5);
foreach (var coord in coordinates)
Console.WriteLine(coord.X + " " + coord.Y);