He intentado utilizar el método drawOval con la misma altura y anchura, pero a medida que aumenta el diámetro, el círculo se vuelve peor. ¿Qué puedo hacer para tener un círculo de aspecto decente sin importar el tamaño? ¿Cómo implementaría anti-aliasing en Java o algún otro método?Cómo dibujar un Círculo de aspecto decente en Java
Respuesta
Como resultado, Java2D (que yo supongo que es lo que estás usando) ¡ya es bastante bueno en esto! Hay un tutorial decente aquí: http://www.javaworld.com/javaworld/jw-08-1998/jw-08-media.html
La línea importante es:
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
se pueden establecer consejos de renderizado:
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Dos cosas que pueden ayudar:
- Uso
Graphics2D.draw(Shape)
con una instancia dejava.awt.geom.Ellipse2D
en lugar deGraphics.drawOval
- Si el resultado todavía no es satisfactoria, intente usar
Graphics2D.setRenderingHint
para habilitar el antialiasing
Ejemplo
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);
}
respuesta
Sede de Josef para un ejemplo de setRenderingHint
Por supuesto se establece su radio a lo que usted necesita:
@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);
}
También es necesario ajustar la posición de la elipse, y creo que no desea g2d.draw g2d.stroke – finnw
Incapacidad para dibujar un "círculo de aspecto decente" está relacionada con la muy antigua fallo 6431487.
Activar el antialiasing no ayuda mucho - solo compruebe el tipo de "círculo" producido por drawOval() o drawShape (Eclipse) cuando el tamaño del círculo requerido es 16 píxeles (todavía bastante común para el tamaño del icono) y antialiasing Está encendido. Los círculos antialias más grandes se verán mejor, pero siguen siendo asimétricos, si alguien se preocupa por mirarlos de cerca.
Parece que para dibujar un "círculo de aspecto decente" hay que dibujar uno manualmente. Sin antialiasing será un algoritmo de círculo de punto medio (este question tiene una respuesta con un bonito código de java para él).
Editado: 06 de septiembre de 2017
Eso es un algoritmo inventado por mí para dibujar un círculo sobre una matriz de enteros. La misma idea podría usarse para escribir un círculo dentro de una Imagen Buffered. Si está tratando de dibujar ese círculo con la clase Graphics, este no es el answare que está buscando (a menos que desee modificar cada asignación de color con g.drawLine (x, y, x + 1, y), pero podría ser muy lento).
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;
}
Lo intenté muchas veces, verificando manualmente su corrección, así que creo que funcionará. No hice ningún control de rango solo para simplificar el código. Espero que te ayude a ti y a todos a dibujar un círculo sobre una matriz (por ejemplo, esos programadores que intentan crear sus propios videojuegos en código puro y necesitan administrar un mapa de juego orientado a la matriz para almacenar los objetos que están sobre el mapa del juego [si necesita ayuda sobre esto, envíeme un correo electrónico]).
Gracias a Oleg Estekhin por señalar el informe de fallos, porque explica cómo hacerlo.
Aquí hay algunos círculos pequeños antes y después. Magnificado algunas veces para ver la cuadrícula de píxeles.
Bajando una fila, se están moviendo ligeramente por cantidades subpíxeles.
La primera columna no contiene sugerencias. El segundo es solo con antialias. El tercero es con antialias y modo puro.
Tenga en cuenta que solo con sugerencias antialias, los primeros tres círculos son iguales y los dos últimos también son iguales. Parece que está ocurriendo una transición discreta. Probablemente redondeando en algún punto.
Aquí está el código. Está en Jython para facilitar la lectura, pero controla la biblioteca de tiempo de ejecución de Java y puede ser portado sin pérdidas a una fuente Java equivalente, con exactamente el mismo efecto.
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"))
Resumen: Se necesitan las dos VALUE_ANTIALIAS_ON
y VALUE_STROKE_PURE
para obtener adecuado mirando los círculos dibujados con precisión de subpíxeles.
- 1. Cómo dibujar un círculo lleno en Java?
- 2. ¿Cómo dibujar un círculo transparente?
- 3. dibujar un círculo lleno
- 4. Dibujar círculo en Android
- 5. Cómo dibujar un círculo concéntrico en iphone?
- 6. WPF: ¿Cómo dibujar un círculo y arrastrarlo?
- 7. Dibujar círculo simple en XNA
- 8. Cómo dibujar un círculo con un color específico en XNA?
- 9. Cómo dibujar un círculo con particionado en Android?
- 10. Cómo dibujar un círculo en img usando php?
- 11. Cómo dibujar un círculo comenzando en la parte superior
- 12. Dibujar texto en superposición de círculo
- 13. OpenGL GLSL Shader: dibujar un círculo en un polígono plano
- 14. Cómo dibujar un círculo sólido con cocos2d para iPhone
- 15. ¿Cómo dibujar una elipse o círculo a mano alzada?
- 16. Cómo cambiar el aspecto de un JButton deshabilitado en java
- 17. Dibuja parte de un círculo
- 18. cómo dibujar autómatas en Java
- 19. ¿Hay alguna manera de dibujar un CGContextDrawRadialGradient como un óvalo en lugar de un círculo perfecto?
- 20. matlab: poner un número en un círculo en un gráfico
- 21. Cómo burlarse de un aspecto
- 22. ¿Es posible dibujar un círculo en un mapa estático de Google?
- 23. ¿Qué aspecto tiene Java en la memoria?
- 24. ¿Cómo dibujar en un JLabel?
- 25. ¿Qué aspecto tiene un método estático de Java en Ruby?
- 26. Dibuja un círculo hueco en SVG
- 27. trazar un círculo con pyplot
- 28. aspecto de Java: cómo romper una dependencia en sun.swing.SwingUtilities2
- 29. Dibujar arco con 2 puntos y el centro del círculo
- 30. UIImage en un círculo
Tienes vínculos de amor de 11 años, la esperanza de que nunca morirán. –
Parece que las constantes se han movido de Graphics2D a RenderingHints. Ver [este ejemplo] (http://www.java2s.com/Code/JavaAPI/java.awt/Graphics2DsetRenderingHintKeyhintKeyObjecthintValue.htm). –
Tiene 17 años ahora ... sigue vivo xD lol – maganap