【发布时间】:2015-10-11 23:26:24
【问题描述】:
我正在做一个关于空间物理学的应用程序,所以我做了很多关于轨道的事情。当然,我遇到Ellipse2D.Double 在屏幕上绘制我的轨道。
每当我的 JPanel 刷新时,我都会使用 Ellipse2D 绘制物体的轨道,并使用不同的方法绘制物体本身。
本质上,我发现当数字变得非常大时(无论是轨道的大小变大还是可视化被放大得很远),身体的位置和 Ellipse2D 的位置并不一致。
我使用从极坐标到直角坐标的转换来计算身体的位置,并将 Ellipse2D 的数学运算留给 geom 包。
看看这个代码示例。这是我能做的最独立的问题,因为圆圈的规模必须非常大:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.math.BigDecimal;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class EllipseDemo extends JPanel {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.add(new EllipseDemo());
frame.setVisible(true);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// These values allow for a very zoomed in view of a piece of the circle
BigDecimal[] circleCenter = { new BigDecimal(-262842.5), new BigDecimal(-93212.8) };
BigDecimal circleRadius = new BigDecimal(279081.3);
// Draw the circle at the given center, with the given width and height
// x = centerx - radius, y = centery - radius, w = h = radius * 2
g2d.draw(new Ellipse2D.Double(circleCenter[0].subtract(circleRadius).doubleValue(),
circleCenter[1].subtract(circleRadius).doubleValue(), circleRadius.multiply(new BigDecimal(2)).doubleValue(),
circleRadius.multiply(new BigDecimal(2)).doubleValue()));
// Get a rectangular conversion of a point on the circle at this angle
BigDecimal angle = new BigDecimal(0.34117696217);
BigDecimal[] rectangular = convertPolarToRectangular(new BigDecimal[] {
circleRadius, angle });
// Draw a line from the center of the circle to the point
g2d.draw(new Line2D.Double(circleCenter[0].doubleValue(), circleCenter[1].doubleValue(),
circleCenter[0].add(rectangular[0]).doubleValue(), circleCenter[1]
.add(rectangular[1]).doubleValue()));
}
public BigDecimal[] convertPolarToRectangular(BigDecimal[] polar) {
BigDecimal radius = polar[0];
BigDecimal angle = polar[1];
BigDecimal x = radius.multiply(new BigDecimal(Math.cos(angle.doubleValue())));
BigDecimal y = radius.multiply(new BigDecimal(Math.sin(angle.doubleValue())));
return new BigDecimal[] { x, y };
}
}
上面的代码本质上是在屏幕上画了一个半径很大的圆。我选择了尺寸,以便在小窗口中可以看到圆形的一部分。
然后它从圆的中心画一条线到圆上在窗口中可见的点:我选择了一个在窗口上可见的角度,并使用几何将该角度和圆的半径转换为直角坐标。
这是程序显示的内容:
请注意,这条线实际上并没有最终接触到椭圆。现在,我决定必须找出是我计算的点还是椭圆不正确。我用计算器算了一下,发现直线是正确的,而椭圆是错误的:
考虑到计算器可能没有错,我被引导相信 Ellipse2D 没有正确绘制。但是,我尝试了很多其他角度,这就是我发现的模式:
而那让我相信这些计算在某种程度上是错误的。
所以这是我的问题。我应该使用 Ellipse2D 以外的东西吗?也许 Ellipse2D 不够准确?我在我的代码示例中使用了 BigDecimals,因为我认为它会给我更高的精度 - 这是错误的方法吗?我的最终目标是能够计算椭圆上某个点在特定角度的矩形位置。
提前致谢。
【问题讨论】: