C#创建网格捕捉功能
我试图创建一些在运行时使用的网格捕捉功能,但我在捕捉部分遇到了问题。我已经成功地在面板上绘制了点网格,但是当我向面板添加标签控件时,如何将标签的左上角捕捉到最近的点C#创建网格捕捉功能,c#,winforms,runtime,C#,Winforms,Runtime,我试图创建一些在运行时使用的网格捕捉功能,但我在捕捉部分遇到了问题。我已经成功地在面板上绘制了点网格,但是当我向面板添加标签控件时,如何将标签的左上角捕捉到最近的点 谢谢pos.x-pos.x%gridWidth应该可以。只需使用整数和除法即可: int xSnap = (xMouse / gridWidth) * gridWidth; int ySnap = (yMouse / gridHeight) * gridHeight; 当然,模解要优雅得多。这里有一个解决方案,将四舍五入到最近的网
谢谢
pos.x-pos.x%gridWidth
应该可以。只需使用整数和除法即可:
int xSnap = (xMouse / gridWidth) * gridWidth;
int ySnap = (yMouse / gridHeight) * gridHeight;
当然,模解要优雅得多。这里有一个解决方案,将四舍五入到最近的网格点:
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);
}
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 );
}
这一个对我来说效果更好,因为它移动点取决于它与下一个或上一个网格点的距离:
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);
if(pt.X%gridWidth
我认为公认的答案不正确。原因如下:
如果gridwidth=3,则x上的a点(如4)应映射为3,但x=5应映射为6。使用Pedery的答案,他们都将映射到3
为了得到正确的结果,您需要这样四舍五入(如果点是分数,则可以使用浮点):
//比如说
int gridCubeWidth = 3;
int gridCubeHeight = 3;
int newX = Math.Round(oldX / gridCubeWidth) * gridCubeWidth;
int newY = Math.Round(oldY / gridCubeHeight) * gridCubeHeight;
Kepp记住,上面的代码将捕捉到接近零的网格线。要向左或向右捕捉,您可以测试x位置%gridWidth是否大于或小于gridWidth/2。记住,坐标低于零时,你会得到一个不同的情况。这将为您提供所需的所有工具。如果您有gridWidth=3。对于点X=5,当它应该映射到6时,它将映射到3。请参阅我的答案以获得更详细的答案。这相当于四舍五入,这并不总是理想的结果。舍入到最近的网格顶点是最好的选择,请查看下面@numansalati的答案!您正在用gridWidth进行乘法和除法运算。这将抵消它们,让它们始终等于xMouse。-1:正如@Julian所说,初等数学表明这个答案是无意义的。计算不是初等数学。当“(xMouse/gridWidth)”的结果是一个整数时,这个公式就可以了。谢谢-这就是我要找的