Comment interpoler autour d'un rectangle?


11

Je veux faire une animation fantaisiste où un point se déplace autour d'un rectangle. Je veux trouver la position du point à la fois t.

Le rectangle est donné par X, Y, Widthet Height.

un rectangle, avec un chemin dans le sens horaire autour

Existe-t-il un algorithme pour cela?

J'ai utilisé sin/ cospour les cercles. Quelle est l'approche équivalente pour les rectangles?


1
Pas une réponse complète, donc un commentaire. Je ne pense pas que vous puissiez diviser cet achat 1/4 si vous n'avez pas un quad, mais un rectangle. Mais ce que vous pouvez faire, si vous connaissez le temps maximum qu'il faut pour faire le tour est: Calculez la circonférence s et utilisez la formule s / a = v pour calculer votre vitesse v.
M0rgenstern

Réponses:


15

Je suppose que votre t va de 0 à 1 . (Sinon, multipliez-le simplement pour le mettre à l'échelle de manière appropriée.)

interpolation rectangle

Déterminez la proportion ( 0 - 1 ) de chaque côté du périmètre. ( longueur latérale / périmètre total )

Pour trouver la quantité de chaque côté «remplie» au temps t , parcourez les côtés, en soustrayant leurs proportions jusqu'à ce que t soit épuisé à une valeur négative. Ce dernier bord (qui a fait t devenir négatif) est rempli par une proportion de (longueur latérale + restant) / longueur latérale . Le reste n'est pas rempli.

Pour obtenir la position exacte du vecteur à t , multipliez le vecteur de chaque côté par la proportion de ce côté qui est rempli et ajoutez-les.

Cela fonctionne pour n'importe quel polygone!

interpolation de polygone arbitraire


2

Le sinus et le cosinus de t sont respectivement les coordonnées y et x d'un point sur le cercle formant un angle t avec l'axe x. Pas besoin de ça dans un rectangle! Un rectangle est composé de quatre lignes. Si tva de 0à 1, il atteint le point (px,py)à t==0et à (qx,qy)à t==1avec la ligne donnée par:

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

si au lieu de 0et 1, le temps passe de t0à t1, vous pouvez d'abord normaliser le temps, puis appliquer la formule ci-dessus.

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

Maintenant, pour votre rectangle, divisez en quatre cas avec un ifpour chaque bord qui couvre l'un des intervalles de temps et appliquez un mouvement de ligne.

Notez que si votre rectangle est aligné sur l'axe, vous aurez toujours la valeur x ou la valeur y qui est constante. Par exemple, pour t entre 0et a/4(et en supposant que (X, Y) est en bas à gauche),

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

Ce qui équivaut également à:

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

1

Je ne sais pas s'il existe un algorithme réel pour cela, mais j'en ai créé un moi-même (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;
}

Vous devez transformer les variables xet ypour obtenir votre animation aussi grande ou petite que vous le souhaitez (en multipliant) et où vous le souhaitez (en ajoutant / en soustrayant de x et y).

Je n'ai pas testé ce code, mais je pense qu'il devrait fonctionner. Cela devrait également fonctionner pour tout polygone avec un nombre quelconque de points (vous pouvez également utiliser un peu de code pour générer le polygone).


1

Donné :

a=total time

perimeter = WIDTH *2 + HEIGTH * 2;

Compte tenu du temps, T1comment monter Psur le périmètre (en supposant une position droite à 0,0)?

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

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

maintenant une géométrie scool primaire facile et en mathématiques (qui espérez - vous me) pour obtenir P.xet P.ydedistT1

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.