ScottPlot 查找离鼠标最近的点
2024-03-17 17:33:41

官方已经在 Mouse Position - ScottPlot FAQ 中给出了查找鼠标位置和最近点的方法。
官方示例是以单个散点图作为说明的。而现实中,一个图表肯定不止一条数据,我们不仅仅需要找出最近的X点,还要找出最近的Y点。

解决思路如下:

  1. 遍历绘图对象,找出每个绘图对象当前鼠标所处的XY点。
  2. 再通过上面得到的X点,找出最近的X点。此时便得到了距离鼠标最近的X点。
  3. 用第一步得到的XY点,计算出鼠标所在的像素点位置。
  4. 获取鼠标像素点位置,从第3步的结果中找出离当前鼠标像素位置最近的点即可。


一句话说就是找出距离鼠标最近的每个绘图对象的XY点并转换为像素坐标,再从中找出离鼠标最近的像素坐标即可。
伪代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
foreach (var plottable in formsPlot.Plot.GetPlottables())
{
// 得到当前 X 点
var (mouseCoordX, _) = formsPlot.GetMouseCoordinates(plottable.XAxisIndex, plottable.YAxisIndex);

// 注意,并非所有绘制对象都有 GetPointNearest 方法。这里以信号图举例
if (plottable is SignalPlotConst<double> signalPlot)
{
// 得到最近的 X 点
var (nearestX, nearestY, index) = signalPlot.GetPointNearestX(mouseCoordX);

// 得到离鼠标最近的 XY 像素坐标
var (xPixel, yPixel) = formsPlot.Plot.GetPixel(nearestX, nearestY, plottable.XAxisIndex, plottable.YAxisIndex);
}
}

// 得到当前鼠标像素位置
var (mousePixelX, mousePixelY) = formsPlot.GetMousePixel();

//TODO: 从上面的结果中找出离当前鼠标位置最近的点

至于如何从一系列坐标中找出最近的点,可以用欧氏距离的公式,通过计算 X 坐标和 Y 坐标的差的平方和再开根号得到距离。
伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
private static PointF FindNearestPoint(List<PointF> list, float mousePixelX, float mousePixelY)
{
PointF nearestPoint = default;
var minDistance = double.MaxValue;
foreach (var point in list)
{
var distance = Math.Sqrt(Math.Pow(point.X - mousePixelX, 2) + Math.Pow(point.Y - mousePixelY, 2));
if (distance > minDistance) continue;
minDistance = distance;
nearestPoint = point;
}
return nearestPoint;
}

效果图:

参考

Mouse Position
How to find the plottable nearest the cursor