我有点担心这一点,但我有一个问题,试图让我的头围绕鼠标捕捉到网格。目前我正在通过覆盖OnRender
来绘制网格;
protected override void OnRender(DrawingContext drawingContext)
{
int numberOfVerticalLines = 8;
int numberOfHorizontalLines = 8;
CellHeight = this.ActualHeight / numberOfVerticalLines;
CellWidth = this.ActualWidth / numberOfHorizontalLines;
double verticalOffset = 0;
double horizontalOffset = 0;
Pen pen = new Pen(Stroke, StrokeThickness);
pen.DashStyle = DashStyle;
for (int i = 0; i <= numberOfHorizontalLines; i++)
{
for (int j = 0; j <= numberOfVerticalLines; j++)
{
drawingContext.DrawLine(pen, new Point(horizontalOffset, verticalOffset), new Point(horizontalOffset, CellHeight + verticalOffset));
verticalOffset += CellHeight;
}
horizontalOffset += CellWidth;
verticalOffset = 0;
}
horizontalOffset = 0;
verticalOffset = 0;
for (int i = 0; i <= numberOfVerticalLines; i++)
{
for (int j = 0; j <= numberOfHorizontalLines; j++)
{
drawingContext.DrawLine(pen, new Point(horizontalOffset, verticalOffset), new Point(CellWidth + horizontalOffset, verticalOffset));
horizontalOffset += CellWidth;
}
verticalOffset += CellHeight;
horizontalOffset = 0;
}
}
这给出了以下结果;
然而,我有点想到要将鼠标捕捉到最近的网格交叉点(水平线与垂直线相交)的路线。显然,当我使用drawingcontext绘制线条时,我们在绘制这些线条后没有引用这些线条。
所以我猜我的问题基本上是,如何实现鼠标捕捉到网格呢?这是一个数学问题而不是面向对象的控制问题吗?我已经阅读了几乎所有相关的堆栈溢出问题,但还未能找到任何现实的想法。
注意:虽然我在硬编码8x8网格时,最终会由用户定义。
答案 0 :(得分:1)
答案粗略开始:
int nearGridX = CellWidth * Math.Round( mouseX / CellWidth);
int nearGridY = CellHeight * Math.Round( mouseY / CellHeight);
答案 1 :(得分:1)
一种基本方法是将鼠标的(x,y)与十字架进行比较: 1.计算鼠标所在单元格宽度和高度的起点和终点;和 2.将这两个区间(宽度和高度)与实际鼠标(x,y)进行比较,以找到最近的单元格点。
以下是一些快速抛出的示例代码,用于演示捕捉:
/// <summary>
/// When left shift key is pressed we snap the mouse to the closest
/// intersection
/// </summary>
void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.LeftShift)
{
var p = GetSnappingPoint(Mouse.GetPosition(this), new Size(200, 200));
SetCursorPos((int)p.X, (int)p.Y+20);
}
}
[DllImport("User32.dll")]
private static extern bool SetCursorPos(int x, int y);
/// <summary>
/// Get snapping point by
/// </summary>
Point GetSnappingPoint(Point mouse,Size cellSize)
{
//Get x interval based on cell width
var xInterval = GetInterval(mouse.X, cellSize.Width);
//Get y interal based in cell height
var yInterval = GetInterval(mouse.Y, cellSize.Height);
// return the point on cell grid closest to the mouseposition
return new Point()
{
X = Math.Abs(xInterval.Lower - mouse.X) > Math.Abs(xInterval.Upper - mouse.X) ? xInterval.Upper : xInterval.Lower,
Y = Math.Abs(yInterval.Lower - mouse.Y) > Math.Abs(yInterval.Upper - mouse.Y) ? yInterval.Upper : yInterval.Lower,
};
}
/// <summary>
/// Find an interval of the celsize based on mouse position and size
/// </summary>
Interval GetInterval(double mousePos,double size)
{
return new Interval()
{
Lower = ((int)(mousePos / size)) * size,
Upper = ((int)(mousePos / size)) * size + size
};
}
/// <summary>
/// Basic interval class
/// </summary>
class Interval
{
public double Lower { get; set; }
public double Upper { get; set; }
}
答案 2 :(得分:0)
xPos= mouseX - (mouseX % gridWidth);
yPos= mouseY - (mouseY % gridHeight);
这会让您快速而又脏地捕捉到当前网格的左上角。如果您更接近当前网格的底部或右侧,则不会考虑这一点。它只会查看你所在的网格并将其放在那里。