在尝试绘制四叶玫瑰时确实遇到困难:这是练习:
画出“四叶玫瑰”的图,其极坐标方程为 r=cos(2θ) 。让 θ 以 100 步从 0 变化到 2*pi。每次计算 r,然后使用以下公式从极坐标计算 (x, y) 坐标 x = r ⋅ cos( θ) , y = r ⋅ sin(θ )
我的代码:
public Rose(double awidth, double aheight)
{
width = awidth;
height = aheight;
theta = 0;
}
public void drawRose(Graphics2D g2)
{
Ellipse2D.Double test ;
double r = 0;
for(int i = 0; i <= 100; i++)
{
r = Math.cos(Math.toRadians(2*theta) );
x = r *( Math.cos( Math.toRadians(theta) ) * width ) + 300;
y = r * ( Math.sin( Math.toRadians(theta) ) * height ) + 300 ;
test = new Ellipse2D.Double(x, y, width, height);
theta += 3.6;
g2.draw(test);
}
}
}
任何帮助将不胜感激。
最佳答案
你最大的错误在这里:
test = new Ellipse2D.Double(x, y, width, height);
您正在使用玫瑰上的点创建 100 个椭圆,但具有所需玫瑰的高度和宽度。你确实不需要 100 个椭圆,而是想要连接你创建的 x 和 y 点之间的线,即将当前的 x、y 与之前创建的 x、y 连接起来(只要有之前的 x 和 y)。
一种方法是通过这些建议,但还有其他方法可以做到这一点:
- 使用 Path2D对象,具体实现是 Path2D.Double,用于保存数据点。在创建数据点之前创建它。
- 使用从 0 到 100 的 for 循环,并在类的构造函数中执行此操作
- 在循环中设置双 theta
- 在循环中设置双
r
变量 - 计算 x 和 y 双倍积分
- 通过将 x 和 y 点乘以比例因子来缩放它们,以便绘图具有一定的大小。我用的是150.0
- 通过添加平移常量来平移 x 和 y 值。我使用了 200,它在 400 x 400 JPanel 中运行良好。否则,玫瑰的中心将位于 0, 0,并且只有四分之一可见。
- 在 for 循环的第一次迭代中,调用 Path2D 的
moveTo(...)
方法来添加起点 - 在所有其他迭代中调用
lineTo(...)
方法。这将在相邻点之间画一条线。 - 在 for 循环之后,通过调用
closePath()
来关闭路径。 - 通过将 Graphics 参数转换为 Graphics2D 对象(实际上您不需要这个,因为您的绘制方法获取 Grahpics2D 对象),并使用 Graphics2D 对象调用
draw(path)
并传入您的 Path2D 对象,在 JPanel 的 PaintComponent 方法中绘制路径。
例如,创建的是:
使用此代码:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class RosePanel extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private static final int MAX = 100;
private static final double SCALE = 150.0;
private static final double DELTA_X = 200;
private static final double DELTA_Y = DELTA_X;
private static final Color ROSE_COLOR = Color.red;
private static final Stroke ROSE_STROKE = new BasicStroke(8f);
private Path2D path = new Path2D.Double();
public RosePanel() {
for (int i = 0; i < MAX; i++) {
double theta = i * 2 * Math.PI / MAX;
double r = Math.cos(2 * theta);
double dX = SCALE * r * Math.cos(theta) + DELTA_X;
double dY = SCALE * r * Math.sin(theta) + DELTA_Y;
if (i == 0) {
path.moveTo(dX, dY);
} else {
path.lineTo(dX, dY);
}
}
path.closePath();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(ROSE_COLOR);
g2.setStroke(ROSE_STROKE);
g2.draw(path);
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
RosePanel mainPanel = new RosePanel();
JFrame frame = new JFrame("RosePanel");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
请注意,除了翻译和缩放之外,我的代码和您的代码之间的主要区别在于我连接了创建的点之间的线。
关于java - 用Java绘制四叶玫瑰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31036718/