Вопрос

Я хочу иметь возможность перемещать частицу по прямой в трехмерной среде, но не могу придумать, как определить следующее местоположение на основе двух точек в трехмерном пространстве?

Я создал структуру, которая представляет частицу, имеющую местоположение и следующее местоположение?Подойдет ли это для определения следующего места переезда?Я знаю, как изначально установить следующее местоположение, используя следующий метод:

// Set particle's direction to a random direction
void setDirection(struct particle *p)
{
    float xnm = (p->location.x * -1) - p->velocity;
    float xnp = p->location.x + p->velocity;
    float ynm = (p->location.y * -1) - p->velocity;
    float ynp = p->location.y + p->velocity;
    float znm = (p->location.z * -1) - p->velocity;
    float znp = p->location.z + p->velocity;

    struct point3f nextLocation = { randFloat(xnm, xnp), randFloat(ynm, ynp), randFloat(znm, znp) };
    p->nextLocation = nextLocation;
}

Структуры, которые я использовал:

// Represents a 3D point
struct point3f
{
    float x;
    float y;
    float z;
};

// Represents a particle
struct particle
{
    enum TYPES type;
    float radius;
    float velocity;
    struct point3f location;
    struct point3f nextLocation;
    struct point3f colour;
};

Я делаю это совершенно неправильно?

вот весь мой код http://pastebin.com/m469f73c2

Это было полезно?

Решение

Другой ответ немного математический, на самом деле он довольно простой.

Вам нужна «Скорость», с которой вы двигаетесь.Он также имеет координаты x, y и z.

За один период времени для перемещения вы просто добавляете скорость x к вашему положению x, чтобы получить новое положение x, повторите то же самое для y и z.

Кроме того, у вас может быть «Ускорение» (также x,y,z). Например, ваше ускорение Z может быть константой силы тяжести.

Каждый период времени ваша скорость должна пересчитываться таким же образом: Назовите скорость x «vx», поэтому vx должно стать vx + ax, повторите для y и z (снова).

Прошло много времени с математикой, но я ее помню такой, довольно простой, если только вам не нужно следить за единицами, тогда становится немного интереснее (но все равно неплохо)

Другие советы

Я бы предположил, что у частицы должен быть только один член местоположения — текущее местоположение.Кроме того, скорость в идеале сама должна быть вектором из трех компонентов.Создайте функцию (назовите ее move, displace что угодно) это занимает particle и продолжительность времени t.Это вычислит окончательную позицию после t прошло единиц времени:

struct point3f move(struct *particle, int time) {
    particle->location->x = particle->velocity->x * t;
    /* and so on for the other 2 dimensions */
    return particle->location;
}

Я бы порекомендовал две вещи:

  1. прочитайте пару статей по основам векторной математики для анимации.Например, этот это сайт, на котором объясняются 2D-векторы для Flash.

  2. начните с простого, начните с точки 1d, то есть точки, движущейся только вдоль x.Затем попробуйте добавить второе измерение (двухмерную точку в двухмерном пространстве) и третье измерение.Это может помочь вам лучше понять основную механику.надеюсь это поможет

Подумайте о физике.Объект имеет позицию (x, y, z) и вектор движения (a, b, c).Ваш объект должен существовать на своем месте;с ним связан вектор движения, который описывает его импульс.При отсутствии каких-либо дополнительных сил на объект и предположении, что ваш вектор движения описывает движение за период времени t, положение вашего объекта в момент времени x будет (x + (aт), у + (бt), z + (c*t)).

Суммируя;не сохраняйте текущую позицию и следующую позицию.Сохраните текущую позицию и импульс объекта.Достаточно легко «тикать часы» и обновлять местоположение объекта, просто добавляя импульс к положению.

Сохраните скорость как структуру point3f, и тогда у вас будет что-то вроде этого:

void move(struct particle * p)
{
  p->position.x += p->velocity.x;
  p->position.y += p->velocity.y;
  p->position.z += p->velocity.z;
}

По сути, скорость — это то, насколько вы хотите, чтобы позиция менялась каждую секунду/тик/что угодно.

Вы хотите реализовать векторную математику X_{i+1} = X_{i} + Vt.Для Xпесок V векторы, представляющие положение и скорость соответственно, и t представляющее время.Я параметризовал расстояние по трассе временем, потому что я физик, но это действительно естественная вещь.Нормализуйте вектор скорости, если вы хотите указать расстояние пути (т.е.шкала V такой, что V.x*V.x + V.y*V.y + V.z*V.z = 1).

Используя struct выше делает естественным доступ к элементам, но не столь удобным делать сложение:массивы лучше для этого.Так:

double X[3];
double V[3];

// initialize

for (int i=0; i<3 ++1){
  X[i] = X[i] + V[i]*t;
}

Благодаря объединению вы можете получить преимущества обоих:

struct vector_s{
  double x;
  double y;
  double z;
}
typedef
union vector_u {
  struct vector_s s; // s for struct
  double a[3];       // a for array
} vector;

Если вы хотите связать с частицей и положение, и скорость (очень разумный поступок), вы создаете структуру, поддерживающую два вектора.

typedef
struct particle_s {
  vector position;
  vector velocity;
  //...
} particle_t;

и запустите процедуру обновления, которая выглядит примерно так:

void update(particle *p, double dt){
  for (int i=0; i<3 ++i){
    p->position.a[i] += p->velocity.a[i]*dt;
  }
}

На самом деле, есть два способа расчета новой позиции.Один, как и другой, объяснил, что нужно использовать явную скорость.Другая возможность — сохранить последнюю и текущую позицию и использовать Интеграция Верлет.Оба пути имеют свои преимущества и недостатки.Вы также можете взглянуть на это интересное страница.

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

P(t) = P1*(1-t) + P2*t

P(t) — расчетное положение точки, t — скаляр в диапазоне от 0 до 1, P1 и P2 — конечные точки, а сложение, указанное выше, — это сложение векторов (поэтому вы применяете эту формулу отдельно к x, y и z-компоненты ваших баллов).Когда t=0, вы получаете P1;когда t=1, вы получаете P2, а для промежуточных значений вы получаете точку на полпути между P1 и P2.Таким образом, t=0,5 дает вам среднюю точку между P1 и P2, t=0,333333 дает вам точку на 1/3 пути от P1 до P2 и т. д.Значения t вне диапазона [0, 1] экстраполируются на точки вдоль линии за пределами сегмента от P1 до P2.

Использование формулы интерполяции может быть лучше, чем вычисление скорости и повторное ее добавление, если скорость мала по сравнению с расстоянием между точками, поскольку вы ограничиваете ошибку округления.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top