我正在尝试创建一些在运行时使用的对齐网格功能,但我遇到了捕捉部分的问题。我已成功在面板上绘制了一个虚线网格,但当我向面板添加标签控件时,如何将标签的左上角捕捉到最近的点?
由于
答案 0 :(得分:16)
pos.x - pos.x % gridWidth
应该这样做。
答案 1 :(得分:16)
我不认为接受的答案是正确的。原因如下:
如果gridwidth = 3,x上的a点4应映射到3,但x = 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;
答案 2 :(得分:4)
这是舍入到最近的网格点的解决方案:
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 );
}
答案 3 :(得分:3)
这个对我来说效果更好,因为它根据它与下一个或前一个网点的接近程度来移动点:
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);
答案 4 :(得分:2)
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);
}
答案 5 :(得分:0)
只需使用整数,除法将适合您:
int xSnap = (xMouse / gridWidth) * gridWidth;
int ySnap = (yMouse / gridHeight) * gridHeight;
除了模数解决方案当然更优雅。