Calcul de la position des points dans un cercle


87

Je suis un peu aveugle à ce sujet pour le moment. J'ai un problème où je dois calculer la position des points autour d'un point central, en supposant qu'ils sont tous équidistants du centre et l'un de l'autre.

Le nombre de points est variable donc DrawCirclePoints(int x) je suis sûr qu'il y a une solution simple, mais pour la vie de moi, je ne peux pas la voir :)


1
Tout le monde a donné d'excellentes réponses, follement rapides, alors j'ai
coché

Réponses:


72

Un point à l'angle thêta sur le cercle dont le centre est (x0,y0)et dont le rayon est rest (x0 + r cos theta, y0 + r sin theta). Choisissez maintenant des thetavaleurs régulièrement espacées entre 0 et 2pi.


La question classique est la valeur de pi 3,14 ou 180? (c.-à-d. l'angle est-il en degrés ou
radians

Certainement des radians. Si vous utilisez des degrés, vous avez besoin d'angles compris entre 0 et 360 à la place.
Gareth McCaughan

7
(La valeur de pi est de 3,14ish, quelle que soit la façon dont vous préférez écrire les angles, bien sûr. C'est ce que c'est.)
Gareth McCaughan

87

Étant donné une longueur de rayon r et un angle t en radians et le centre d'un cercle (h, k) , vous pouvez calculer les coordonnées d'un point sur la circonférence comme suit (il s'agit d'un pseudo-code, vous devrez l'adapter à votre Langue):

float x = r*cos(t) + h;
float y = r*sin(t) + k;

Vous avez inversé les fonctions cos et sin devrait être sin pour x et cos pour y. Pas l'inverse.
Andreas

18
Mon diplôme en mathématiques, ainsi que toutes les autres réponses ici, disent que vous avez tort.
Brian Driscoll

2
Hm .. bien sur le wikipedia suédois, il dit que le péché est l'axe des x Je sais que ce n'est pas une source sécurisée, mais j'ai ensuite utilisé sin sur x et cos sur y mon cube a commencé à se déplacer dans la bonne direction. Même mon professeur de mathématiques a fait remarquer que je les ai retournés. Pouvez-vous penser à une autre raison pour laquelle mon cube se déplacerait selon un schéma étrange loin de l'emplacement cible, puis je les ai retournés pour se déplacer vers sa position?
Andreas

C'est le code que j'ai écrit peut-être pourriez-vous dire pourquoi cela fonctionne avec eux retourné? jsfiddle.net/Lf5sZ
Andreas

3
Dans les coordonnées d'écran, l'axe y positif est inversé, ce qui est logique.
Brian Driscoll

51

Voici une solution utilisant C #:

void DrawCirclePoints(int points, double radius, Point center)
{
    double slice = 2 * Math.PI / points;
    for (int i = 0; i < points; i++)
    {
        double angle = slice * i;
        int newX = (int)(center.X + radius * Math.Cos(angle));
        int newY = (int)(center.Y + radius * Math.Sin(angle));
        Point p = new Point(newX, newY);
        Console.WriteLine(p);
    }
}

Exemple de sortie de DrawCirclePoints(8, 10, new Point(0,0));:

{X=10,Y=0}
{X=7,Y=7}
{X=0,Y=10}
{X=-7,Y=7}
{X=-10,Y=0}
{X=-7,Y=-7}
{X=0,Y=-10}
{X=7,Y=-7}

Bonne chance!


1
Excellent! Cela a très bien fonctionné pour moi, je l'ai déjà traduit en php-cairo et fonctionne très bien!
Melsi

je cherche à faire le même genre de tâche, mais la mienne dépend du Triggertrap / SeekArc · GitHub, quand un utilisateur déplace le pouce, je veux placer une image pour indiquer la progression sélectionnée de la personne .... tout ce que j'ai essayé de me donner les points un peu et le pas une perfec
Ruyonga Dan

9

En utilisant l'une des réponses ci-dessus comme base, voici l'exemple Java / Android:

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    RectF bounds = new RectF(canvas.getClipBounds());
    float centerX = bounds.centerX();
    float centerY = bounds.centerY();

    float angleDeg = 90f;
    float radius = 20f

    float xPos = radius * (float)Math.cos(Math.toRadians(angleDeg)) + centerX;
    float yPos = radius * (float)Math.sin(Math.toRadians(angleDeg)) + centerY;

    //draw my point at xPos/yPos
}

4

Placer un nombre dans un chemin circulaire

// variable

let number = 12; // how many number to be placed
let size = 260; // size of circle i.e. w = h = 260
let cx= size/2; // center of x(in a circle)
let cy = size/2; // center of y(in a circle)
let r = size/2; // radius of a circle

for(let i=1; i<=number; i++) {
  let ang = i*(Math.PI/(number/2));
  let left = cx + (r*Math.cos(ang));
  let top = cy + (r*Math.sin(ang));
  console.log("top: ", top, ", left: ", left);
}

3

Je devais le faire sur le Web, alors voici une version coffeescript de la réponse de @ scottyab ci-dessus:

points = 8
radius = 10
center = {x: 0, y: 0}

drawCirclePoints = (points, radius, center) ->
  slice = 2 * Math.PI / points
  for i in [0...points]
    angle = slice * i
    newX = center.x + radius * Math.cos(angle)
    newY = center.y + radius * Math.sin(angle)
    point = {x: newX, y: newY}
    console.log point

drawCirclePoints(points, radius, center)

3

Solution PHP:

class point{
    private $x = 0;
    private $y = 0;
    public function setX($xpos){
        $this->x = $xpos;
    }
    public function setY($ypos){
        $this->y = $ypos;
    }
    public function getX(){
        return $this->x;
    }
    public function getY(){
        return $this->y;
    }
    public function printX(){
        echo $this->x;
    }
    public function printY(){
        echo $this->y;
    }
}
function drawCirclePoints($points, $radius, &$center){
    $pointarray = array();
    $slice = (2*pi())/$points;
    for($i=0;$i<$points;$i++){
        $angle = $slice*$i;
        $newx = (int)($center->getX() + ($radius * cos($angle)));
        $newy = (int)($center->getY() + ($radius * sin($angle)));
        $point = new point();
        $point->setX($newx);
        $point->setY($newy);
        array_push($pointarray,$point);
    }
    return $pointarray;
}

Je pense que la parenthèse est incorrecte pour $newxet $newy, mettant les coordonnées bien en dehors du rayon du cercle. Essayez $newx = (int)($center->getX() + ($radius * cos($angle)));et similaire pour $newy.
Jason

2

Par souci de complétion, ce que vous décrivez comme «la position des points autour d'un point central (en supposant qu'ils sont tous équidistants du centre)» n'est rien d'autre que des «coordonnées polaires». Et vous demandez moyen de convertir entre coordonnées polaires et cartésiennes qui est donnée à x = r*cos(t), y = r*sin(t).


1

L'angle entre chacun de vos points va être 2Pi/xdonc vous pouvez dire que pour les points, n= 0 to x-1l'angle à partir d'un point 0 défini est2nPi/x .

En supposant que votre premier point est à (r,0)(où r est la distance du point central), les positions par rapport au point central seront:

rCos(2nPi/x),rSin(2nPi/x)

1

Solution de travail en Java:

import java.awt.event.*;
import java.awt.Robot;

public class CircleMouse {

/* circle stuff */
final static int RADIUS = 100;
final static int XSTART = 500;
final static int YSTART = 500;
final static int DELAYMS = 1;
final static int ROUNDS = 5;

public static void main(String args[]) {

    long startT = System.currentTimeMillis();
    Robot bot = null;

    try {
        bot = new Robot();
    } catch (Exception failed) {
        System.err.println("Failed instantiating Robot: " + failed);
    }
    int mask = InputEvent.BUTTON1_DOWN_MASK;

    int howMany = 360 * ROUNDS;
    while (howMany > 0) {
        int x = getX(howMany);
        int y = getY(howMany);
        bot.mouseMove(x, y);
        bot.delay(DELAYMS);
        System.out.println("x:" + x + " y:" + y);
        howMany--;
    }

    long endT = System.currentTimeMillis();
    System.out.println("Duration: " + (endT - startT));

}

/**
 * 
 * @param angle
 *            in degree
 * @return
 */
private static int getX(int angle) {
    double radians = Math.toRadians(angle);
    Double x = RADIUS * Math.cos(radians) + XSTART;
    int result = x.intValue();

    return result;
}

/**
 * 
 * @param angle
 *            in degree
 * @return
 */
private static int getY(int angle) {
    double radians = Math.toRadians(angle);
    Double y = RADIUS * Math.sin(radians) + YSTART;
    int result = y.intValue();

    return result;
}
}

1

Voici une Rversion basée sur la réponse @Pirijan ci-dessus.

points <- 8
radius <- 10
center_x <- 5
center_y <- 5

drawCirclePoints <- function(points, radius, center_x, center_y) {
  slice <- 2 * pi / points
  angle <- slice * seq(0, points, by = 1)

  newX <- center_x + radius * cos(angle)
  newY <- center_y + radius * sin(angle)

  plot(newX, newY)
}

drawCirclePoints(points, radius, center_x, center_y)

1

Voici comment j'ai découvert un point sur un cercle avec javascript, en calculant l'angle (degré) à partir du haut du cercle.

  const centreX = 50; // centre x of circle
  const centreY = 50; // centre y of circle
  const r = 20; // radius
  const angleDeg = 45; // degree in angle from top
  const radians = angleDeg * (Math.PI/180);
  const pointY = centreY - (Math.cos(radians) * r); // specific point y on the circle for the angle
  const pointX = centreX + (Math.sin(radians) * r); // specific point x on the circle for the angle

0

Sur la base de la réponse ci-dessus de Daniel, voici mon point de vue sur Python3.

import numpy


def circlepoints(points,radius,center):
    shape = []
    slice = 2 * 3.14 / points
    for i in range(points):
        angle = slice * i
        new_x = center[0] + radius*numpy.cos(angle)
        new_y = center[1] + radius*numpy.sin(angle)

        p = (new_x,new_y)
        shape.append(p)

    return shape

print(circlepoints(100,20,[0,0]))
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.