-
Точка движется по след. формулe:
x:= round(x + cos(Angle) * Speed); y:= round(y + sin(Angle) * Speed);
где Angle измеряется в градусах. Но почему то вся эта система не работает. При Angle = 0, точка двигается как надо, т.е. по горизонту в правую сторону. При других значениях Angle точка летит чёрт знает куда.
-
переводи в радианы
-
Хм... заработало. Но по часовой стрелке, а нужно против.
-
Всё разобрался. Передел функцию вычисления угла, чтобы считала угол по часовой стрелке.
Но возник друго вопрос: почему то точка немного промахивается, когда летит. Это из-за округления? Если да, то как это предотвратить. Координаты точки должны быть целыми.
-
в каком смысле "промахивается"?
-
> в каком смысле "промахивается"?
Объясняю: Имеется на форме точка с координатами X,Y; При клике на форму в переменную GotoPoint записываются координаты клика. Затем находится угол между этими точками. Далее во включенном таймере, где вставлена эта формула, вычисляется траектория движения точки. По смыслу точка должна двигаться в место последнего клика, но, если расстояние между этими точками велико, то точка немного промахивается и пролетает мимо. Кажется это из-за постоянного округления - накапливается погрешность. Как с ней бороться?
-
округляй только для вывода.
-
> округляй только для вывода.
Не получится. Точка (Она, для теста, представлена как панель) всегда должна округляться, для вывода.
-
> [7] Б (07.01.09 15:13)
Для расчета храни реальные. для вывода - округлай. и будет шастье.
-
> Для расчета храни реальные. для вывода - округлай. и будет шастье.
Сделал. Немного всё равно промахивается, но и так сойдёт. Иногда почему-то точка не долетает до нужной, порой на значительные расстояния. В таймере стоит проверка: если перемещаемая точка равна той, к которой стремиться, то она останавливается.
-
> [9] Б (07.01.09 16:46)
1) Для чисел с плавающей точкой нет понятия "равно", есть понятие "равно с некоторым допустимым Epsilon" 2) Где-то в коде косяк, недолжно ничего промахиваться.
-
Вот код:
Var Angle: double;
X, Y: double;
GotoPoint: TPoint;
procedure TForm1.FormCreate(Sender: TObject);
begin
GotoPoint:= Point(Panel1.Left, Panel1.Top);
X:= Panel1.Left;
Y:= Panel1.Top;
end;
procedure TForm1.FormMouseDown(Sender:TObject;Button:TMouseButton;Shift: TShiftState; X, Y: Integer);
begin
GotoPoint:= Point(x,y);
Angle:= GetAngle(Point(Panel1.Left, Panel1.Top), GotoPoint);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
Const Speed = 3;
begin
If (Panel1.Left = GotoPoint.X) and (Panel1.Top = GotoPoint.Y) then EXIT;
X:= X + Cos(DegToRad(Angle)) * Speed);
Y:= Y + Sin(DegToRad(Angle)) * Speed);
Panel1.Left:= round(X);
Panel1.Top:= round(Y);
end;
;
-
А функция getangle где?
-
Прошу прощения, функция getangle должна использовать арктангенс с учетом знака это раз. А во-вторых, поставив скорость равной 3, вы получаете положение точки с точночтью до этой скорости, т.е. Б (07.01.09 16:46) [9] > Сделал. Немного всё равно промахивается, но и так сойдёт Промахивается в пределах устанавливаемой вами скорости
-
> Прошу прощения, функция getangle должна использовать арктангенс с учетом знака это раз. Моя функция работает шикарно.
> Промахивается в пределах устанавливаемой вами скорости... Проверил. Это не так. По словам @!!ex "недолжно ничего промахиваться". Поставил Speed в 30 интервал таймера в 3. Диапазон промаха всегда одинаковый, при любых скоростях, он равен < 1.
-
> Иногда почему-то точка не долетает до нужной, порой на значительные > расстояния. Разобрался. Потому что вместо AND стоял OR:
If (Panel1.Left = GotoPoint.X) and (Panel1.Top = GotoPoint.Y) then EXIT;
-
Теперь осталось добавить таблицу косинов и синусов... :)
-
Хм... при некоторых параметрах - точка пока летит, что-то очень сильно дёргается в стороны.
-
Ваш код даже не откомпилируется: [code] X:= X + Cos(DegToRad(Angle)) * Speed); Y:= Y + Sin(DegToRad(Angle)) * Speed);[/code] Вы работаете с одним кодом, а сюда выкладываете другой.
-
> Вы работаете с одним кодом, а сюда выкладываете другой.
Подумаешь... стёрлась пара скобой. Беда какая. :) Код такой же.
|