2 votes

Animation C# - déplacer un objet d'un point A à un point B ou d'un angle à un autre

Bonjour, je fais une petite animation qui déplace un objet d'un point a à un point b ou par angle/radians.

Voici ce que j'ai actuellement

Point CalcMove(Point pt, double angle, int speed)
    {
        Point ret = pt;

        ret.X = (int)(ret.X + speed * Math.Sin(DegToRad(angle)));
        ret.Y = (int)(ret.Y + speed * Math.Cos(DegToRad(angle)));

        return ret;
    }

mais il ne ressemble pas à ce que j'attendais.

Aidez-nous !

mettre à jour :
oh et j'utilise NETCF


CalcMove(Point pt, double angle, int speed)
"Point pt" est l'emplacement actuel de l'objet. "angle" est l'endroit où l'objet doit aller. "speed" est le pas.


Ainsi, après des jours de travail..
Voici ce sur quoi j'ai travaillé Neko pour Windows Mobile 6.5

1voto

Ed S. Points 70246

Utiliser une matrice de rotation. Ce code permet de se déplacer d'un point (x,y) par theta radians vers un nouveau point (px, px).

Point Rotate(x, y, theta)
    int px = (x * Math.Cos(theta)) - (y * Math.Sin(theta));
    int py = (y * Math.Cos(theta)) + (x * Math.Sin(theta));
    return new Point(px, py);
end

La matrice utilisée ci-dessus,

[cosθ - sinθ][x]
[cosθ + sinθ][y]

Déplace un point autour du cercle dans le sens des aiguilles d'une montre lors de l'utilisation de coordonnées graphiques.

J'ai fait exactement la même chose la semaine dernière. Vous pouvez animer ceci en trouvant le thêta total que vous souhaitez déplacer et en le divisant par le nombre d'images (ou de pas). Maintenant, commencez chaque mouvement à un point arbitraire (par exemple, (0, rayon)) et incrémentez un compteur totalSteps et déplacez toujours à partir de ce point initial . Si vous déplacez simplement le point lui-même à chaque image, vous accumulerez des erreurs, mais si vous vous déplacez toujours du point initial en fonction de l'incrément actuel, en vous arrêtant lorsque l'incrément == totalTheta, ce sera parfait. J'aimerais savoir si cela a du sens.

Je devrais peut-être illustrer un peu plus. Supposons que vous ayez une méthode "BeginMove" :

double totalTheta = 0;
double increment = 0;
double currentTheta = 0;
bool moving = false;
void BeginMove()
{
    totalTheta = (2 * Math.PI) / numObjects;
    increment = totalTheta / steps;
    currentTheta = 0;
    moving = true;
}

Vous disposez maintenant d'une méthode qui met à jour le mouvement à chaque image :

void Update
{
    if (!moving) return;
    // do a min/max to ensure that you never pass totalTheta when incrementing.
    // there will be more error handling, but this is the basic idea.
    currentTheta += increment;
    SomeObject.Location = Rotate(0, radius, currentTheta);
    moving = (currentTheta < totalTheta);
}

Il y aura évidemment plus de logique ici en fonction de votre situation exacte, mais l'idée est la suivante :

  1. Trouvez la valeur totale de la thêta à déplacer.
  2. Trouver l'incrément (totalTheta / pas)
  3. Tenez à jour le total de ce que vous avez déjà déménagé.
  4. Incrémenter le total en cours par l'incrément d'angle avant chaque mouvement.
  5. Chaque mouvement commence au même point (arbitraire) du cercle et tourne en fonction du total courant.
  6. Répéter jusqu'à ce que le total courant == total thêta.

0voto

Andrey Points 36869

Oui, votre formule est un peu incorrecte :

appelons l'angle actuel α et l'angle que vous voulez faire pivoter est β d est la longueur de la ligne : d = sqrt(x x + y y)

Pour calculer les nouvelles coordonnées, nous avons besoin de

sin(α+β) = cos β sin α + sin β cos α

cos(α+β) = cos α cos β - sin α sin β

cos α = x / d sin α = y / d

Les nouvelles coordonnées seront : x = sin(α+β)*d y = cos(α+β)*d

tous ensemble :

double d = Math.Sqrt(x*x + y*y);
double sina = pt.Y / d;
double cosa = pt.X / d;
double sinb = Math.Sin(DegToRad(angle));
double cosb = Math.Cos(DegToRad(angle));

ret.X = (int)(cosb*sina + sinb*cosa);
ret.Y = (int)(cosa*cosb - sina*sinb);

0voto

jaysonragasa Points 444

Après tous les essais infructueux des codes suggérés (honte à moi) je viens de trouver une très vieille solution.

pour dessiner un cercle par xypixel, voici comment je l'ai fait auparavant dans TurboBasic(dos)

x = xcenter + radius * Cos(radian)<br/>
y = ycenter + radius * Sin(radian)

J'ai appliqué la même idée en faisant du centre xy l'emplacement de l'objet, le rayon est juste une valeur qui s'incrémente (par étape), et le radian est calculé à partir du dernier emplacement xy de l'objet et de la destination xy.

J'ai maintenant mon objet qui se déplace d'un point A à un point B

-1voto

Matt Points 313

Pour l'angle, la formule est la suivante : pas vers le haut / pas vers la droite = tan (angle en degrés)

Ainsi, si vous souhaitez que quelque chose se déplace à un angle de 45° :

tan (45) = 1. Puisque 1= 1/1 : pour chaque pixel déplacé vers la droite, un pixel est déplacé vers le haut.

pour déplacer un objet à un angle de 35° : tan (35) = 0,7.... Puisque 0,7 = 1/0,7 : déplacer un pixel vers le haut pour chaque 0,7 pixel vers la droite OU 10 pixels vers le haut pour chaque 7 pixels vers la droite.

Notez que si vous essayez de vous déplacer de 90°, vous vous déplacerez d'une infinité de pas vers le haut pour chaque pas vers la droite (vous vous déplacerez directement vers le haut), car tan(90) = ∞

mise à jour : Exemple de code pour montrer ce que je veux dire. Il fonctionne avec une pente de la ligne que le point doit parcourir (montée sur descente) :

Point CalcMove(Point pt, double angle, int speed)
    {
        Point ret = pt;
        if (angle == 90) { ret.Y += speed; }
        else if (angle == 270) { ret.Y -= speed; }
        else {
             ret.Y = (int)(ret.X + speed * Math.Tan(angle));
             ret.X = (int)(ret.Y + speed);
        }
        return ret;
    }

Notez mon erreur de rattrapage de tan(90) et tan(270)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X