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ę :)


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.


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;

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!


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
}

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

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)

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

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,


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)

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

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)

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

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]))
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.