【问题标题】:Make oval/rectangle using float/double values使用浮点/双精度值制作椭圆/矩形
【发布时间】:2013-03-19 09:46:01
【问题描述】:

确切地说,我想使用浮点数或双精度值绘制图形。

我用:

g.drawOval(0, 0, 10, 10);

画一个圆,但我只能使用整数值。

是否有任何使用浮点/双精度值的语句做同样的事情?

这是一张图片:Problem

圆圈必须居中,而我不能。有什么解决办法吗?

代码:

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JPanel;

public class Bulls_EYE extends JPanel
{
    int red, green, blue;
    int height, width;
    int heightOval = 475, widthOval = 475;
    Random rValue = new Random();

    public void paint (Graphics g)
    {           
        super.paint(g);

        for (int idx = 0; idx < 100; idx++)
        {
        g.setColor(new Color(red = 1 + rValue.nextInt(255), green = 1 + rValue.nextInt(255), blue = 1 + rValue.nextInt(255)));
        g.fillOval(width+2*idx, height+2*idx, widthOval-5*idx, heightOval-5*idx);
        }
    }
}

【问题讨论】:

标签: java graphics


【解决方案1】:

您没有理由这样做,因为在使用给定坐标绘制椭圆时,它们指的是屏幕上的像素。由于您无法在像素之间进行绘制,因此 1 是您可以使用的最小单位。如果要在绘制之前对值进行四舍五入,可以使用

g.drawOval(Math.round(a),Math.round(b),Math.round(x),Math.round(y)

这将在绘制椭圆之前对float a、b、x 和y 进行四舍五入。我能看到的唯一原因是你计算了坐标,结果是float,那么你需要像上面那样四舍五入。

【讨论】:

  • 好吧,那就忘了我的回答吧。下次请说清楚你想要什么:)
  • 另一个不知道抗锯齿的答案。这样想:如果我们在更大的像素网格(即更高的分辨率)上绘制它会发生什么,然后缩放图像,例如到一半大小,将四个相邻像素混合成一种颜色?您也可以这样做,绕过这个实际过程。 Java 库 API 已经可以做到这一点。只是需要使用不同的方法调用:stackoverflow.com/a/31221395/1143274
【解决方案2】:

我认为这是一个有趣的问题,但需要更多背景信息。绘图图元通常以像素坐标表示,因此像素的小数部分没有多大意义。

如果您想要像 CAD 应用程序这样的精度,请注意,由于显示器的限制,屏幕上显示的只是底层模型的近似值。

您可以在内存中精确表示您的模型(浮点表示有限制)并在屏幕上绘制近似值。

更新

根据您的上次更新:

我们从 JavaDoc 中得知fillOval(x, y, w, h) 作为参数,其中x, y 是左上角坐标,w, h 是宽度和高度。

如果您将每个同心圆的左上角坐标向内移动(在本例中为 2 像素),以使它们保持居中,您还必须将宽度和高度减少两倍。更改以下行:

g.fillOval(width+2*idx, height+2*idx, widthOval-5*idx, heightOval-5*idx);

int dx, dy, dw, dh;
dx = 2*idx;
dy = 2*idx;
dw = 2*dx; // note this is 4*idx not 5*idx like you have currently
dh = 2*dy;
g.fillOval(width+dx, height+dy, widthOval-dw, heightOval-dh);

请注意,在第一个和第二个参数中使用的 widthheight 变量实际上与宽度和高度没有任何关系,而是提供了从绘制椭圆的原点开始的偏移量。

【讨论】:

  • 像素的分数是有意义的。这个想法被称为抗锯齿。请参阅我关于如何正确执行此操作的答案:stackoverflow.com/a/31221395/1143274
  • @EvgeniSergeev 抗锯齿超出了这个问题的范围,它仍然不是“像素的分数”。抗锯齿使用渐变值的多个像素来伪造它,以提供平滑线条和曲线的错觉。没有像素的一小部分这样的东西。您不能在像素之间绘制。它们使用整数寻址。 OPs 最初的问题很模糊,我在回答为什么像素坐标表示为整数值而不是浮点数或双精度值。
【解决方案3】:

您可以使用Arc2D 类绘制具有浮点/双精度的圆,因为它是Shape,而Graphics2D 类可以绘制形状。

@Override
protected void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    Shape circle = new Arc2D.Double(
            // Same values as used in the fillOval function,
            // but with double precision.
            x, y, width, height,
            // Draw a full circle (yes, in degrees).
            0, 360,
            // Connect the endpoint with the startpoint.
            Arc2D.CORD
    );
    // Paint the circle.
    g2d.fill(circle);
}

以类似的方式,您可以使用Rectangle2D 类绘制矩形。

另外,请使用paintComponent 函数而不是paint 函数,如here 所述。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-06
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-22
    • 2020-09-24
    相关资源
    最近更新 更多