使用 Java 计算 PI 近似值
Calculating PI approximation with Java
我正在尝试编写一个近似于 PI 值的代码。
我正在做的是:
在矩形内画圆
在矩形和圆内绘制随机点
计算rect/cicle
之间的比率
计算4/比率
应该是PI
这是我的代码:
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Random;
public class Main extends Frame {
int width = 800;
ArrayList<Point> list = new ArrayList<Point>();
public void points(Graphics g) {
int numPoint = 10000000;
for (int i = 0; i < numPoint; i++) {
int min = 23;
int max = 23 + width;
Random rand = new Random();
int x = rand.nextInt(width);
int y = (int) (Math.random() * (max - min + 1) + min);
Point temp = new Point(x, y);
list.add(temp);
if (inCircle(temp)) {
g.setColor(Color.green);
} else {
g.setColor(Color.blue);
}
g.drawLine(x, y, x, y);
}
}
public void paint(Graphics g) {
g.fillRect(0, 0, 1000, 1000);
int x = width / 2;
int y = width / 2 + 23;
int radius = width / 2;
g.setColor(Color.WHITE);
g.drawOval(x - radius, y - radius, radius * 2, radius * 2);
g.drawRect(0, 23, width, width);
points(g);
calculatingPI();
}
public void calculatingPI() {
double inCircle = 0;
double inRect = list.size();
for (Point p : list) {
if (inCircle(p)) {
inCircle++;
}
}
double ratio = inRect / inCircle;
System.out.print("PI is approximated to: " + 4 / ratio + " ");
}
public boolean inCircle(Point p) {
Point center = new Point(width / 2, width / 2 + 23);
return center.distance(p) <= width / 2;
}
public static void main(String[] args) {
Frame frame = new Main();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
// circle coordinates.
frame.setSize(800, 1000);
frame.setVisible(true);
}
}
它工作得很好,即使大多数时候这个数字在 1,13 左右,这不是一个很好的近似值。
问题是:
我越是减小矩形和圆形的大小(不改变点数),PI 就越不准确。我不明白,这是为什么?我的代码有问题吗?
不应该相反吗?面积越小,点越准,PI越准。为什么不是这样?
您正在使用整数像素。这意味着您制作的“圆圈”越小,它就越接近真实的圆圈。例如,这是一个 3x3 像素正方形内的圆:它看起来根本不是圆形。
█
███
█
要获得更好的近似值,请使用 double
浮点数而不是整数。使用 Point2D.Double
而不是 Point
class:
ArrayList<Point2D.Double> list = new ArrayList<>();
要生成随机点:
double x = Math.random() * width;
double y = Math.random() * (max - min) + min;
Point2D.Double temp = new Point2D.Double(x, y);
请注意,您在 max-min+1
的位置必须删除 +1。
判断点是否在圆内:
public boolean inCircle(Point2D.Double p) {
Point2D.Double center = new Point2D.Double(width / 2d, width / 2d + 23);
return center.distance(p) <= width / 2d;
}
我正在尝试编写一个近似于 PI 值的代码。 我正在做的是:
在矩形内画圆
在矩形和圆内绘制随机点
计算rect/cicle
之间的比率计算4/比率
应该是PI
这是我的代码:
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Random;
public class Main extends Frame {
int width = 800;
ArrayList<Point> list = new ArrayList<Point>();
public void points(Graphics g) {
int numPoint = 10000000;
for (int i = 0; i < numPoint; i++) {
int min = 23;
int max = 23 + width;
Random rand = new Random();
int x = rand.nextInt(width);
int y = (int) (Math.random() * (max - min + 1) + min);
Point temp = new Point(x, y);
list.add(temp);
if (inCircle(temp)) {
g.setColor(Color.green);
} else {
g.setColor(Color.blue);
}
g.drawLine(x, y, x, y);
}
}
public void paint(Graphics g) {
g.fillRect(0, 0, 1000, 1000);
int x = width / 2;
int y = width / 2 + 23;
int radius = width / 2;
g.setColor(Color.WHITE);
g.drawOval(x - radius, y - radius, radius * 2, radius * 2);
g.drawRect(0, 23, width, width);
points(g);
calculatingPI();
}
public void calculatingPI() {
double inCircle = 0;
double inRect = list.size();
for (Point p : list) {
if (inCircle(p)) {
inCircle++;
}
}
double ratio = inRect / inCircle;
System.out.print("PI is approximated to: " + 4 / ratio + " ");
}
public boolean inCircle(Point p) {
Point center = new Point(width / 2, width / 2 + 23);
return center.distance(p) <= width / 2;
}
public static void main(String[] args) {
Frame frame = new Main();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
// circle coordinates.
frame.setSize(800, 1000);
frame.setVisible(true);
}
}
它工作得很好,即使大多数时候这个数字在 1,13 左右,这不是一个很好的近似值。
问题是: 我越是减小矩形和圆形的大小(不改变点数),PI 就越不准确。我不明白,这是为什么?我的代码有问题吗?
不应该相反吗?面积越小,点越准,PI越准。为什么不是这样?
您正在使用整数像素。这意味着您制作的“圆圈”越小,它就越接近真实的圆圈。例如,这是一个 3x3 像素正方形内的圆:它看起来根本不是圆形。
█
███
█
要获得更好的近似值,请使用 double
浮点数而不是整数。使用 Point2D.Double
而不是 Point
class:
ArrayList<Point2D.Double> list = new ArrayList<>();
要生成随机点:
double x = Math.random() * width;
double y = Math.random() * (max - min) + min;
Point2D.Double temp = new Point2D.Double(x, y);
请注意,您在 max-min+1
的位置必须删除 +1。
判断点是否在圆内:
public boolean inCircle(Point2D.Double p) {
Point2D.Double center = new Point2D.Double(width / 2d, width / 2d + 23);
return center.distance(p) <= width / 2d;
}