web-dev-qa-db-fra.com

Faites pivoter un point autour d'un autre point

J'ai une tâche pour dessiner un graphique spécifique. Dans le cadre de cette tâche, j'ai besoin de faire pivoter certains points de 45 degrés.

J'ai déjà passé 2 jours à essayer de calculer une formule, mais je ne pouvais tout simplement pas le faire correctement. Je cherche partout sur la place, y compris ce site particulier, je suis très proche, mais je ne suis toujours pas là.

Ici c'est: j'ai besoin de dessiner 4 points différents

J'ai une formule spécifique pour calculer la position, qui est hors de portée de la question, mais voici ce que je reçois à la suite de cela:

int radius = 576;
int diameter = radius * 2;
Point blueA = new Point(561, 273);
Point greenB = new Point(273, 561);
Point yellowC = new Point (849, 561);
Point redD = new Point (561, 849);

result

Maintenant, j'ai besoin de faire pivoter ces points sur 45 degrés. J'utilise le code suivant pour y parvenir:

double rotationAngle = 45;
double rotationRadians = rotationAngle * (Math.PI / 180);
int center = radius;    
result.X = (int)(Math.Cos(rotationRadians) * ((double)result.X - (double)center) - (double)Math.Sin(rotationRadians) * ((double)result.Y - center) + (double)center);
result.Y = (int)(Math.Sin(rotationRadians) * ((double)result.X - (double)center) + (double)Math.Cos(rotationRadians) * ((double)result.Y - center) + (double)center);

Mais c'est ce que j'obtiens:

Result

Toute aide serait très appréciée

18
Vlad Spreys

Le problème est int center = radius que vous définissez int radius = 576. Cela n'a pas de sens que vous tournez sûrement sur un point qui devrait avoir un emplacement X et Y.

Étant donné que vous tournez autour de l'origine, le centre x et y devraient tous deux être 0 ne pas 576.

Donc, étant donné que, essayez ceci.

/// <summary>
/// Rotates one point around another
/// </summary>
/// <param name="pointToRotate">The point to rotate.</param>
/// <param name="centerPoint">The center point of rotation.</param>
/// <param name="angleInDegrees">The rotation angle in degrees.</param>
/// <returns>Rotated point</returns>
static Point RotatePoint(Point pointToRotate, Point centerPoint, double angleInDegrees)
{
    double angleInRadians = angleInDegrees * (Math.PI / 180);
    double cosTheta = Math.Cos(angleInRadians);
    double sinTheta = Math.Sin(angleInRadians);
    return new Point
    {
        X =
            (int)
            (cosTheta * (pointToRotate.X - centerPoint.X) -
            sinTheta * (pointToRotate.Y - centerPoint.Y) + centerPoint.X),
        Y =
            (int)
            (sinTheta * (pointToRotate.X - centerPoint.X) +
            cosTheta * (pointToRotate.Y - centerPoint.Y) + centerPoint.Y)
    };
}

Utiliser comme si.

Point center = new Point(0, 0); 
Point newPoint = RotatePoint(blueA, center, 45);

Évidemment si le point central est toujours 0,0 Ensuite, vous pouvez simplifier la fonction en conséquence, sinon rendre le point central facultatif via un paramètre par défaut ou en surcharge de la méthode. Vous voudriez probablement probablement encapsuler une partie des mathématiques réutilisables dans d'autres méthodes statiques.

par exemple.

/// <summary>
/// Converts an angle in decimal degress to radians.
/// </summary>
/// <param name="angleInDegrees">The angle in degrees to convert.</param>
/// <returns>Angle in radians</returns>
static double DegreesToRadians(double angleInDegrees)
{
   return angleInDegrees * (Math.PI / 180);
}

/// <summary>
/// Rotates a point around the Origin
/// </summary>
/// <param name="pointToRotate">The point to rotate.</param>
/// <param name="angleInDegrees">The rotation angle in degrees.</param>
/// <returns>Rotated point</returns>
static Point RotatePoint(Point pointToRotate, double angleInDegrees)
{
   return RotatePoint(pointToRotate, new Point(0, 0), angleInDegrees);
}

Utiliser comme si.

Point newPoint = RotatePoint(blueA, 45);

Enfin, si vous utilisez GDI, vous pouvez également faire simplement un RotateTransform. Voir: http://msdn.microsoft.com/en-us/en-us bibliothèque/a0z3f662.aspx

Graphics g = this.CreateGraphics();
g.TranslateTransform(blueA);
g.RotateTransform(45);
42
Fraser

VOUS VÊTEZ QUE VOUS ÊTES SEAT WEAIRE POUR MOI. Je pense dx = r * cos (theta) et dy = r * sin (theta).

Voici un petit programme que j'ai écrit parce que cela me dérangeait et je n'ai pas fait de mathématiques, c'est des années.

Point center = new Point() { X = 576, Y = 576 };

Point previous = new Point() { X = 849, Y=561 };
double rotation = 45;
double rotationRadians = rotation * (Math.PI / 180);

//get radius based on the previous point and r squared = a squared + b squared
double r = Math.Sqrt(Math.Pow(previous.X - center.X, 2) + Math.Pow(previous.Y - center.Y, 2));
Console.WriteLine("r = " + r.ToString());

//calculate previous angle
double previousAngle = Math.Atan((previous.Y - center.Y) / (previous.X - center.X));
Console.WriteLine("Previous angle: " + previousAngle.ToString());

double newAngle = previousAngle + rotationRadians;

Point newP = new Point();
newP.X = center.X + r * Math.Cos(newAngle);
newP.Y = center.Y + r * Math.Sin(newAngle);

Console.WriteLine("(" + newP.X.ToString() + ", " + newP.Y.ToString() + ")");

Console.ReadLine();
1
Nick Bray