如何使用Java计算圆中点的坐标?

Posted

技术标签:

【中文标题】如何使用Java计算圆中点的坐标?【英文标题】:How to calculate the coordinates of points in a circle using Java? 【发布时间】:2018-07-01 03:34:21 【问题描述】:

我找到了this website,您可以在其中尝试画一个完美的圆。只是为了好玩,我编写了这个小型 Java 应用程序,它从屏幕中间画了一个圆圈:

    // here is my massive array
    private static int[] circle = 0, -100, 1, -100, 2, -100, 3, -100, 4, -100, 5, -100, 6, -100, 7, -100, 8, -100, 9, -100, 10, -100, 11, -99, 12, -99, 13, -99, 14, -99, 15, -99, 16, -99, 17, -98, 18, -98, 19, -98, 20, -98, 21, -98, 22, -97, 23, -97, 24, -97, 25, -97, 26, -96, 27, -96, 28, -96, 29, -96, 30, -95, 31, -95, 32, -95, 33, -94, 34, -94, 35, -94, 36, -93, 37, -93, 38, -92, 39, -92, 40, -92, 41, -91, 42, -91, 43, -90, 44, -90, 45, -89, 46, -89, 47, -88, 48, -88, 49, -87, 50, -86, 51, -86, 52, -85, 53, -85, 54, -84, 55, -83, 56, -84, 57, -83, 58, -82, 59, -82, 60, -81, 61, -80, 62, -79, 63, -79, 64, -78, 65, -77, 66, -76, 67, -75, 68, -74, 69, -73, 70, -72, 71, -71, 72, -70, 73, -69, 74, -68, 75, -67, 76, -66, 77, -65, 78, -64, 79, -63, 79, -62, 80, -61, 81, -60, 82, -59, 82, -58, 83, -57, 84, -56, 83, -55, 84, -54, 85, -53, 85, -52, 86, -51, 86, -50, 87, -49, 88, -48, 88, -47, 89, -46, 89, -45, 90, -44, 90, -43, 91, -42, 91, -41, 92, -40, 92, -39, 92, -38, 93, -37, 93, -36, 94, -35, 94, -34, 94, -33, 95, -32, 95, -31, 95, -30, 96, -29, 96, -28, 96, -27, 96, -26, 97, -25, 97, -24, 97, -23, 97, -22, 98, -21, 98, -20, 98, -19, 98, -18, 98, -17, 99, -16, 99, -15, 99, -14, 99, -13, 99, -12, 99, -11, 100, -10, 100, -9, 100, -8, 100, -7, 100, -6, 100, -5, 100, -4, 100, -3, 100, -2, 100, -1, 100, 0, 100, 1, 100, 2, 100, 3, 100, 4, 100, 5, 100, 6, 100, 7, 100, 8, 100, 9, 100, 10, 100, 11, 99, 12, 99, 13, 99, 14, 99, 15, 99, 16, 99, 17, 98, 18, 98, 19, 98, 20, 98, 21, 98, 22, 97, 23, 97, 24, 97, 25, 97, 26, 96, 27, 96, 28, 96, 29, 96, 30, 95, 31, 95, 32, 95, 33, 94, 34, 94, 35, 94, 36, 93, 37, 93, 38, 92, 39, 92, 40, 92, 41, 91, 42, 91, 43, 90, 44, 90, 45, 89, 46, 89, 47, 88, 48, 88, 49, 87, 50, 86, 51, 86, 52, 85, 53, 85, 54, 84, 55, 83, 56, 84, 57, 83, 58, 82, 59, 82, 60, 81, 61, 80, 62, 79, 63, 79, 64, 78, 65, 77, 66, 76, 67, 75, 68, 74, 69, 73, 70, 72, 71, 71, 72, 70, 73, 69, 74, 68, 75, 67, 76, 66, 77, 65, 78, 64, 79, 63, 79, 62, 80, 61, 81, 60, 82, 59, 82, 58, 83, 57, 84, 56, 83, 55, 84, 54, 85, 53, 85, 52, 86, 51, 86, 50, 87, 49, 88, 48, 88, 47, 89, 46, 89, 45, 90, 44, 90, 43, 91, 42, 91, 41, 92, 40, 92, 39, 92, 38, 93, 37, 93, 36, 94, 35, 94, 34, 94, 33, 95, 32, 95, 31, 95, 30, 96, 29, 96, 28, 96, 27, 96, 26, 97, 25, 97, 24, 97, 23, 97, 22, 98, 21, 98, 20, 98, 19, 98, 18, 98, 17, 99, 16, 99, 15, 99, 14, 99, 13, 99, 12, 99, 11, 100, 10, 100, 9, 100, 8, 100, 7, 100, 6, 100, 5, 100, 4, 100, 3, 100, 2, 100, 1, 100, 0,100,-1,100,-2,100,-3,100,-4,100,-5,100,-6,100,-7,100,-8,100,-9,100,-10,100,-11,99,-12,99,-13,99,-14,99,-15,99,-16,99,-17,98,-18,98,-19,98,-20,98,-21,98,-22,97,-23,97,-24,97,-25,97,-26,96,-27,96,-28,96,-29,96,-30,95,-31,95,-32,95,-33,94,-34,94,-35,94,-36,93,-37,93,-38,92,-39,92,-40,92,-41,91,-42,91,-43,90,-44,90,-45,89,-46,89,-47,88,-48,88,-49,87,-50,86,-51,86,-52,85,-53,85,-54,84,-55,83,-56,84,-57,83,-58,82,-59,82,-60,81,-61,80,-62,79,-63,79,-64,78,-65,77,-66,76,-67,75,-68,74,-69,73,-70,72,-71,71,-72,70,-73,69,-74,68,-75,67,-76,66,-77,65,-78,64,-79,63,-79,62,-80,61,-81,60,-82,59,-82,58,-83,57,-84,56,-83,55,-84,54,-85,53,-85,52,-86,51,-86,50,-87,49,-88,48,-88,47,-89,46,-89,45,-90,44,-90,43,-91,42,-91,41,-92,40,-92,39,-92,38,-93,37,-93,36,-94,35,-94,34,-94,33,-95,32,-95,31,-95,30,-96,29,-96,28,-96,27,-96,26,-97,25,-97,24,-97,23,-97,22,-98,21,-98,20,-98,19,-98,18,-98,17,-99,16,-99,15,-99,14,-99,13,-99,12,-99,11,-100,10,-100,9,-100,8,-100,7,-100,6,-100,5,-100,4,-100,3,-100,2,-100,1,-100,0,-100,-1,-100,-2,-100,-3,-100,-4,-100,-5,-100,-6,-100,-7,-100,-8,-100,-9,-100,-10,-100,-11,-99,-12,-99,-13,-99,-14,-99,-15,-99,-16,-99,-17,-98,-18,-98,-19,-98,-20,-98,-21,-98,-22,-97,-23,-97,-24,-97,-25,-97,-26,-96,-27,-96,-28,-96,-29,-96,-30,-95,-31,-95,-32,-95,-33,-94,-34,-94,-35,-94,-36,-93,-37,-93,-38,-92,-39,-92,-40,-92,-41,-91,-42,-91,-43,-90,-44,-90,-45,-89,-46,-89,-47,-88,-48,-88,-49,-87,-50,-86,-51,-86,-52,-85,-53,-85,-54,-84,-55,-83,-56,-84,-57,-83,-58,-82,-59,-82,-60,-81,-61,-80,-62,-79,-63,-79,-64,-78,-65,-77,-66,-76,-67,-75,-68,-74,-69,-73,-70,-72,-71,-71,-72,-70,-73,-69,-74,-68,-75,-67,-76,-66,-77,-65,-78,-64,-79,-63,-79,-62,-80,-61,-81,-60,-82,-59,-82,-58,-83,-57,-84,-56,-83,-55,-84,-54,-85,-53,-85,-52,-86,-51,-86,-50,-87,-49,-88,-48,-88,-47,-89,-46,-89,-45,-90,-44,-90,-43,-91,-42,-91,-41,-92,-40,-92,-39,-92,-38,-93,-37,-93,-36,-94,-35,-94,-34,-94,-33,-95,-32,-95,-31,-95,-30,-96,-29,-96,-28,-96,-27,-96,-26,-97,-25,-97,-24,-97,-23,-97,-22,-98,-21,-98,-20,-98,-19,-98,-18,-98,-17,-99,-16,-99,-15,-99,-14,-99,-13,-99,-12,-99,-11,-100,-10,-100,-9,-100,-8,-100,-7,-100,-6,-100,-5,-100,-4,-100,-3,-100,-2,-100,-1,-100,0;
    public static void main(String[] args) 
        try 
            // Waiting for the website to load
            Thread.sleep(3000);
         catch (InterruptedException e) 
        // Getting the center of the screen
        Point p = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
        // Drawing the circle by clicking on each point in the array relative to the middle of the screen
        for (int x = 0; x < circle.length; x+=2) 
            // Calculating the x and y coordinates
            int xx = p.x + circle[x];
            int yy = p.y + circle[x+1];
            click(xx, yy);
            // waiting 10ms so the website can calculate the action
            try 
                Thread.sleep(10);
             catch (InterruptedException e) 
        
    
    public static void click(int x, int y) 
        try 
            Robot bot = new Robot();
            bot.mouseMove(x, y);
            bot.mousePress(InputEvent.BUTTON1_MASK);
            bot.mouseRelease(InputEvent.BUTTON1_MASK);
         catch (Exception e) 
    

该应用程序用于本网站。但我的问题是如您所见,我必须将圆的每个点保存在一个数组中,并且该数组非常大。如果我想扩大半径(100px),我需要重写所有这些点。有没有更简单的方法?也许通过使用方程式或类似的东西。

【问题讨论】:

你一定已经想出了一些公式来推导分数,不是吗?请告诉我你没有手写整个列表。 首先查看现有点中的模式。弄清楚您可以编写什么函数来生成现有的点列表,然后您应该能够针对不同大小的圆圈对其进行修改。 @Michael 我在油漆中画了一个圆圈,然后查看每个像素相对于其中心的位置...(是的,我知道,但我无事可做,所以我花了点时间) 一点提示:一些老家伙,现在已经死了,想到了很多东西,比如:pi(不是馅饼),radiantscalculating circle-stuff。也许这些东西可以帮助你。 @Milan:您不必定义圆中的每个点。只需定义圆心及其半径或直径,然后使用数学。使用辐射点,您可以动态计算圆上的每个点,然后移动鼠标。 【参考方案1】:

您可以通过cos(angle), sin(angle) 计算给定角度(以弧度为单位)的圆圆周上的点的坐标。

因此,我们可以获得点列表的一种方法是循环并获取每个n 度的坐标,其中n 是可配置的(您需要更多的点来获得更大的半径来绘制平滑的圆)。

我首先声明一个 Point 类来保存这些值:

class Point

    final int x;
    final int y;

    Point(final double x, final double y)
    
        this.x = (int) x; // we're dealing with pixels, so just truncate it
        this.y = (int) y;
    

    @Override
    public String toString()
    
        return "" + x + ", " + y + "";
    

然后我们可以执行以下操作来填充 Points 数组:

final int NUM_POINTS = 1000;
final double RADIUS = 100d;

final Point[] points = new Point[NUM_POINTS];

for (int i = 0; i < NUM_POINTS; ++i)

    final double angle = Math.toRadians(((double) i / NUM_POINTS) * 360d);

    points[i] = new Point(
        Math.cos(angle) * RADIUS, 
        Math.sin(angle) * RADIUS
    );


System.out.println(Arrays.toString(points));

【讨论】:

【参考方案2】:

您可以使用Circle Equations 绘制一个近乎完美的圆。由于您的屏幕分辨率,您无法画出完美的圆圈。

您只需要 x 和 y 坐标。

public Point [] generateCoordinates(Point center, int diameter) 
    //You will use algorithm here

这是一个示例算法;

https://www.tutorialspoint.com/computer_graphics/circle_generation_algorithm.htm

【讨论】:

我知道你不能画一个近乎完美的圆,但是例如绘画是如何做到的? Paint 不会画出完美的圆形。它正在使用我上面所说的。 “圆方程” 是的,但是我如何使用它来生成数组? 这个叫bresenhams算法(详见en.wikipedia.org/wiki/Midpoint_circle_algorithm)【参考方案3】:

https://www.varsitytutors.com/hotmath/hotmath_help/topics/equation-of-a-circle

你应该使用这个方程,这样你就可以调整圆的大小和精度

【讨论】:

如何使用它来生成数组? 这个方法可以完成这项工作(但缺乏精度,如果您愿意,可以使用 Doubles): Integer[] getCirclePoints(final int centerX, final int centerY, final int radius) List l = 新的 ArrayList(); for (int x = -radius; x != radius; x++) l.add(centerX + x); l.add(centerY +Integer.valueOf((int) Math.sqrt(radius * radius - x * x))); return (Integer[]) l.toArray(); 【参考方案4】:

我使用这段代码来生成我的数组,但它非常慢,这就是为什么@Michael 的答案更好......

int r = Integer.parseInt(rad) / 2;
    String[] circle = "0", "0";
    String[] circleq = "0", "0";
    String[] circlew = "0", "0";
    String[] circlee = "0", "0";

    for (int x = 0; x < r; x++) 
        double yy;

        yy = Math.sqrt((r*r) - (x*x));


        int y = (int) Math.round(yy);;
        circle = add(circle, Integer.parseInt("-" + x));
        circle = add(circle, Integer.parseInt("-" + y));
    
    String[] circle2 = circle;

    for (int c = 0; c < circle2.length; c++) 
        if ((c & 1) == 0 || c == 0) 
            circleq = add(circleq, Integer.parseInt(circle2[c]));
         else 
            circleq = add(circleq, Integer.parseInt(circle2[c].replace("-", "")));
        
    

    for (int c = 0; c < circle2.length; c++) 
        circlew = add(circlew, Integer.parseInt(circle2[c].replace("-", "")));
    

    for (int c = 0; c < circle2.length; c++) 
        if ((c & 1) == 0 || c == 0) 
            circlee = add(circlee, Integer.parseInt(circle2[c].replace("-", "")));
         else 
            circlee = add(circlee, Integer.parseInt(circle2[c]));
        
    

它将圆的每个四分之一保存在一个单独的数组中。

【讨论】:

以上是关于如何使用Java计算圆中点的坐标?的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode1828. 统计一个圆中点的数目(C++)

如何以给定的 X 和 Y 坐标绘制一个圆作为圆的中间点?

实心圆的中点圆算法

POJ 2194 2850 计算几何

计算经纬度坐标的中点

四道图像图像算法题目