#generics #math #trigonometry
#общие сведения #математика #тригонометрия
Вопрос:
Я пытаюсь вычислить, как долго мой объект будет перемещаться в пределах данной ячейки, прежде чем он переместится в другую ячейку.
Это то, что действительно важно для меня, но также мне нужно знать, какова точка пересечения (но было бы тривиально, если бы я знал расстояние от начальной точки).
Некоторые из моих правил игры :
- Каждая ячейка может иметь разную стоимость перемещения
- Стоимость перемещения точно такая же по всей ячейке
- Я перемещаю объект из точки A в точку B по прямой
- Я знаю начальное местоположение объекта и его направление (как вектор)
- ячейки имеют границы на строках, которые являются полными целыми числами в сети чисел.
Что мне нужно в конце :
- где именно у единицы закончатся точки перемещения, если она продолжит движение в указанном направлении.
Итак, для каждой ячейки мне нужно вычислить :
- расстояние от точки внутри ячейки до границы этой ячейки — при движении вдоль вектора направления.
Я думаю, что пропустил какой-то урок тригонометрии, или я слишком сонный, но я не смог бы найти ни простого решения этой проблемы, ни быстрого и грязного обходного пути.
Комментарии:
1. Формула расстояния равна C в квадрате = A в квадрате B в квадрате. Другими словами, найдите изменение в X, возведите его в квадрат, найдите изменение в Y, возведите его в квадрат, сложите квадраты вместе и извлеките квадратный корень.
Ответ №1:
Я создал некоторую функцию, которая делает то, что мне нужно. Я не уверен, будет ли оно полностью надежным (я особенно боюсь некоторого округления с плавающей запятой, которое приведет к размещению точки, которая находится на границе, — на неправильной стороне этой границы и приведет к расстоянию 0). Он также много печатает и назначает много, но я планирую сократить его, улучшить и обновить этот ответ в будущем. Я хотел поделиться тем, что сработало достаточно хорошо — на случай, если у кого-то возникнет подобная проблема / или если я не буду обновлять ее в ближайшее время.
Vector2D cellCross(Vector2D startPoint, Vector2D direction)
{
printf("start point [x:%f|y:%f]n",startPoint.x,startPoint.y);
printf("direction [x:%f|y:%f]n",direction.x,direction.y);
if (!direction.isNormalized())
{
printf("in cellCross() : direction vector must be normalized!n");
throw "bad arg";
}
//cell center is like Vector2D(x,y) from my image
Vector2D cellCenter (floor(startPoint.x) 0.5 , floor(startPoint.y) 0.5);
printf("cell center [x:%f|y:%f]n",cellCenter.x,cellCenter.y);
//relative point is like Vector2D(m,n) from my image
Vector2D relativePoint ( startPoint.x-cellCenter.x , startPoint.y-cellCenter.y );
printf("relative point [x:%f|y:%f]n",relativePoint.x,relativePoint.y);
Vector2D targetCorner;
if (direction.x>0)
targetCorner.x=0.5;
else
targetCorner.x=-0.5;
if (direction.y>0)
targetCorner.y=0.5;
else
targetCorner.y=-0.5;
printf("target corner [x:%f|y:%f]n",targetCorner.x,targetCorner.y);
double x_diff = targetCorner.x - relativePoint.x;
double y_diff = targetCorner.y - relativePoint.y;
printf("x_diff : %fn",x_diff);
printf("y_diff : %fn",y_diff);
Vector2D crossPoint;
if (fabs(x_diff*direction.x) > fabs(y_diff*direction.y))
{ // we will cross at (targetCorner.x,[unknown]y)
crossPoint.x = targetCorner.x;
crossPoint.y = relativePoint.y (direction.y * (x_diff/direction.x) );
}
else
{ // we will cross at ([unknown]x,targetCorner.y)
crossPoint.y = targetCorner.y;
crossPoint.x = relativePoint.x (direction.x * (y_diff/direction.y) );
}
crossPoint.x =cellCenter.x;
crossPoint.y =cellCenter.y;
printf("cross point [x:%f|y:%f]n",crossPoint.x,crossPoint.y);
printf("distance : %fn",startPoint.distanceTo(crossPoint) );
return crossPoint;
}
Чтобы представить один пример — для :
Vector2D startPoint (2.0,0.5);
Vector2D direction = Vector2D(10,-30).normalized();
Vector2D endingPoint = cellCross(startPoint,direction);
он напечатал :
start point [x:2.000000|y:0.500000]
direction [x:0.316228|y:-0.948683]
cell center [x:2.500000|y:0.500000]
relative point [x:-0.500000|y:0.000000]
target corner [x:0.500000|y:-0.500000]
x_diff : 1.000000
y_diff : -0.500000
cross point [x:2.166667|y:0.000000]
distance : 0.527046
что выглядит примерно как правильный результат для меня и моего калькулятора.
Тогда я мог бы просто умножить расстояние от результата функции на стоимость перемещения для этой плитки и повторить вычисление для следующей плитки, пока мое устройство не перейдет к отрицательному количеству точек перемещения. Быстрая коррекция путем перемещения его по last_tile_movement_cost * movement_points в том же направлении должна поместить его прямо туда, где он должен был приземлиться.