Войти
Подсказки

Быстрый расчет растояния между двумя точками (с погрешностью).

Автор:

Как правило для правильного расчета расстояния между двумя точками используется функция наподобие этой:

float distance_0 ( float dx, float dy )   
{  
  return sqrt(dx*dx+dy*dy);  
}

где dx=p1_x - p2_x;    а  dy=p1_y - p2_y
если ее использовать для нахождения растояния от центра области, то получится следующее:
Изображение удалено

Эта функция точна и проста в написании, но у нее есть серьезный недостаток - она очень медленная из-за квадратного корня.
Поэтому ради скорости можно пожертовать этим корнем - это не позволит найти расстояние, но позволяет сравнивать его с другим. (Для сравнения, известное расстояние надо возвести в квадрат и после этого сравнивать)

float distance_0 ( float dx, float dy )   
{  
  return dx*dx+dy*dy;  
}

А для того чтобы все же найти само расстояние, и главное быстро - придется пожертовать точностью, которая не всегда и нужна (например проверка столкновений).

float distance_1( float dx, float dy )
{
  if ( dx < 0 ) dx = -dx;
  if ( dy < 0 ) dy = -dy;
  if ( dx < dy )  return 0.961f*dy+0.398f*dx;  
  else    return 0.961f*dx+0.398f*dy;
}

Функция работает в 2 раза быстрее первого варианта и имеет погрешность 5%
При этом получается следующий график
Изображение удалено

Но и это еще не предел - если ее перевести на int то она станет в 2,5 раза быстрее первого варианта, с погрешностью 5%
и тем же графиком

int distance2( int dx, int dy )
{
  if ( dx < 0 ) dx = -dx;
  if ( dy < 0 ) dy = -dy;
  if ( dx < dy )  return (123*dy+51*dx)/128;  
  else    return (123*dx+51*dy)/128;
}

Также это можно упростить до квадрата со скоростью в 3,5 раза быстрее первого варианта, с погрешностью 30%
Изображение удалено

int distance2( int dx, int dy )
{
  if ( dx < 0 ) dx = -dx;
  if ( dy < 0 ) dy = -dy;
  if ( dx < dy )  return dy;  
  else    return dx;
}

3 октября 2003