У меня есть стрелка, нарисованная между двумя объектами в Winform.
Какой самый простой способ определить, что моя мышь в данный момент находится над или около этой линии?
Я рассмотрел вопрос о том, пересекает ли точка мыши квадрат, определенный и экстраполированный двумя точками, однако это было бы возможно только в том случае, если две точки имели очень похожие значения x или y.
Я также думаю, что эта проблема, скорее всего, больше связана с линейной алгеброй, чем с простой тригонометрией, и хотя я помню более простые аспекты матриц, эта проблема выходит за рамки моих знаний о линейной алгебре.
С другой стороны, если библиотека .NET справится с этой функцией, даже лучше.
EDIT
Спасибо за ответы, есть несколько очень хороших, которые заслуживают того, чтобы их отметили как отвеченные.
Я выбрал ответ Coincoin в качестве принятого, так как мне нравится, что он может быть применен к любой нарисованной фигуре, однако в итоге реализовал уравнение Тима Робинсона, так как он оказался намного эффективнее с простым уравнением, а не обновлял графические пути и ручки , как и в моем случае, мне нужно сделать это на MouseMove для 1-n различных отношений (очевидно, было бы некоторое кэширование и оптимизация, но суть все еще остается)
Основная проблема с уравнением заключалась в том, что оно, по-видимому, рассматривало линию как бесконечную, поэтому я также добавил тест границ.
Код (начальный вырез, я, вероятно, немного опрятный), для тех, кто заинтересован, ниже
if (Math.Sqrt( Math.Pow(_end.X - _start.X, 2) +
Math.Pow(_end.Y - _start.Y, 2) ) == 0)
{
_isHovering =
new RectangleF(e.X, e.Y, 1, 1).IntersectsWith(_bounds);
}
else
{
float threshold = 10.0f;
float distance = (float)Math.Abs(
( ( (_end.X - _start.X) * (_start.Y - e.Y) ) -
( (_start.X - e.X) * (_end.Y - _start.Y) ) ) /
Math.Sqrt( Math.Pow(_end.X - _start.X, 2) +
Math.Pow(_end.Y - _start.Y, 2) ));
_isHovering = (
distance <= threshold &&
new RectangleF(e.X, e.Y, 1, 1).IntersectsWith(_bounds)
);
}
и _bounds определяется как:
_bounds = new Rectangle(
Math.Min(_start.X, _end.X),
Math.Min(_start.Y, _end.Y),
Math.Abs(_start.X - _end.X), Math.Abs(_start.Y - _end.Y));