views:

384

answers:

4

I am trying to create some snap to grid functionality to be used at run time but I am having problems with the snapping part. I have successfully drawn a dotted grid on a panel but when I add a label control to the panel how to I snap the top, left corner of the label to the nearest dot?

Thanks

+7  A: 

pos.x - pos.x % gridWidth should do it

Pedery
Thanks very much!
Nathan
Kepp in mind that the above code will snap to the gridline closer to zero though. To snap left or right you could i.e. test wether pos.x % gridWidth is more or less than gridWidth / 2. Remember that you'll get a different case for coordinates below zero. That should give you all the tools you need.
Pedery
+2  A: 

Just use integers and division will just work for you:

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

Except of course the modulo solution is so much more elegant.

Igor Zevaka
+1  A: 
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);
}
Wiesław Šoltés
A: 

Here is a solution that rounds to the nearest grid point:

    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 );
    }
Roland