Drawing Simple circle using java 2D

I was looking for an example implementation of circle for debugging on the forum, didnt find an example

so here is another implementation using Graphic 2D for those who want to.

with this implementation, you can set a fill color and decide of the angle of the arc drawn.

a circle is a node with a Quad Child having a texture generated by Java2D
this is just an exemple so you guys can do other things, draw rectangles and stuff.
if you update anything, just call circle.generateImage(), so the texture gets updated.

and if you want to rotate the circle, just use the regular stuff you do with Nodes, dont edit the child node, just rotate the parent.

Result :

Usage :
[java]
//Usage :

     Circle circle = new Circle(assetManager,50,5,Color.GRAY,360,Color.red,45);
    circle.setLocalTranslation(0, 0, 0);
    app.getRootNode().attachChild(circle);

[/java]

[java]
/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package other;

import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture2D;
import com.jme3.texture.plugins.AWTLoader;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

/**
*

  • @author bobo
    */
    public class Circle extends Node {
    private float radius = 5;
    private int angle = 360;
    private int borderAngle = 360;
    private Color color = Color.BLACK;
    private Color fillColor = null;
    private AssetManager assetManager;
    private final Texture texture = new Texture2D();
    private float borderWidth;
    private int heightResolution = 64;
    private int widthResolution = 64;
    private Material material;
    private Geometry geometry;

    /**
    *

    • @param assetManager
    • @param radius radius of the circle
    • @param borderWidth width of the border
    • @param color fill color
    • @param borderAngle and of border displayed
    • @param fillColor filled color
    • @param angle and gle of the filled color
      */
      public Circle(AssetManager assetManager, float radius, float borderWidth, Color color, int borderAngle, Color fillColor, int angle) {
      this.assetManager = assetManager;
      this.radius = radius;
      this.color = color;
      this.fillColor = fillColor;
      this.borderWidth = borderWidth;
      this.borderAngle = borderAngle;
      this.angle = angle;
      material = new Material(this.assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);
      material.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
      initSpatial();
      updateSpatial();
      }

    private void initSpatial() {
    generateImage();
    Quad q = new Quad(10, 10);
    geometry = new Geometry(“circle”, q);
    geometry.rotate(-3.1416f / 2, 0, 0);
    geometry.setMaterial(material);
    this.attachChild(geometry);
    }

    private void updateSpatial() {
    geometry.setLocalScale(radius / 10f, radius / 10f, radius / 10f);
    }

    public void generateImage() {
    BufferedImage image = new BufferedImage(widthResolution, heightResolution, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = image.createGraphics();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    if (fillColor != null) {
    g.setColor(fillColor);
    g.fillArc((int) borderWidth / 2, (int) borderWidth / 2, (int) (widthResolution - 1 - borderWidth), (int) (heightResolution - borderWidth), 180+(angle/2), -angle);
    }
    g.setStroke(new BasicStroke(borderWidth));
    g.setColor(color);
    g.drawArc((int) borderWidth / 2, (int) borderWidth / 2, (int) (widthResolution - 1 - borderWidth), (int) (heightResolution - borderWidth), 180 +(borderAngle/2), -borderAngle);

     AWTLoader awtLoader = new AWTLoader();
     texture.setImage(awtLoader.load(image, false));
     material.setTexture("ColorMap", texture);
    

    }

    public void setRadius(float radius) {
    this.radius = radius;
    updateSpatial();
    }

    public void setFillColor(Color fillColor) {
    this.fillColor = fillColor;
    }

    public void setColor(Color color) {
    this.color = color;
    }

    public void setBorderWidth(float borderWidth) {
    this.borderWidth = borderWidth;
    }

    public void setResolution(int resolution) {
    this.heightResolution = resolution;
    this.widthResolution = resolution;
    }

}

[/java]

Cool. Thanks for sharing!

Thanks.
Added to SimpleExamples project.
https://code.google.com/p/jme-simple-examples/source/detail?r=6f6d5279905c45aa11136ccf280514d11bf97f88

If you want i can add you as a committer to the SimpleExamples project and you can do your experiments there.

It would be nice to add this facility to ImagePainter so that the dependency on graphics 2d can be avoided :slight_smile:

yep, awt and android do not play nice together!

almost as much as @zarch and @pspeed

oh thats nice mifth,
I just tweaked your Circle2DTest example a little bit to show what we can do with it, here is the code:

Result:

here is the code if you wanna update your example
[java]
package com.intermediate;

/*You can get transforms from *.blend files and use your models for it.

  • Blender could be used as a World Editor or scene composer.
  • Names of JME objects and blend objects should be like:
  • JME names - Box, Sphere
  • blend names - Box, Box.000, Box.001, Box.002… Sphere, Sphere.000, Sphere.001…
    /
    import com.jme3.app.SimpleApplication;
    import com.jme3.font.BitmapText;
    import com.jme3.math.
    ;
    import com.jme3.system.AppSettings;
    import java.awt.Color;

import java.util.Random;

import other.Circle2D;

public class CircleTest2D extends SimpleApplication {

public static void main(String[] args) {

    AppSettings settings = new AppSettings(true);
    settings.setTitle("Circle");
    settings.setResolution(800, 600);
    CircleTest2D app = new CircleTest2D();
    app.setSettings(settings);
    app.setPauseOnLostFocus(false);
    app.setShowSettings(false);

    app.start();
}

@Override
public void simpleInitApp() {
    Random randomGenerator = new Random();
  
    for (float i = 0; i < settings.getWidth(); i+=settings.getWidth()/10) {
        for (float j = 0; j < settings.getHeight(); j+=settings.getHeight()/10) {
            int borderAngle = randomGenerator.nextInt(360); 
            int innerAngle = randomGenerator.nextInt(360); 
            Color randomBorderColor = new Color(randomGenerator.nextInt(255), randomGenerator.nextInt(255), randomGenerator.nextInt(255));
            Color randomInnerColor = new Color(randomGenerator.nextInt(255), randomGenerator.nextInt(255), randomGenerator.nextInt(255));
            Circle2D circle = new Circle2D(assetManager, 1, randomGenerator.nextInt(20), randomBorderColor, borderAngle, randomInnerColor, innerAngle);
            circle.setLocalTranslation(0, 0, 0);
            guiNode.attachChild(circle);
            circle.rotate(90, 0,0);
            circle.setLocalTranslation(new Vector3f(i , j, 0));
            circle.scale(70);
        }
    }
    guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
    BitmapText ch = new BitmapText(guiFont, false);
    ch.setSize(guiFont.getCharSet().getRenderedSize());
    ch.setText("Circle2d Mesh Example"); // crosshairs
    ch.setColor(new ColorRGBA(1f, 0.8f, 0.1f, 1f));
    ch.setLocalTranslation(settings.getWidth() * 0.3f, settings.getHeight() * 0.1f, 0);
    guiNode.attachChild(ch);

    flyCam.setEnabled(false);
    viewPort.setBackgroundColor(ColorRGBA.Gray);

}

@Override
public void simpleUpdate(float tpf) {

// circle.generateImage();
}
}

[/java]

@navycougar said: oh thats nice mifth, I just tweaked your Circle2DTest example a little bit to show what we can do with it, here is the code: ..... here is the code if you wanna update your example ....

Thank you man! Nice example! Updated!
https://code.google.com/p/jme-simple-examples/source/detail?r=20c945d83cef7fe3650aa6503ea33f7a8020f774

@wezrule said: yep, awt and android do not play nice together!

almost as much as @zarch and @pspeed

Actually, I thought we played very nice together. How many technical discussions go on that long without getting personal? :slight_smile:

It’s pretty rare the two of us disagree on something actually, so it was an interesting discussion.

@navycougar is it possible to convert svg vector file to texture using your method? it would be really cool.
Just like these svg vector files:
http://streambag.se/files/freebsdlogo.svg
http://upload.wikimedia.org/wikipedia/commons/5/53/GNU_and_Tux.svg

@mifth said: @navycougar is it possible to convert svg vector file to texture using your method? it would be really cool. Just like these svg vector files: http://streambag.se/files/freebsdlogo.svg http://upload.wikimedia.org/wikipedia/commons/5/53/GNU_and_Tux.svg

Hey mifth, it is possible to generate a BufferedImage or an Awt Image from an SVG here are some links :

http://bbgen.net/blog/2011/06/java-svg-to-bufferedimage/
http://xmlgraphics.apache.org/batik/javadoc/org/apache/batik/svggen/SVGGraphics2D.html

if you are having issues with the examples resolution, you can change the resolution of the circle by increasing the widthResolution and heighResolution of circle2D, by default its set to 64x64, if that’s not enough just increase to 256x256 ^^