C # анимация - переместить объект из А в В или по углу - PullRequest
2 голосов
/ 17 июня 2010

Привет, я просто делаю небольшую анимацию, которая перемещает объект из точки a в точку b или на угол / радианы.

В настоящее время у меня есть

Point CalcMove(Point pt, double angle, int speed)
    {
        Point ret = pt;

        ret.X = (int)(ret.X + speed * Math.Sin(DegToRad(angle)));
        ret.Y = (int)(ret.Y + speed * Math.Cos(DegToRad(angle)));

        return ret;
    }

, но этоне смотри, что я ожидал.

помогите пожалуйста?

обновление:о, и я использую NETCF


CalcMove (точка pt, двойной угол, внутренняя скорость)«Точка pt» - текущее местоположение объекта.«угол» - это то, куда должен идти объект.«скорость» - это шаг.


так после рабочих дней ..вот над чем я работал .. Neko для Windows Mobile 6.5

Ответы [ 3 ]

1 голос
/ 17 июня 2010

Используйте матрицу вращения.Этот код переместится из точки (x, y) с помощью тета-радианов в новую точку (px, px)

Point Rotate(x, y, theta)
    int px = (x * Math.Cos(theta)) - (y * Math.Sin(theta));
    int py = (y * Math.Cos(theta)) + (x * Math.Sin(theta));
    return new Point(px, py);
end

Матрица, использованная выше,

[cosθ - sinθ][x]
[cosθ + sinθ][y]

Переместитпри использовании графических координат указывайте вокруг круга по часовой стрелке.

На прошлой неделе я делал то же самое.Вы можете анимировать это, найдя общую тета, которую вы хотите переместить, а затем разделите ее на количество кадров (или шагов).Теперь начинайте каждое движение в некоторой произвольной точке (например, (0, радиус)), увеличивайте счетчик totalSteps и двигайтесь всегда начиная с этой начальной точки .Если вы просто перемещаете саму точку в каждом кадре, вы накапливаете некоторую ошибку, но если вы всегда двигаетесь от начальной точки с текущим шагом, останавливаясь при увеличении == totalTheta, это будет идеально.Дайте мне знать, если это имеет смысл.

Может быть, я должен проиллюстрировать немного больше.Допустим, у вас есть метод "BeginMove":

double totalTheta = 0;
double increment = 0;
double currentTheta = 0;
bool moving = false;
void BeginMove()
{
    totalTheta = (2 * Math.PI) / numObjects;
    increment = totalTheta / steps;
    currentTheta = 0;
    moving = true;
}

Теперь у вас есть метод, который обновляет ход в каждом кадре:

void Update
{
    if (!moving) return;
    // do a min/max to ensure that you never pass totalTheta when incrementing.
    // there will be more error handling, but this is the basic idea.
    currentTheta += increment;
    SomeObject.Location = Rotate(0, radius, currentTheta);
    moving = (currentTheta < totalTheta);
}

Очевидно, здесь будет больше логики в зависимости от вашегоТочная ситуация, но идея такова:

  1. Найдите общее количество тета для перемещения.
  2. Найдите приращение (totalTheta / шаги)
  3. Поддержите промежуточный итог того, какНа сколько вы уже продвинулись.
  4. Увеличивайте промежуточную сумму на угол приращения перед каждым движением.
  5. Начинайте каждое движение с одной и той же (произвольной) точки на круге и поворачивайте на общую сумму.
  6. Повторять до тех пор, пока итоговая сумма не будет == итого тета.
0 голосов
/ 17 июня 2010

После каждого неудачного теста этих предложенных кодов (позор мне) .. Я только что нашел очень старое решение.

чтобы нарисовать круг на xypixel, вот как я делал это раньше в TurboBasic (dos)

x = xcenter + radius * Cos(radian)<br/>
y = ycenter + radius * Sin(radian)

Я применил ту же идею, сделав центр xy в качестве местоположения объекта, радиус - это просто значение приращения (за шаг), а радиан был вычислен из последнего местоположения объекта xy и пункта назначения xy

Теперь у меня есть объект, который перемещается из точки A в точку B

0 голосов
/ 17 июня 2010

Да, ваша формула немного неверна:

давайте назовем фактический угол α, а угол, на который вы хотите повернуть, равен β d - длина строки: d = sqrt (x x + y y)

Для расчета новых координат нам нужно:

sin (α + β) = cos β sinα + sin β cos α

cos (α + β) = cosα cos β - sinα sin β

cos α = x / d грех α = г / д

Новые координаты будут: х = грех (α + β) * д y = cos (α + β) * d

все вместе:

double d = Math.Sqrt(x*x + y*y);
double sina = pt.Y / d;
double cosa = pt.X / d;
double sinb = Math.Sin(DegToRad(angle));
double cosb = Math.Cos(DegToRad(angle));

ret.X = (int)(cosb*sina + sinb*cosa);
ret.Y = (int)(cosa*cosb - sina*sinb);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...