如何画一个体面的在Java中寻找圈子如何画一个体面的在Java中寻找圈子(How to draw a

2019-05-17 11:00发布

我已经使用具有相等的高度和宽度的方法drawOval尝试,但随着直径增加了圆变差寻找。 我能做些什么有一个体面的寻找圈子事无大小。 我将如何实现在Java或其他方法抗锯齿。

Answer 1:

事实证明,Java2D的(这我假设是你所使用的)已经在这个不错! 这里有一个像样的教程: http://www.javaworld.com/javaworld/jw-08-1998/jw-08-media.html

最重要的行是:

graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                          RenderingHints.VALUE_ANTIALIAS_ON);


Answer 2:

您可以设置渲染提示:

Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_ON);


Answer 3:

有两件事情可以帮助:

  1. 使用Graphics2D.draw(Shape)与实例java.awt.geom.Ellipse2D代替Graphics.drawOval
  2. 如果结果仍然不能令人满意,请尝试使用Graphics2D.setRenderingHint启用抗锯齿

public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    Shape theCircle = new Ellipse2D.Double(centerX - radius, centerY - radius, 2.0 * radius, 2.0 * radius);
    g2d.draw(theCircle);
}

见约瑟夫的答案的例子setRenderingHint



Answer 4:

当然,你的设置半径为你需要什么都:

@Override
public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    Ellipse2D.Double hole = new Ellipse2D.Double();
    hole.width = 28;
    hole.height = 28;
    hole.x = 14;
    hole.y = 14;
    g2d.draw(hole);
}


Answer 5:

感谢奥列格Estekhin您指出的错误报告,因为它解释了如何做到这一点。

下面是一些小圆圈之前和之后。 放大几次看到像素网格。

下去一排,它们是由子像素数量轻微地移动。

第一列是没有呈现提示。 二是只抗锯齿。 第三个是与抗混叠和纯模式。

注意如何与抗锯齿提示只,前三圈都是一样的,最后两个也相同。 似乎有一些不连续的过渡发生。 也许四舍五入在一些点。

下面的代码。 这是Jython中的可读性,但其下方驱动的Java运行时库,可以无损地移植到相应的Java源,具有完全相同的效果。

from java.lang import *
from java.io import *
from java.awt import *
from java.awt.geom import *
from java.awt.image import *
from javax.imageio import *

bim = BufferedImage(30, 42, BufferedImage.TYPE_INT_ARGB)
g = bim.createGraphics()
g.fillRect(0, 0, 100, 100)
g.setColor(Color.BLACK)
for i in range(5):
    g.draw(Ellipse2D.Double(2+0.2*i, 2+8.2*i, 5, 5))

g.setRenderingHint( RenderingHints.  KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON)

for i in range(5):
    g.draw(Ellipse2D.Double(12+0.2*i, 2+8.2*i, 5, 5))

g.setRenderingHint( RenderingHints.  KEY_STROKE_CONTROL,
                    RenderingHints.VALUE_STROKE_PURE)

for i in range(5):
    g.draw(Ellipse2D.Double(22+0.2*i, 2+8.2*i, 5, 5))

#You'll probably want this too later on:
#g.setRenderingHint( RenderingHints.  KEY_INTERPOLATION,
#                    RenderingHints.VALUE_INTERPOLATION_BICUBIC)
#g.setRenderingHint( RenderingHints.  KEY_RENDERING, 
#                    RenderingHints.VALUE_RENDER_QUALITY)

ImageIO.write(bim, "PNG", File("test.png"))

摘要:你既需要VALUE_ANTIALIAS_ONVALUE_STROKE_PURE得到适当的寻求与亚像素精度描画圆。



Answer 6:

无法画一个“体面的寻找圈”是关系到很老的bug 6431487 。

打开反锯齿上不会有很大的帮助 - 只检查一种由drawOval()或drawShape(Eclipse中)生产的“圆”的时候所需要的圆圈大小为16个像素(还是很常见的图标大小)和抗锯齿开启。 更大的抗锯齿界会更好看,但他们仍然是不对称的,如果有人会关心他们仔细看看。

看来,画一个“体面的寻找圈”一个具有手动绘制一个。 没有抗锯齿这将是中点画圆算法(这个问题有它一个漂亮的Java代码中的答案)。



Answer 7:

编辑:2017年09月06日

这是由我发明的画在整数矩阵的一个圆的算法。 同样的想法可以用来写一个BufferedImage内圆。 如果您尝试使用类的图形,这是不是你要找的(除非你想修改的每个颜色assignement与g.drawLine(X,Y,X + 1,Y)的answare得出这样的圈子,但它可能很慢)。

protected boolean runOnCircumference(int[][] matrix, int x, int y, int ray, int color) {
    boolean ret;
    int[] rowUpper = null, rowInferior = null, rowCenterUpper = null, rowCenterInferior = null;

    if (ret = ray > 0) {
        if (ray == 1) {
            matrix[y][x + 1] = color;
            rowUpper = matrix[++y];
            rowUpper[x] = color;
            rowUpper[x + 2] = color;
            matrix[y][x] = color;
        } else {
            double rRay = ray + 0.5;
            int r = 0, c = 0, ray2 = ray << 1, ray_1 = ray - 1, halfRay = (ray >> 1) + ray % 2, rInf,
                    ray1 = ray + 1, horizontalSymmetricOldC;
            // draw cardinal points

            rowUpper = matrix[ray + y];
            rowUpper[x] = color;
            rowUpper[x + ray2] = color;
            matrix[y][x + ray] = color;
            matrix[ray2 + y][x + ray] = color;

            horizontalSymmetricOldC = ray1;
            rInf = ray2;
            c = ray_1;
            for (r = 0; r < halfRay; r++, rInf--) {

                rowUpper = matrix[r + y];
                rowInferior = matrix[rInf + y];

                while (c > 0 && (Math.hypot(ray - c, (ray - r)) < rRay)) {

                    rowUpper[x + c] = color;
                    rowUpper[x + horizontalSymmetricOldC] = color;
                    rowInferior[x + c] = color;
                    rowInferior[x + horizontalSymmetricOldC] = color;

                    // get the row pointer to optimize
                    rowCenterUpper = matrix[c + y];
                    rowCenterInferior = matrix[horizontalSymmetricOldC + y];
                    // draw
                    rowCenterUpper[x + r] = color;
                    rowCenterUpper[x + rInf] = color;
                    rowCenterInferior[x + r] = color;
                    rowCenterInferior[x + rInf] = color;
                    horizontalSymmetricOldC++;
                    c--;
                }
            } // end r circle
        }
    }
    return ret;
}

我试了很多次,验证手动将其正确性,所以我认为它会工作。 我没有作任何范围的检查只是为了简化代码。 我希望它会帮助你,每个人都希望画一个圆圈在矩阵(例如,谁试图在纯代码创建自己的视频游戏和需要这些程序员来管理一个面向矩阵游戏地图存储躺在对象游戏地图[如果你需要这方面的帮助,给我发电子邮件])。



文章来源: How to draw a decent looking Circle in Java