Wie interpoliere ich um ein Rechteck?


11

Ich möchte eine ausgefallene Animation erstellen, bei der sich ein Punkt um ein Rechteck bewegt. Ich möchte die Position des Punktes zu einem Zeitpunkt finden t.

Das Rechteck ist gegeben durch X, Y, Widthund Height.

ein Rechteck mit einem Pfad im Uhrzeigersinn

Gibt es dafür einen Algorithmus?

Ich habe sin/ cosfür Kreise verwendet. Was ist der äquivalente Ansatz für Rechtecke?


1
Keine vollständige Antwort, daher ein Kommentar. Ich glaube nicht, dass Sie diesen Kauf 1/4 teilen können, wenn Sie kein Quad, sondern ein Rechteck haben. Aber was Sie tun können, wenn Sie die maximale Zeit kennen, die es dauern sollte, um
herumzugehen,

Antworten:


15

Ich gehe davon aus, dass Ihr t von 0 auf 1 geht . (Wenn nicht, multiplizieren Sie einfach, um es entsprechend zu skalieren.)

Rechteckinterpolation

Finden Sie heraus, welcher Anteil ( 0 - 1 ) jede Seite am Umfang hat. ( Seitenlänge / Gesamtumfang )

Um herauszufinden, wie viel von jeder Seite zum Zeitpunkt t „ausgefüllt“ ist , durchlaufen Sie die Seiten und subtrahieren ihre Proportionen, bis t auf einen negativen Wert abgereichert ist. Diese letzte Kante (die dazu führte, dass t negativ wurde) wird mit einem Anteil von (Seitenlänge + verbleibende) / Seitenlänge gefüllt . Der Rest ist nicht gefüllt.

Um die genaue Vektorposition bei t zu erhalten , multiplizieren Sie den Vektor jeder Seite mit dem Anteil der gefüllten Seite und addieren Sie sie.

Dies funktioniert tatsächlich für jedes Polygon!

beliebige Polygoninterpolation


2

Der Sinus und der Cosinus von t sind jeweils die y- und x-Koordinate eines Punktes auf dem Kreis, der mit der x-Achse einen Winkel t bildet. Keine Notwendigkeit dafür in einem Rechteck! Ein Rechteck besteht aus vier Linien. Wenn taus geht erreichen sie den Punkt an und auf der Linie gegeben durch:01(px,py)t==0(qx,qy)t==1

(l(x),l(y)) = (t*qx + (1-t)*px, t*qy + (1-t)*py)

Wenn anstelle von 0und die 1Zeit von t0bis t1abläuft, können Sie zuerst die Zeit normalisieren und dann die obige Formel anwenden.

(l(x),l(y)) = (  ((t-t0)/(t1-t0))*qx + ((t1-t)/(t1-t0))*px, ((t-t0)/(t1-t0))*qy + ((t1-t)/(t1-t0))*py  )

Teilen Sie nun für Ihr Rechteck in vier Fälle mit einem iffür jede Kante, die einen Zeitraum abdeckt, und wenden Sie eine Linienbewegung an.

Beachten Sie, dass Sie immer entweder den x-Wert oder den y-Wert haben, wenn Ihr Rechteck achsenausgerichtet ist. Zum Beispiel für t zwischen 0und a/4(und angenommen (X, Y) ist unten links),

(l(x),l(y)) = ((4*t/a)*(X+Width) + (1-4*t/a)*(X), Y+Height)

Welches ist auch gleich:

(l(x),l(y)) = (X + (1-4*t/a)*(Width), Y+Height)

1

Ich weiß nicht, ob es dafür einen tatsächlichen Algorithmus gibt, aber ich habe selbst einen erstellt (Java):

int points = 4; // for a rectangle
double progress = 0.0; // 0.0 -> 1.0 (with 1.0 being 100%)
double pp = points * progress; // This calculation would otherwise be done multiple times

int p1 = Math.floor(pp);
int p2 = Math.ceil(pp);

while (p1 >= points) p1 -= points;
while (p2 >= points) p2 -= points;

double tmp = 2 * Math.PI / points;

int p1x = Math.cos(tmp * p1);
int p1y = Math.sin(tmp * p1);
int p2x = Math.cos(tmp * p2);
int p2y = Math.sin(tmp * p2);

double p = pp - Math.floor(pp);

int x = (1.0 - p) * p1x + p * p2x; // between -1.0 and 1.0
int y = (1.0 - p) * p2x + p * p2y; // between -1.0 and 1.0

if (p == 0.0) { // prevent a weird glitch when p = 0.0 (I think this is a glitch)
    x = p1x;
    y = p1y;
}

Sie sollten die Variablen xund transformieren y, um Ihre Animation so groß oder klein zu machen, wie Sie möchten (durch Multiplizieren) und wo Sie möchten (Hinzufügen zu / Subtrahieren von x und y).

Ich habe diesen Code nicht getestet, aber ich denke, er sollte funktionieren. Dies sollte auch für jedes Polygon mit einer beliebigen Anzahl von Punkten funktionieren (Sie können auch einen Teil des Codes zum Generieren des Polygons verwenden).


1

Gegeben :

a=total time

perimeter = WIDTH *2 + HEIGTH * 2;

Gegebene Zeit, T1wie man Pauf den Umfang kommt (unter der Annahme einer richtigen Position bei 0,0)?

T1=T1%a; //use mod to have T1<a

distT1 = (T1*Perimeter)/a; //distance traveled in time T1

jetzt einige einfache primäre Schulgeometrie und Mathematik (die hoffen, dass Sie mich verschonen) zu erhalten P.xund P.yvondistT1

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.