Tính vị trí của các điểm trong một đường tròn


88

Tôi đang có một chút đầu óc trống rỗng về điều này vào lúc này. Tôi gặp một vấn đề trong đó tôi cần tính toán vị trí của các điểm xung quanh một điểm trung tâm, giả sử chúng đều cách đều tâm và cách xa nhau.

Số điểm có thể thay đổi nên DrawCirclePoints(int x) tôi chắc chắn rằng có một giải pháp đơn giản, nhưng đối với cuộc sống của tôi, tôi không thể nhìn thấy nó :)


1
Mọi người đều đưa ra câu trả lời tuyệt vời, nhanh chóng đến điên cuồng, vì vậy tôi đã đánh dấu vào câu trả lời đầu tiên :) Tất cả đều tuyệt vời :)
JoeBrown

Câu trả lời:


73

Một điểm ở góc theta trên đường tròn có tâm (x0,y0)và bán kính r(x0 + r cos theta, y0 + r sin theta). Bây giờ chọn thetacác giá trị cách đều nhau từ 0 đến 2pi.


Câu hỏi kinh điển- là giá trị của pi 3,14 hay 180? (tức là góc trong DEG hoặc radian?)
nirvanaswap

Chắc chắn là radian. Thay vào đó, nếu bạn sử dụng độ, bạn cần các góc từ 0 đến 360.
Gareth McCaughan

7
(Giá trị của pi là 3.14ish bất kể thế nào bạn thích góc độ ghi, tất nhiên là nó là gì..)
Gareth McCaughan

87

Với độ dài bán kính r và góc t tính bằng radian và tâm của hình tròn (h, k) , bạn có thể tính tọa độ của một điểm trên chu vi như sau (đây là mã giả, bạn sẽ phải điều chỉnh nó cho phù hợp với ngôn ngữ):

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

Bạn đã đảo lộn các hàm cos và sin nên sin đối với x và cos đối với y. Không phải hướng ngược lại.
Andreas

18
Bằng toán của tôi, cũng như mọi câu trả lời khác ở đây, nói rằng bạn không chính xác.
Brian Driscoll

2
Hm .. tốt trên wikipedia tiếng Thụy Điển nó nói sin là trục x Tôi biết đây không phải là nguồn an toàn nhưng sau đó tôi đã sử dụng sin trên x và cos trên y khối lập phương của tôi bắt đầu di chuyển theo đúng hướng. Ngay cả giáo viên toán của tôi cũng chỉ ra rằng tôi đã lật chúng. Bạn có thể nghĩ ra lý do nào khác khiến khối lập phương của tôi di chuyển theo một mô hình kỳ lạ ra khỏi vị trí mục tiêu và sau đó tôi lật chúng lại, nó sẽ di chuyển đến vị trí của nó?
Andreas

Đây là mã tôi đã viết, có lẽ bạn có thể biết tại sao nó hoạt động với chúng bị lật? jsfiddle.net/Lf5sZ
Andreas

3
Trong tọa độ màn hình, trục y dương được đảo ngược, vì vậy điều đó có ý nghĩa.
Brian Driscoll

51

Đây là một giải pháp sử dụng 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);
    }
}

Đầu ra mẫu từ 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}

Chúc may mắn!


1
Thông minh! Làm việc rất tốt cho tôi, tôi đã dịch nó sang php-cairo và hoạt động tuyệt vời!
Melsi

tôi đang tìm cách thực hiện cùng một loại nhiệm vụ, tuy nhiên trên Triggertrap / SeekArc · GitHub, khi người dùng di chuyển ngón tay cái, tôi muốn đặt một hình ảnh để cho biết tiến trình đã chọn của người đó .... tất cả những gì tôi có cố gắng cho tôi điểm một chút tắt và không phải là một perfec
Ruyonga Dan

9

Sử dụng một trong các câu trả lời trên làm cơ sở, đây là ví dụ về 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

Đặt một số trong một đường tròn

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

Tôi phải làm điều này trên web, vì vậy đây là phiên bản coffeescript của câu trả lời của @ scottyab ở trên:

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

Giải pháp 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;
}

Tôi tin rằng ngoặc là không chính xác cho $newx$newy, đưa tọa độ cách bên ngoài bán kính vòng tròn. Hãy thử $newx = (int)($center->getX() + ($radius * cos($angle)));và tương tự cho $newy.
Jason

2

Để hoàn thiện, những gì bạn mô tả là "vị trí của các điểm xung quanh điểm trung tâm (giả sử chúng cách đều nhau từ trung tâm)" không là gì ngoài "Tọa độ cực". Và bạn đang yêu cầu cách để Chuyển đổi giữa tọa độ cực và Descartes mà được cho là x = r*cos(t), y = r*sin(t).


1

Góc giữa mỗi điểm của bạn sẽ là 2Pi/xvì vậy bạn có thể nói rằng đối với các điểm n= 0 to x-1thì góc từ một điểm 0 xác định là 2nPi/x.

Giả sử điểm đầu tiên của bạn ở (r,0)(trong đó r là khoảng cách từ điểm chính giữa) thì vị trí so với điểm chính giữa sẽ là:

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

1

Giải pháp làm việc trong 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

Đây là Rphiên bản dựa trên câu trả lời @Pirijan ở trên.

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

Đây là cách tôi tìm ra một điểm trên đường tròn bằng javascript, tính góc (độ) từ đỉnh của vòng tròn.

  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

Dựa trên câu trả lời ở trên từ Daniel, đây là cách sử dụng Python3 của tôi.

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]))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.