Pergunta

Eu quero ser capaz de se mover uma partícula em uma linha reta dentro de um ambiente 3D, mas eu não posso pensar como trabalhar a próxima localização com base em dois pontos dentro de um espaço 3D?

Eu criei uma estrutura que representa uma partícula que tem uma localização e uma localização próxima? Será que isso é adequado para trabalhar fora o próximo local para mover também? Eu sei como configurar inicialmente o próximo local usando o seguinte método:

// 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;
}

As estruturas que tenho usado são:

// 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;
};

Am I lidando com isso de forma completamente errada?

aqui está todo o meu código http://pastebin.com/m469f73c2

Foi útil?

Solução

A outra resposta é um pouco mathish, é realmente bastante simples.

Você precisa de um "Velocity", que você está se movendo. Ele também tem x, y e z coordenadas.

Em um período de tempo, para movê-lo basta adicionar a velocidade x de sua posição x para obter a sua nova posição x, repita para y e z.

Além disso, você pode ter uma "aceleração" (também x, y, z), por exemplo, a sua aceleração z poderia ser a gravidade, uma constante.

Cada período de tempo a sua velocidade deve ser recalcualted da mesma forma, Call velocidade x "vx", de modo vx deve tornar-se vx + machado, repita para Y e Z (de novo).

Tem sido um tempo desde matemática, mas é assim que eu me lembro, muito para a frente, a menos que você precisa para manter o controle de unidades, então fica um pouco mais interessante (mas ainda não é mau)

Outras dicas

Eu sugiro que uma partícula deve ter apenas um membro do local - a localização atual. Além disso, a velocidade deve, idealmente, ser um vector de 3 componentes em si. Crie uma função (chamemos-lhe move, displace qualquer outro) que leva um particle e uma duração t tempo. Isto irá calcular a posição final depois unidades t de tempo decorrido:

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;
}

Eu recomendaria duas coisas:

  1. ler um artigo ou dois em matemática básica vetor para a animação. Por exemplo, este é um site que explica vetores 2D para o flash.

  2. começar simples, comece com um ponto 1d, ou seja, um único ponto se movendo ao longo x. Tente adicionar uma segunda dimensão (um ponto 2d num espaço 2d) e terceira dimensão. Esta ajuda lhe possam obter uma melhor compreensão dos mecanismos subjacentes. espero que isso ajude

Pense da física. Um objecto tem uma posição (x, y, z) e um vector de movimento (a, b, c). Seu objeto deve existir em sua posição; ele tem um vector de movimento associado a ele que descreve o seu dinamismo. Na falta de quaisquer forças adicionais no objeto, e assumindo que o seu vector movimento descreve o movimento ao longo de um período de tempo t, a posição do seu objeto em tempo de x será (x + (a t), y + ( b t), Z + (c * t)).

Em suma; não guarde a posição atual e a próxima posição. Armazenar a posição atual e dinâmica do objeto. É fácil o suficiente para "tick do relógio" e atualizar a localização do objeto simplesmente adicionando o impulso para a posição.

velocidade de loja como um point3f struct, e então você tem algo como isto:

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

Essencialmente, a velocidade é o quanto você quer a posição de mudar a cada segundo / carrapato / whatever.

Você deseja implementar o X_{i+1} = X_{i} + Vt vector de matemática. Para os Xs e vectores que representam V posição e de velocidade, respectivamente, e representam t tempo. Eu parametrizado a distância ao longo da pista por vez, porque eu sou um físico, mas é realmente a coisa natural a fazer. Normalizar o vetor velocidade se você quer dar a pista de distância (ou seja, escala V tal que V.x*V.x + V.y*V.y + V.z*V.z = 1).

Usando o struct acima torna natural para acessar os elementos, mas não tão conveniente para fazer a adição: matrizes são melhores para isso. Como esta:

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

// initialize

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

Com a união, você pode obter as vantagens de ambos:

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;

Se você deseja associar tanto a posição ea velocidade de com a partícula (uma coisa muito razoável para fazer) você construir uma estrutura que suporte dois vetores

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

e executar uma rotina de atualização que parece mais ou menos como:

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

AFAIK, existem essencialmente duas maneiras de como você pode calcular a nova posição. Um deles é como o outro têm explaint usar uma velocidade explícito. A outra possibilidade é armazenar a última e a posição atual e usar o Verlet integração . Ambas as formas têm suas vantagens e desvantagens. Você também pode dar uma olhada neste interresting página .

Se você está tentando se mover ao longo de uma linha reta entre dois pontos, você pode usar a fórmula de interpolação:

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

P (t) é a posição calculado do ponto, t é um escalar que varia de 0 a 1, P1 e P2 são os pontos de extremidade, e a adição na acima é a adição de vectores (modo de aplicar esta fórmula separadamente para o x, y e componentes z dos seus pontos). Quando t = 0, você começa P1; quando t = 1, você começa P2, e para valores intermediários, você tem uma maneira da parte ponto ao longo da linha entre P1 e P2. Assim, t = 0,5 lhe dá o ponto médio entre P1 e P2, t = 0,333333 lhe dá o ponto de 1/3 do percurso de P1 a P2, etc. valores de T fora do intervalo [0, 1] extrapolar para os pontos ao longo a linha de fora do segmento de P1 a P2.

Usando a fórmula de interpolação pode ser melhor do que computar uma velocidade e repetidamente adicionando-se a velocidade é pequena em comparação com a distância entre os pontos, porque você limitar o erro de arredondamento.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top