C# Создание Функции Привязки К Сетке

Я пытаюсь создать некоторые функции привязки к сетке, которые будут использоваться во время выполнения, но у меня возникли проблемы с частью привязки. Я успешно нарисовал пунктирную сетку на панели, но когда я добавляю элемент управления label на панель, как привязать верхний левый угол метки к ближайшей точке?

спасибо

6 ответов


pos.x - pos.x % gridWidth должны сделать это.


Я не думаю, что принятый ответ является правильным. Вот почему:

если gridwidth = 3, в точке x как 4 к 3, А х=5 к 6. используя ответ Pedery они оба карту 3.

для правильного результата вам нужно округлить так (вы можете использовать float, если точки являются дробями):

//допустим.

int gridCubeWidth  = 3;
int gridCubeHeight = 3;

int newX = Math.Round(oldX / gridCubeWidth)  * gridCubeWidth;
int newY = Math.Round(oldY / gridCubeHeight) * gridCubeHeight;

вот решение, которое патронов до ближайшей точки сетки:

    public static readonly Size  Grid     = new Size( 16, 16 );
    public static readonly Size  HalfGrid = new Size( Grid.Width/2, Grid.Height/2 );

    // ~~~~ Round to nearest Grid point ~~~~
    public Point  SnapCalculate( Point p )
    {
        int     snapX = ( ( p.X + HalfGrid.Width  ) / Grid.Width  ) * Grid.Width;
        int     snapY = ( ( p.Y + HalfGrid.Height ) / Grid.Height ) * Grid.Height;

        return  new Point( snapX, snapY );
    }

private enum SnapMode { Create, Move }
private Size gridSizeModeCreate = new Size(30, 30);
private Size gridSizeModeMove = new Size(15, 15);

private Point SnapCalculate(Point p, Size s)
{
    double snapX = p.X + ((Math.Round(p.X / s.Width) - p.X / s.Width) * s.Width);
    double snapY = p.Y + ((Math.Round(p.Y / s.Height) - p.Y / s.Height) * s.Height);
    return new Point(snapX, snapY);
}

private Point SnapToGrid(Point p, SnapMode mode)
{
    if (mode == SnapMode.Create)
        return SnapCalculate(p, gridSizeModeCreate);
    else if (mode == SnapMode.Move)
        return SnapCalculate(p, gridSizeModeMove);
    else
        return new Point(0, 0);
}

этот работает лучше для меня, поскольку он перемещает точку в зависимости от того, насколько близко она находится к следующей или предыдущей точке:

            if (pt.X % gridWidth < gridWidth/2)
                pt.X = pt.X - pt.X % gridWidth;
            else
                pt.X = pt.X + (gridWidth - pt.X % gridWidth);

            if (pt.Y % gridHeight < gridHeight / 2)
                pt.Y = pt.Y - pt.Y % gridHeight;
            else
                pt.Y = pt.Y + (gridHeight - pt.Y % gridHeight);

просто используйте целые числа, и деление будет работать только для вас:

int xSnap = (xMouse / gridWidth) * gridWidth;
int ySnap = (yMouse / gridHeight) * gridHeight;

за исключением, конечно, решения по модулю намного элегантнее.