在圆圈内绘制随机点

时间:2023-02-09 15:33:25

I would like to draw 50 random dots within a given circle. The problem is the dots are not contained in the circle. Here is a runnable example:

我想在给定的圆圈内绘制50个随机点。问题是圆圈中不包含点。这是一个可运行的例子:

package mygraphicsshapehomework;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;


public class MyGraphicsShapeHomeWork extends JFrame {


    public static void main(String[] args) {
        new MyGraphicsShapeHomeWork();        
    }


      public MyGraphicsShapeHomeWork() {
        super("Title"); 
        setBounds(600, 400, 700, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;

        g2.drawOval(40, 40, 90, 90); 

        Color newColor = new Color(255, 0, 0); 
        g2.setColor(newColor); 

        for (int i = 0; i < 50; i++) {
            int x =  (int) Math.ceil(Math.random() * 10);
            int y =  (int) Math.ceil(Math.random() * 10);            

                g2.fillOval(i+x, i+y, 3, 3);   // ???          

        }

    }    
}

Here is the result it produces:

这是它产生的结果:

在圆圈内绘制随机点

How can I draw the dots within the circle only?

我怎样才能在圆圈内画出点?

2 个解决方案

#1


3  

To get a random point in a circle with radius R find a random angle and a random radius:

要获得半径为R的圆中的随机点,请找到随机角度和随机半径:

double a = random() * 2 * PI; 
double r = R * sqrt(random()); 

Then the coordinates of the point are:

那么点的坐标是:

double x = r * cos(a)
double y = r * sin(a)

Here are some notes about the drawing part. You should not paint directly on top level container such as JFrame. Instead, use JComponent or JPanel. Override paintComponent() for painting rather than paint() and don't forget to call super.paintComponent(g)

以下是有关绘图部分的一些注意事项。您不应直接在*容器(如JFrame)上绘制。而是使用JComponent或JPanel。覆盖paintComponent()以进行绘制而不是paint(),并且不要忘记调用super.paintComponent(g)

Take a look at Performing Custom Painting tutorial for more information.

有关更多信息,请参阅执行自定义绘画教程。

Do not use setBounds(), override panel's getPreferredSize() and pack() the frame. Also, you rarely need to extend JFrame.

不要使用setBounds(),覆盖面板的getPreferredSize()和pack()框架。此外,您很少需要扩展JFrame。

Here is a basic example that demonstrates drawing with a sub-pixel precision:

这是一个基本示例,演示了以子像素精度绘制:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestDots extends JPanel{
    public static final int POINTS_NUM = 1000;
    public static final Color POINT_COLOR = Color.RED;

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 400);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;

        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

        double padding = 10;
        double radius = Math.min(this.getWidth(), this.getHeight()) / 2 - padding * 2;

        g2.draw(new Ellipse2D.Double(padding, padding, radius * 2, radius * 2));
        g2.setColor(POINT_COLOR); 

        for (int i = 0; i < POINTS_NUM; i++) {
            double a = Math.random() * 2 * Math.PI;
            double r = radius * Math.sqrt(Math.random());
            double x = r * Math.cos(a) + radius + padding;
            double y = r * Math.sin(a) + radius + padding;

            g2.draw(new Ellipse2D.Double(x, y, 1, 1));
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {   
            public void run() {   
                JFrame frame = new JFrame("TestDots");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationByPlatform(true);
                frame.add(new TestDots());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

Here is a result:

结果如下:

在圆圈内绘制随机点

#2


0  

For the position of the dots, generate random coordinates within the bounds of the outer circle. In order to generate these coordinates, the radius of the point from the center of the circle must be less than that of the outer circle. Get a random angle using

对于点的位置,在外圆的边界内生成随机坐标。为了生成这些坐标,从圆心开始的点的半径必须小于外圆的半径。使用随机角度

float a = Math.random() * Math.PI * 2; 

Then, subtract a random value from the outer radius:

然后,从外半径中减去一个随机值:

outerR - (Math.sqrt(Math.random()) * outerR)

and assign the positions to:

并将职位分配给:

double x = Math.cos(a)*newR;
double y = Math.sin(a)*newR;

I'm sure there is a more mathematical approach to this, but this was the simplest in my opinion.

我相信这有更多的数学方法,但在我看来这是最简单的。

#1


3  

To get a random point in a circle with radius R find a random angle and a random radius:

要获得半径为R的圆中的随机点,请找到随机角度和随机半径:

double a = random() * 2 * PI; 
double r = R * sqrt(random()); 

Then the coordinates of the point are:

那么点的坐标是:

double x = r * cos(a)
double y = r * sin(a)

Here are some notes about the drawing part. You should not paint directly on top level container such as JFrame. Instead, use JComponent or JPanel. Override paintComponent() for painting rather than paint() and don't forget to call super.paintComponent(g)

以下是有关绘图部分的一些注意事项。您不应直接在*容器(如JFrame)上绘制。而是使用JComponent或JPanel。覆盖paintComponent()以进行绘制而不是paint(),并且不要忘记调用super.paintComponent(g)

Take a look at Performing Custom Painting tutorial for more information.

有关更多信息,请参阅执行自定义绘画教程。

Do not use setBounds(), override panel's getPreferredSize() and pack() the frame. Also, you rarely need to extend JFrame.

不要使用setBounds(),覆盖面板的getPreferredSize()和pack()框架。此外,您很少需要扩展JFrame。

Here is a basic example that demonstrates drawing with a sub-pixel precision:

这是一个基本示例,演示了以子像素精度绘制:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestDots extends JPanel{
    public static final int POINTS_NUM = 1000;
    public static final Color POINT_COLOR = Color.RED;

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 400);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;

        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

        double padding = 10;
        double radius = Math.min(this.getWidth(), this.getHeight()) / 2 - padding * 2;

        g2.draw(new Ellipse2D.Double(padding, padding, radius * 2, radius * 2));
        g2.setColor(POINT_COLOR); 

        for (int i = 0; i < POINTS_NUM; i++) {
            double a = Math.random() * 2 * Math.PI;
            double r = radius * Math.sqrt(Math.random());
            double x = r * Math.cos(a) + radius + padding;
            double y = r * Math.sin(a) + radius + padding;

            g2.draw(new Ellipse2D.Double(x, y, 1, 1));
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {   
            public void run() {   
                JFrame frame = new JFrame("TestDots");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationByPlatform(true);
                frame.add(new TestDots());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

Here is a result:

结果如下:

在圆圈内绘制随机点

#2


0  

For the position of the dots, generate random coordinates within the bounds of the outer circle. In order to generate these coordinates, the radius of the point from the center of the circle must be less than that of the outer circle. Get a random angle using

对于点的位置,在外圆的边界内生成随机坐标。为了生成这些坐标,从圆心开始的点的半径必须小于外圆的半径。使用随机角度

float a = Math.random() * Math.PI * 2; 

Then, subtract a random value from the outer radius:

然后,从外半径中减去一个随机值:

outerR - (Math.sqrt(Math.random()) * outerR)

and assign the positions to:

并将职位分配给:

double x = Math.cos(a)*newR;
double y = Math.sin(a)*newR;

I'm sure there is a more mathematical approach to this, but this was the simplest in my opinion.

我相信这有更多的数学方法,但在我看来这是最简单的。