Berechnung der Position von Punkten in einem Kreis


86

Ich habe im Moment ein bisschen Bedenken. Ich habe ein Problem, bei dem ich die Position von Punkten um einen zentralen Punkt berechnen muss, vorausgesetzt, sie sind alle gleich weit vom Zentrum und voneinander entfernt.

Die Anzahl der Punkte ist variabel, daher DrawCirclePoints(int x) bin ich mir sicher, dass es eine einfache Lösung gibt, aber für mein Leben kann ich sie einfach nicht sehen :)


1
Alle gaben großartige Antworten, verrückt schnell, also gab ich der ersten Antwort den Haken :) Sie waren alle großartig :)
JoeBrown

Antworten:


71

Ein Punkt im Winkel Theta auf dem Kreis, dessen Mittelpunkt (x0,y0)und dessen Radius rist (x0 + r cos theta, y0 + r sin theta). Wählen Sie nun thetaWerte mit gleichmäßigem Abstand zwischen 0 und 2 pi.


Die klassische Frage ist der Wert von pi 3,14 oder 180? (dh ist der Winkel in Grad oder Bogenmaß?)
Nirvanaswap

Auf jeden Fall Bogenmaß. Wenn Sie Grad verwenden, benötigen Sie stattdessen Winkel zwischen 0 und 360.
Gareth McCaughan

7
(Der Wert von pi ist 3,14ish, unabhängig davon, wie Sie Winkel schreiben möchten. Es ist, was es ist.)
Gareth McCaughan

86

Bei einer Radiuslänge r und einem Winkel t im Bogenmaß und dem Mittelpunkt eines Kreises (h, k) können Sie die Koordinaten eines Punktes auf dem Umfang wie folgt berechnen (dies ist ein Pseudocode, den Sie an Ihren anpassen müssen Sprache):

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

Sie haben cos umgedreht und sin-Funktionen sollten sin für x und cos für y sein. Nicht umgekehrt.
Andreas

18
Mein Abschluss in Mathematik sowie jede andere Antwort hier sagen, dass Sie falsch sind.
Brian Driscoll

2
Hm .. auf der schwedischen Wikipedia heißt es, dass Sünde die x-Achse ist. Ich weiß, dass dies keine sichere Quelle ist, aber dann habe ich sin auf x und cos auf y verwendet. Mein Würfel begann sich in die richtige Richtung zu bewegen. Sogar mein Mathematiklehrer wies darauf hin, dass ich sie umgedreht habe. Können Sie sich einen anderen Grund vorstellen, warum sich mein Würfel in einem seltsamen Muster vom Zielort wegbewegt und ich sie dann umgedreht habe, bis er sich in seine Position bewegt?
Andreas

Dies ist der Code, den ich geschrieben habe. Vielleicht können Sie erkennen, warum er mit ihnen funktioniert. jsfiddle.net/Lf5sZ
Andreas

3
In Bildschirmkoordinaten ist die positive y-Achse umgekehrt, was Sinn macht.
Brian Driscoll

50

Hier ist eine Lösung mit 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);
    }
}

Beispielausgabe von 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}

Viel Glück!


1
Ausgezeichnet! Hat super für mich funktioniert, ich habe es bereits in php-cairo übersetzt und funktioniert super!
Melsi

Ich möchte die gleiche Art von Aufgabe erledigen, aber meine hängt vom Triggertrap / SeekArc · GitHub ab. Wenn ein Benutzer den Daumen bewegt, möchte ich ein Bild platzieren, um den ausgewählten Fortschritt der Person anzuzeigen ... alles, was ich habe versuchte mir die Punkte ein bisschen zu geben und das nicht perfekt
Ruyonga Dan

9

Anhand einer der oben genannten Antworten als Basis finden Sie hier das Java / Android-Beispiel:

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

Platzieren einer Zahl auf einer Kreisbahn

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

Ich musste dies im Web tun, daher hier eine Coffeescript-Version von @ scottyabs Antwort oben:

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

PHP-Lösung:

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

Ich glaube, die Klammer ist falsch für $newxund $newysetzt die Koordinaten weit außerhalb des Kreisradius. Versuchen Sie $newx = (int)($center->getX() + ($radius * cos($angle)));und ähnlich für $newy.
Jason

2

Der Vollständigkeit halber ist das, was Sie als "Position von Punkten um einen zentralen Punkt (vorausgesetzt, sie sind alle gleich weit vom Zentrum entfernt)" beschreiben, nichts anderes als "Polarkoordinaten". Und Sie fragen nach einer Möglichkeit, zwischen polaren und kartesischen Koordinaten zu konvertieren, die als x = r*cos(t), y = r*sin(t).


1

Der Winkel zwischen jedem Ihrer Punkte wird 2Pi/xso sein, dass Sie sagen können, dass für Punkte n= 0 to x-1der Winkel von einem definierten 0-Punkt ist 2nPi/x.

Angenommen, Ihr erster Punkt liegt bei (r,0)(wobei r der Abstand vom Mittelpunkt ist), dann sind die Positionen relativ zum Mittelpunkt:

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

1

Arbeitslösung 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

Hier ist eine RVersion, die auf der obigen Antwort von @Pirijan basiert.

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

So habe ich mit Javascript einen Punkt auf einem Kreis herausgefunden und den Winkel (Grad) vom oberen Rand des Kreises berechnet.

  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

Basierend auf der obigen Antwort von Daniel, hier ist meine Einstellung mit 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]))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.