Friday, May 6, 2011

Grinded steel plate effect

On my way back from the JAX conference in Mainz last tuesday i saw a stainless steel plate on the train that looked like on this image here. In german this treatment of metal has the name "Zapfenschliff" and is used to give the metal a nice design and a more robust surface.
Taking a closer look to the plate it reminds me on the conical gradient that i created a while ago and in fact it's just a simple pattern made out of many conical gradients.
Well you know me...i have to reproduce it in swing and voila here's a little tutorial on how i realized it. So the principle approach is to create a texture and use this texture to fill some shape with it.
Now you could argue that i simply could take an exsting texture and use it to fill the shape but i like to create the stuff completely in 100% pure Java right...

So first of all we need to create a conical gradient like the following:


And here is the code you need to create a gradient like this...

double diameter = 50;
Ellipse2D circle = new Ellipse2D.Double(0, 0, diameter, diameter);
Point2D center = new Point2D.Double(circle.getCenterX(), circle.getCenterY());
float[] fractions =  
{
    0f,
    0.03f,
    0.10f,
    0.14f,
    0.24f,
    0.33f,
    0.38f,
    0.5f,
    0.62f,
    0.67f,
    0.76f,
    0.81f,
    0.85f,
    0.97f,
    1.0f 
};

Color[] colors = 
{ 
    new Color(0xFDFDFD),
    new Color(0xFDFDFD),
    new Color(0xB2B2B4),
    new Color(0xACACAE),
    new Color(0xFDFDFD),
    new Color(0x6E6E70),
    new Color(0x6E6E70),
    new Color(0xFDFDFD),
    new Color(0x6E6E70),
    new Color(0x6E6E70),
    new Color(0xFDFDFD),
    new Color(0xACACAE),
    new Color(0xB2B2B4),
    new Color(0xFDFDFD),
    new Color(0xFDFDFD) 
};    
ConicalGradientPaint gradient = new ConicalGradientPaint(false, center, -0.45f, fractions, colors);
G2.setPaint(gradient);
G2.fill(circle);

After this we need to create a texture that contains a repeatable pattern of the conical gradient. I created a little drawing to make it easier to understand...



The texture (which will be represented by a BufferedImage object) should be a square rectangle with the given SIZE. In this case i used 2x the diameter of the conical gradient. As you can see we need 13 circles that have to be placed in a pattern where we place 3 circles in the first row, 2 circles in the second row, 3 circles in the third row and so on. The stepsize in x- and y-direction is half the size of the diameter and we start on the upper left corner at x=-stepsize, y=-stepsize.
Here is the code for the creation of the texture...


int amount = 3;
double stepsize = diameter / 2.0;
G2.translate(-stepsize, -stepsize);
AffineTransform oldTransform = G2.getTransform();
for (int y = 0 ; y < 5 ; y++)
{            
    if (y%2 == 0)
    {
        amount = 3;
        G2.translate(0, stepsize * y);
    }
    else
    {
        amount = 2;
        G2.translate(stepsize, stepsize * y);
    }
                                                
    for (int x = 0 ; x < amount ; x++)
    {
        G2.setPaint(gradient);
        G2.fill(circle);
        G2.translate(diameter, 0);                
    }                                    
    G2.setTransform(oldTransform);            
}         


After we have create the BufferedImage object we can use it as a texture in the java.awt.TexturePaint class to fill a shape. And the result could look like this...




On this image we filled a square with four textures but the image was created in Adobe Fireworks, the Java Swing version would look like this...




Fun isn't it ? Well the only problem with this texture is that it looks too perfect right but this is something i'll leave to you...   :-)


As always you will find the sourcecode for this little fun project as a Netbeans project...


SteelPaint.zip


Enjoy your weekend and keep coding...just for the fun of it...

2 comments:

  1. Hallo!

    I'm sorry, but in line 3 - "Point2D center = new jPoint2D.Double(circle.getCenterX(), circle.getCenterY());"
    isn't it should be => "Point2D.Double(circle.getCenterX(), circle.getCenterY());" without 'j' Hm? :)

    ReplyDelete
  2. Hmmm...which typo...? Can't see it (anymore) ;-)
    Cheers,
    Gerrit

    ReplyDelete