Frage

Ich möchte in der Lage, ein Teilchen in einer geraden Linie in einer 3D-Umgebung zu bewegen, aber ich kann nicht glauben, wie die nächste Lage an zwei Punkten innerhalb eines 3D-Raum basiert arbeiten?

Ich habe eine Struktur geschaffen, die ein Teilchen darstellt, die einen Ort und eine nächste Lage hat? Wäre dies geeignet sein, den nächsten Ort zu arbeiten, zu bewegen? Ich weiß, wie man zunächst die nächste Stelle legen Sie die folgende Methode:

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

Die structs ich verwendet habe, sind:

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

Ist ich über diesen völlig falschen Weg gehen?

Hier ist alles meines Code http://pastebin.com/m469f73c2

War es hilfreich?

Lösung

Die andere Antwort ist ein wenig mathish, es ist eigentlich ziemlich einfach.

Sie müssen eine „Geschwindigkeit“, die Sie sich bewegen. Es hat auch x, y und z-Koordinaten.

In einer Zeit, bewegen Sie nur die x Geschwindigkeit Position zu Ihrer x fügen Sie Ihre neue X-Position zu bekommen, wiederholen Sie für y und z.

Obendrein können Sie eine „Beschleunigung“ haben (auch x, y, z) beispielsweise Ihre z Erdbeschleunigung sein könnte, eine Konstante ist.

Jedes Mal, Zeit Ihre Geschwindigkeit sollte auf die gleiche Art und Weise recalcualted werden, Anrufgeschwindigkeit "vx" x sollte so vx werden vx + ax, wiederholen Sie für y und z (wieder).

Es ist schon eine Weile her, seit Mathematik, aber das ist, wie ich mich daran erinnere, ziemlich geradlinig, es sei denn Sie verfolgen Einheiten halten müssen, dann ist es ein wenig interessanter wird (aber immer noch nicht schlecht)

Andere Tipps

Ich würde vorschlagen, dass ein Teilchen nur an eine Stelle Mitglied haben sollte - die aktuelle Position. Auch sollte die Geschwindigkeit im Idealfall ein Vektor von drei Komponenten selbst sein. Erstellen Sie eine Funktion (nennen wir es move, displace was auch immer), die eine particle und eine Zeitdauer t nimmt. Dies wird die endgültige Position berechnet nach t Zeiteinheiten abgelaufen sind:

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

Ich würde zwei Dinge empfehlen:

  1. einen Artikel oder zwei zu den grundlegenden Vektor Mathematik für Animation lesen. Zum Beispiel diese ist eine Website, die 2d-Vektoren für Flash erklärt.

  2. Starten einfach, mit einem 1d Punkt beginnen, dh nur ein Punkt entlang x bewegt. Dann versuchen Sie eine zweite Dimension hinzugefügt (ein 2D-Punkt in einem 2D-Raum) und die dritte Dimension. Dies könnte Ihnen helfen, ein besseres Verständnis der zugrunde liegenden Mechanik zu erhalten. hoffe, das hilft

Denken der Physik. Ein Objekt hat eine Position (x, y, z) und einen Bewegungsvektor (a, b, c). Ihre Aufgabe sollte an seiner Position existieren; es hat einen Bewegungsvektor mit ihm verbunden, dass seine Dynamik beschreibt. Im Fehlen von zusätzlichen Kräften auf dem Objekt, und unter der Annahme, dass Ihr Bewegungsvektor die Bewegung über einen Zeitraum t beschreibt, wird die Position des Objekts zum Zeitpunkt x (x + (a t), y + ( b t), Z + (C * t)).

Kurz gesagt; nicht die aktuelle Position speichern und die nächste Position. Speichern Sie die aktuelle Position und die Dynamik des Objekts. Es ist einfach genug, um „die Uhr ticken“ und aktualisieren Sie die Lage des Objekts, indem Sie einfach den Schwung in die Position hinzugefügt wird.

Ladengeschwindigkeit als struct Point3f, und dann sind Sie so etwas wie diese:

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

Im Wesentlichen ist die Geschwindigkeit, wie viel Sie die Position wollen jede Sekunde / tick ändern / was auch immer.

Sie möchten den Vektor Mathematik X_{i+1} = X_{i} + Vt implementieren. Für die Xs und V Vektoren repräsentierte Position und die Geschwindigkeit ist, und t die Zeit darstellt. Ich habe die Strecke entlang der Strecke durch die Zeit parametriert, weil ich ein Physiker bin, aber es ist wirklich die natürlichste Sache zu tun. Normalisieren der Geschwindigkeitsvektor, wenn Sie Spurabstand (das heißt Skala V so dass V.x*V.x + V.y*V.y + V.z*V.z = 1) geben wollen.

Mit dem struct oben macht es natürlich, die Elemente zuzugreifen, aber nicht so bequem, die zusätzlich zu tun: Arrays für die besser ist. Wie folgt aus:

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

// initialize

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

Mit einer Union, können Sie die Vorteile von beiden erhalten:

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;

Wenn Sie sowohl die Position als auch die Geschwindigkeit des mit dem Teilchen assoziieren (eine sehr vernünftige Sache zu tun) Sie eine Struktur aufzubauen, die zwei Vektoren unterstützen

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

und eine Update-Routine ausgeführt, die in etwa wie folgt aussieht:

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

AFAIK gibt es hauptsächlich zwei Möglichkeiten, wie Sie die neue Position berechnen kann. Eine davon ist wie die andere explaint hat eine explizite Geschwindigkeit zu verwenden. Die andere Möglichkeit ist die letzten und die aktuelle Position zu speichern und die Verlet Integration zu verwenden. Beide Wege haben ihre Vor- und Nachteile. Sie könnten auch einen Blick auf dieses interresting rel="nofollow.

Wenn Sie versuchen, entlang einer geraden Linie zwischen zwei Punkten zu bewegen, können Sie die Interpolation Formel verwenden:

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

P (t) Position des Punktes die berechnete ist, t ein skalarer von 0 bis 1 reicht ist, P1 und P2 sind die Endpunkte, und die Addition in der obigen ist die Vektoraddition (so gelten Sie diese Formel separat auf dem x, y und z-Komponenten der Punkte). Wenn t = 0, erhalten Sie P1; wenn t = 1, erhalten Sie P2 und für Zwischenwerte, einen Punkt teilweise entlang der Linie zwischen P1 und P2 erhalten. So t = 0,5 Ihnen den Mittelpunkt zwischen P1 und P2 gibt, t = 0,333333 gibt Ihnen den Punkt 1/3 des Weges von P1 bis P2 usw. Die Werte von t außerhalb des Bereichs [0, 1], um Punkte entlang extrapolieren die Linie außerhalb des Segments von P1 bis P2.

die Interpolation Formel kann besser sein als eine Geschwindigkeit Berechnung und Zugabe wiederholt, wenn die Geschwindigkeit gering ist im Vergleich zu dem Abstand zwischen den Punkten, weil Sie den Rundungsfehler zu begrenzen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top