Calcolo della posizione dei punti in un cerchio


88

Al momento ho un po 'di vuoto mentale su questo. Ho un problema in cui devo calcolare la posizione dei punti attorno a un punto centrale, assumendo che siano tutti equidistanti dal centro e l'uno dall'altro.

Il numero di punti è variabile quindi DrawCirclePoints(int x) sono sicuro che ci sia una soluzione semplice, ma per la vita di me, non riesco proprio a vederlo :)


1
Tutti hanno dato ottime risposte, pazzamente veloce, quindi ho dato il segno di spunta alla prima risposta :) Sono stati tutti fantastici :)
JoeBrown

Risposte:


74

Un punto all'angolo theta sul cerchio il cui centro è (x0,y0)e il cui raggio rè (x0 + r cos theta, y0 + r sin theta). Ora scegli i thetavalori equidistanti tra 0 e 2 ppi.


La domanda classica è il valore di pi 3,14 o 180? (cioè l'angolo è in gradi o radianti?)
nirvanaswap

Sicuramente radianti. Se usi i gradi, hai bisogno di angoli tra 0 e 360.
Gareth McCaughan

8
(Il valore di pi greco è 3.14ish indipendentemente da come preferisci scrivere gli angoli, ovviamente. È quello che è.)
Gareth McCaughan

88

Data una lunghezza del raggio re un angolo t in radianti e il centro di un cerchio (h, k) , puoi calcolare le coordinate di un punto sulla circonferenza come segue (questo è pseudo-codice, dovrai adattarlo al tuo linguaggio):


Hai invertito le funzioni cos e sin dovrebbero essere sin per xe cos per y. Non il contrario.
Andreas

18
La mia laurea in matematica, così come ogni altra risposta qui, dice che sei sbagliato.
Brian Driscoll

2
Hm .. beh sulla wikipedia svedese si dice che il peccato è l'asse x so che questa non è una fonte sicura ma poi ho usato sin su xe cos su y il mio cubo ha iniziato a muoversi nella giusta direzione. Anche il mio insegnante di matematica ha sottolineato che li ho girati. Riesci a pensare a qualche altro motivo per cui il mio cubo si sarebbe spostato in uno strano schema lontano dalla posizione di destinazione e poi li ho girati e si muoveva nella sua posizione?
Andreas

Questo è il codice che ho scritto forse potresti dirmi perché funziona con loro capovolti? jsfiddle.net/Lf5sZ
Andreas

3
Nelle coordinate dello schermo l'asse y positivo è invertito, quindi ha senso.
Brian Driscoll

52

Ecco una soluzione usando 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);
    }
}

Esempio di output da 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}

In bocca al lupo!


1
Eccellente! Ha funzionato alla grande per me, l'ho già tradotto in php-cairo e funziona alla grande!
Melsi

sto cercando di fare lo stesso tipo di attività, tuttavia il mio dipende da Triggertrap / SeekArc · GitHub, quando un utente sposta il pollice, voglio posizionare un'immagine per indicare il progresso selezionato della persona ... tutto quello che ho provato a darmi i punti un po 'fuori e il non è un
perfetto

1
Perfetto grazie! Proprio quello che stavo cercando.
Patrick Hund

9

Usando una delle risposte precedenti come base, ecco l'esempio 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

Posizionare un numero in un percorso circolare

// 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

Ho dovuto farlo sul web, quindi ecco una versione coffeescript della risposta di @ scottyab sopra:

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

Per ragioni di completamento, ciò che descrivi come "posizione dei punti attorno a un punto centrale (supponendo che siano tutti equidistanti dal centro)" non è altro che "coordinate polari". E si sta chiedendo modo per convertire tra coordinate polari e cartesiane , che è dato come x = r*cos(t), y = r*sin(t).


3

Soluzione 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;
}

Credo la parentesi non è corretto per $newxe $newy, mettendo il coordinate modo fuori del raggio del cerchio. Prova $newx = (int)($center->getX() + ($radius * cos($angle)));e simili per $newy.
Jason

1

L'angolo tra ciascuno dei tuoi punti sarà 2Pi/xcosì puoi dire che per i punti n= 0 to x-1l'angolo da un punto 0 definito è 2nPi/x.

Supponendo che il tuo primo punto sia in (r,0)(dove r è la distanza dal punto centrale), le posizioni relative al punto centrale saranno:

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

1

Soluzione funzionante in 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

Ecco una Rversione basata sulla risposta di @Pirijan sopra.

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

Ecco come ho scoperto un punto su un cerchio con javascript, calcolando l'angolo (gradi) dalla parte superiore del cerchio.

  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

Sulla base della risposta di Daniel sopra, ecco la mia opinione sull'uso di 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]))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.