Конференция "Игры" » Движение точки
 
  • Б (06.01.09 21:58) [0]
    Точка движется по след. формулe:

      x:= round(x + cos(Angle) * Speed);
      y:= round(y + sin(Angle)  * Speed);

      где Angle измеряется в градусах.
     
    Но почему то вся эта система не работает.
    При Angle = 0, точка двигается как надо, т.е. по горизонту в правую сторону.
    При других значениях Angle точка летит чёрт знает куда.
  • antonn © (06.01.09 22:06) [1]
    переводи в радианы
  • Б (06.01.09 22:11) [2]
    Хм... заработало. Но по часовой стрелке, а нужно против.
  • Б (06.01.09 22:20) [3]
    Всё разобрался. Передел функцию вычисления угла, чтобы считала угол по часовой стрелке.

    Но возник друго вопрос: почему то точка немного промахивается, когда летит. Это из-за округления? Если да, то как это предотвратить. Координаты точки должны быть целыми.
  • Denis__ © (06.01.09 22:29) [4]
    в каком смысле "промахивается"?
  • Б (06.01.09 22:37) [5]
    > в каком смысле "промахивается"?

    Объясняю:
    Имеется на форме точка с координатами X,Y;
    При клике на форму в переменную GotoPoint записываются координаты клика.
    Затем находится угол между этими точками.
    Далее во включенном таймере, где вставлена эта формула, вычисляется траектория движения точки.
    По смыслу точка должна двигаться в место последнего клика, но, если расстояние между этими точками велико, то точка немного промахивается и пролетает мимо.
    Кажется это из-за постоянного округления - накапливается погрешность.
    Как с ней бороться?
  • KilkennyCat © (07.01.09 00:10) [6]
    округляй только для вывода.
  • Б (07.01.09 15:13) [7]
    > округляй только для вывода.

    Не получится. Точка (Она, для теста, представлена как панель) всегда должна округляться, для вывода.
  • @!!ex © (07.01.09 16:14) [8]
    > [7] Б   (07.01.09 15:13)

    Для расчета храни реальные. для вывода - округлай. и будет шастье.
  • Б (07.01.09 16:46) [9]
    > Для расчета храни реальные. для вывода - округлай. и будет шастье.

    Сделал. Немного всё равно промахивается, но и так сойдёт.
    Иногда почему-то точка не долетает до нужной, порой на значительные расстояния.
    В таймере стоит проверка: если перемещаемая точка равна той, к которой стремиться, то она останавливается.
  • @!!ex © (07.01.09 17:08) [10]
    > [9] Б   (07.01.09 16:46)

    1) Для чисел с плавающей точкой нет понятия "равно", есть понятие "равно с некоторым допустимым Epsilon"
    2) Где-то в коде косяк, недолжно ничего промахиваться.
  • Б (07.01.09 17:48) [11]
    Вот код:


    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;

    ;
  • Putnik © (07.01.09 18:45) [12]
    А функция getangle где?
  • Putnik © (07.01.09 19:31) [13]
    Прошу прощения, функция getangle должна использовать арктангенс с учетом знака это раз.
    А во-вторых, поставив скорость равной 3, вы получаете положение точки с точночтью до этой скорости, т.е.
    Б   (07.01.09 16:46) [9]
    > Сделал. Немного всё равно промахивается, но и так сойдёт
    Промахивается в пределах устанавливаемой вами скорости
  • Б (07.01.09 20:03) [14]
    > Прошу прощения, функция getangle должна использовать арктангенс с учетом знака это раз.
    Моя функция работает шикарно.

    > Промахивается в пределах устанавливаемой вами скорости...
    Проверил. Это не так. По словам @!!ex "недолжно ничего промахиваться".
    Поставил Speed в 30 интервал таймера в 3. Диапазон промаха всегда одинаковый, при любых скоростях, он равен < 1.
  • Б (07.01.09 20:08) [15]
    > Иногда почему-то точка не долетает до нужной, порой на значительные > расстояния.
    Разобрался. Потому что вместо AND стоял OR:

     If (Panel1.Left = GotoPoint.X) and (Panel1.Top = GotoPoint.Y) then EXIT;

  • Б (07.01.09 20:09) [16]
    Теперь осталось добавить таблицу косинов и синусов... :)
  • Б (07.01.09 20:23) [17]
    Хм... при некоторых параметрах - точка пока летит, что-то очень сильно дёргается в стороны.
  • Putnik © (07.01.09 20:38) [18]
    Ваш код даже не откомпилируется:
    [code]  X:= X + Cos(DegToRad(Angle)) * Speed);
     Y:= Y + Sin(DegToRad(Angle)) * Speed);[/code]
    Вы работаете с одним кодом, а сюда выкладываете другой.
  • Б (07.01.09 20:50) [19]
    > Вы работаете с одним кодом, а сюда выкладываете другой.

    Подумаешь... стёрлась пара скобой. Беда какая. :)
    Код такой же.
 
Конференция "Игры" » Движение точки
Есть новые Нет новых   [134430   +3][b:0][p:0.001]