web-dev-qa-db-fra.com

Calcul du point sur la circonférence d'un cercle à partir de l'angle en C #?

J'imagine que c'est une question simple, mais j'obtiens des résultats étranges avec mon code actuel et je n'ai pas les connaissances en mathématiques pour bien comprendre pourquoi. Mon objectif est simple, comme indiqué dans le titre: je veux juste trouver le point à une certaine distance et un angle d'un point central.

Mon code actuel:

Point centerPoint = new Point ( 0, 0 );
Point result      = new Point ( 0, 0 );
double angle      = 0.5; //between 0 and 2 * PI, angle is in radians
int distance      = 1000;

result.Y = centerPoint.Y + (int)Math.Round( distance * Math.Sin( angle ) );
result.X = centerPoint.X + (int)Math.Round( distance * Math.Cos( angle ) );

En général, cela semble fonctionner assez raisonnablement, mais je rencontre des problèmes à divers endroits, notamment lorsque l'angle correspond à des points dans les axes négatifs x et y. De toute évidence, je fais quelque chose de mal - des réflexions sur ce que c'est?

MISE À JOUR: C'était mon erreur, ce code fonctionne très bien - les quelques valeurs aberrantes qui ne fonctionnaient pas étaient en fait dues à un bug dans la façon dont l'angle pour 1.5PI était calculé. Je pensais avoir vérifié cela assez bien, mais évidemment pas. Merci à tous pour votre temps, j'espère que le code de travail ci-dessus s'avérera utile pour quelqu'un d'autre.

40
x4000

Vous avez oublié d'ajouter le point central:

result.Y = (int)Math.Round( centerPoint.Y + distance * Math.Sin( angle ) );
result.X = (int)Math.Round( centerPoint.X + distance * Math.Cos( angle ) );

Le reste devrait être ok ... (quels résultats étranges avez-vous obtenus? Pouvez-vous donner une entrée exacte?)

34
MartinStettner

Tout d'abord, puisque vous êtes en radians, il est probablement avantageux de définir votre angle comme tel:

double angle = (Math.PI / 3); // 60 degrees...

Les fonctions elles-mêmes fonctionnent bien. L'arrondi n'affectera votre réponse que si votre distance est suffisamment petite. En dehors de cela, les réponses devraient très bien sortir.

Si c'est l'arrondi qui vous inquiète, rappelez-vous que par défaut, .NET fait arrondi du banquier , et vous voudrez peut-être:

result.X = (int)Math.Round(centerPoint.X + distance * Math.Cos(angle), MidpointRounding.AwayFromZero);
result.Y = (int)Math.Round(centerPoint.Y + distance * Math.Sin(angle), MidpointRounding.AwayFromZero);

au lieu.

De plus, dans la question que vous voulez distance X et angle Y ... je suppose que vous ne reliez pas cela au point (X,Y), parce que c'est complètement différent.

La formule de distance est:

double distance = Math.Sqrt((centerPoint.X + result.X)^2 + (centerPoint.Y + result.Y)^2);
6
John Rasch

Une version Swift3

func pointOnCircle(radius: Double, angleInDegrees: Double, Origin: CGPoint) -> CGPoint {
    let x = abs(Double(Origin.x) + radius * cos(angleInDegrees * (.pi / 180)))
    let y = abs(Double(Origin.y) - radius * sin(angleInDegrees * (.pi / 180)))

    return CGPoint(x: x, y: y)
}
3
Joe Susnick

Sans plus d'informations sur les erreurs exactes, il est difficile de dire ce qui ne va pas. Les équations semblent correctes et devraient fonctionner. Êtes-vous sûr que les angles que vous passez sont corrects pour des angles> 90 degrés? La seule autre chose à laquelle je pourrais penser serait que vous multipliez la distance (un int) par le résultat de Math.sin (double) mais cela ne devrait pas vraiment être un problème.

1
JonBWalsh
-(NSMutableArray *)GetPointsForCircle
    {
       NSMutableArray *Points = [[NSMutableArray alloc] init];
       CGPoint CenterPoint = CGPointMake(160, 230);
       CGPoint Point;
       for (float Angel = 0; Angel <= 360; Angel+= 60)
         {
           Point.x = CenterPoint.x + 100 * cos(Angel);
           Point.y = CenterPoint.y + 100 * sin(Angel);
           [Points addObject:[NSValue valueWithCGPoint:Point]];
         }
       return Points;
    }

    - (CGPoint)pointOnCircle:(int)thisPoint withTotalPointCount:(int)totalPoints
     {
        CGPoint centerPoint = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2);
        float radius = 100.0;
        float angle = ( 2 * M_PI / (float)totalPoints ) * (float)thisPoint;
        CGPoint newPoint;
        newPoint.x = (centerPoint.x) + (radius * cosf(angle));
        newPoint.y = (centerPoint.y) + (radius * sinf(angle));
        return newPoint;   
    }
1
Waseem

Je ne sais pas c #, de toute façon si vous essayez de dessiner les points quelque part, vous devez considérer le fait que l'axe Y se plie de haut en bas de l'écran, donc votre élément sin devrait doivent être - sin (...) et non + sin (...)

alors

result.Y = centerPoint.Y + (int)Math.Round( distance * Math.Sin( angle ) );

devrait devenir:

result.Y = centerPoint.Y - (int)Math.Round( distance * Math.Sin( angle ) );

Si vous n'essayez pas de les dessiner, je ne pouvais pas imaginer quel est le problème, pouvez-vous donner un exemple?

0
Andrea Ambu