Obliczanie położenia punktów na okręgu

87

W tej chwili mam trochę pustki w tej sprawie. Mam problem polegający na tym, że muszę obliczyć położenie punktów wokół centralnego punktu, zakładając, że wszystkie są jednakowo oddalone od środka i od siebie.

Liczba punktów jest zmienna, więc DrawCirclePoints(int x) jestem pewien, że istnieje proste rozwiązanie, ale do końca życia po prostu go nie widzę :)

JoeBrown
źródło
1
Wszyscy udzielili świetnych odpowiedzi, szalenie szybko, więc zaznaczyłem pierwszą odpowiedź :) Wszyscy byli świetni :)
JoeBrown

Odpowiedzi:

72

Punkt pod kątem theta na okręgu, którego środek jest (x0,y0)i którego promień rwynosi (x0 + r cos theta, y0 + r sin theta). Teraz wybierz thetawartości w równych odstępach od 0 do 2pi.

Gareth McCaughan
źródło
Klasyczne pytanie - czy wartość pi 3,14 czy 180? (tj. czy kąt jest w stopniach czy radianach?)
nirvanaswap
Zdecydowanie radiany. Jeśli używasz stopni, potrzebujesz zamiast tego kątów z zakresu od 0 do 360.
Gareth McCaughan
7
(Oczywiście wartość pi wynosi 3,14 cala, niezależnie od tego, jak wolisz pisać kąty. Tak właśnie jest.)
Gareth McCaughan
87

Biorąc pod uwagę długość promienia r i kąt t w radianach oraz środek koła (h, k) , możesz obliczyć współrzędne punktu na obwodzie w następujący sposób (jest to pseudokod, musisz dostosować go do swojego język):

float x = r*cos(t) + h;
float y = r*sin(t) + k;
Brian Driscoll
źródło
Masz odwrócone funkcje cos i sin powinny być sin dla x i cos dla y. Nie na odwrót.
Andreas
18
Mój dyplom z matematyki, jak również każda inna odpowiedź tutaj, mówią, że się mylisz.
Brian Driscoll
2
Hm ... cóż, na szwedzkiej wikipedii jest napisane, że sin to oś x. Wiem, że to nie jest bezpieczne źródło, ale potem użyłem sin na x i cos na y, moja kostka zaczęła się poruszać we właściwym kierunku. Nawet mój nauczyciel matematyki zwrócił uwagę, że je przerzuciłem. Czy przychodzi Ci do głowy jakikolwiek inny powód, dla którego moja kostka poruszałaby się w dziwny sposób z dala od miejsca docelowego, a następnie odwróciłem je, aby przesunęły się do swojej pozycji?
Andreas
To jest kod, który napisałem, może mógłbyś powiedzieć, dlaczego działa z nimi odwrócony? jsfiddle.net/Lf5sZ
Andreas
3
Na współrzędnych ekranowych dodatnia oś Y jest odwrócona, więc to ma sens.
Brian Driscoll,
51

Oto rozwiązanie wykorzystujące 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);
    }
}

Przykładowe dane wyjściowe z 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}

Powodzenia!

Daniel Lidström
źródło
1
Świetny! Działało dla mnie świetnie, już przetłumaczyłem to na php-cairo i działa świetnie!
Melsi
szukam tego samego rodzaju zadania, jednak moje jest zależne od Triggertrap / SeekArc · GitHub, kiedy użytkownik poruszy kciukiem, chcę umieścić obraz, aby wskazać wybrany postęp osoby .... wszystko, co mam próbowałem dać mi trochę punktów, a nie
perfek
9

Bazując na jednej z powyższych odpowiedzi, oto przykład 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
}
scottyab
źródło
4

Umieszczanie liczby na ścieżce kołowej

// 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);
}
maSC0d3R
źródło
3

Musiałem to zrobić w Internecie, więc oto wersja Coffeescript odpowiedzi @ scottyab powyżej:

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)
Pirijan
źródło
3

Rozwiązanie 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;
}
bitmiczny
źródło
Uważam, że jest niepoprawna dla nawias $newxi $newy, wprowadzanie współrzędnych drogę na zewnątrz promienia okręgu. Spróbuj $newx = (int)($center->getX() + ($radius * cos($angle)));i podobnie dla $newy.
Jason,
2

W celu zakończenia, to, co opisujesz jako „położenie punktów wokół punktu centralnego (zakładając, że wszystkie są w równej odległości od środka)” to nic innego jak „współrzędne biegunowe”. I prosisz o drodze do konwersji pomiędzy biegunowych i współrzędnych kartezjańskich , który jest podawany jako x = r*cos(t), y = r*sin(t).

Adarsha
źródło
1

Kąt między każdym z twoich punktów będzie 2Pi/xtaki, że możesz powiedzieć, że dla punktów n= 0 to x-1kąt od zdefiniowanego punktu 0 wynosi 2nPi/x.

Zakładając, że pierwszy punkt znajduje się w (r,0)(gdzie r jest odległością od środka), wówczas pozycje względem punktu centralnego będą wyglądać następująco:

rCos(2nPi/x),rSin(2nPi/x)
Chris
źródło
1

Działające rozwiązanie w Javie:

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;
}
}
Gewure
źródło
1

Oto Rwersja oparta na powyższej odpowiedzi @Pirijan.

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)
jsta
źródło
1

Oto jak znalazłem punkt na okręgu za pomocą javascript, obliczając kąt (stopień) od góry koła.

  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
Noby Fujioka
źródło
0

W oparciu o powyższą odpowiedź od Daniela, oto moje podejście do korzystania z 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]))
Pratik
źródło