У вас есть ошибка в угловой части, поэтому результат рассчитывается для одного из концов (30 * sqrt (2)).(Обратите внимание, что вы рассчитываете atan для расстояния, но аргумент должен быть отношением двух расстояний. Кроме того, такой подход страдает проблемами с диапазоном atan и т. Д.).
Но вам не нужно делать тригонометрические вычисления.Просто найдите скалярное произведение векторов ba и bp и скалярное произведение векторов ab и ap .
Если первый отрицателен (угол abp тупой), найдите расстояние до конца b .Если второй отрицательный, получить расстояние до конца a .
Если оба значения отрицательны, используйте расстояние, рассчитанное по перекрестному произведению (оно у вас уже есть).Обратите внимание, что последнее расстояние может быть вычислено после всех сравнений.
Проверенный код :
public static double GetDist(double ax, double ay, double bx,
double by, double x, double y) {
if ((ax-bx)*(x-bx)+(ay-by)*(y-by) <= 0)
return Math.Sqrt((x - bx) * (x - bx) + (y - by) * (y - by));
if ((bx-ax)*(x-ax)+(by-ay)*(y-ay) <= 0)
return Math.Sqrt((x - ax) * (x - ax) + (y - ay) * (y - ay));
return Math.Abs((by - ay)*x - (bx - ax)*y + bx*ay - by*ax) /
Math.Sqrt((ay - by) * (ay - by) + (ax - bx) * (ax - bx));
}
public static void Main()
{
Console.WriteLine(GetDist(0, 2, 2, 0, 0, 0));
Console.WriteLine(GetDist(0, 2, 2, 0, 0, 3));
}
1.41421356237309
1