Page 4
Cartoon-Style layered terrains
Page 5
Index
See this article in english 
Page 6
Cartoon-Style clouds

Random cartoon flowers

Alexander Hristov

Cartoon flowers are another type of graphic that can be procedurally generated. Many flowers have the same graphical structure : a central part (kernel) and a repeating structure ("petal") that is rotated around this central part.

Daffodil Daisy Dandelion

The petal itself has horizontal symmetry :

Petal

This means that in order to generate a random flower, it is enough to generate half of a petal, then construct the other half symmetrically and finally rotate it a number of times around a central location:

Flower construction

We want the petal to vary more or less gently, without sharp edges and without huge variations. To do that, we'll construct it as a series of connected quads. We'll start with several basic parameters:

With these parameters, the algorithm proceeds as follows:

  1. We start at the bottom end of the flower, placing the starting point at the predefined ("aperture") distance from the middle of the image.
  2. We subdivide the available height into a number of equally-spaced segments.
  3. For each of these segments, we compute two points for making a quad : one lies on the edge of the area (the black dots in the diagram above), while the other one lies in a random location within the area (the red dots above). While doing this, we store the computed points in a pair of arrays.
  4. When we have reached the final segment (cp2), we compute a "connecting quad". The connecting quad uses a control point (mp) that is placed exactly on the axis of symmetry. The vertical position of this middle point is determined randomly.
  5. We now proceed downwards, using the stored point locations to compute their horizontal reflections with respect to the axis of symmetry.
  6. Finally, we close the path and we have our petal ready:

The above method can be implemented in a few lines using the following Java code:

 
    GeneralPath petal = new GeneralPath();
    int flowerSize = 128;
    int upsize=flowerSize/5;
    int aperture = rnd.nextInt(5)+5;
    int cp = rnd.nextInt(5)+3;
    int[] fx = new int[2*cp+3];
    int[] fy = new int[2*cp+3];
    petal.moveTo(flowerSize/2-aperture,upsize+flowerSize);
    fx[2*cp+2] = flowerSize/2-aperture;
    fy[2*cp+2] = upsize+flowerSize;
    for (int i = cp; i >= 0; i--) {
      fx[2*i] = rnd.nextInt(flowerSize/2);
      fy[2*i] = upsize+flowerSize/cp*i;
      fx[2*i+1] = rnd.nextInt(flowerSize/2);
      fy[2*i+1] = upsize+fy[2*i]+rnd.nextInt(flowerSize/cp*(i+1)-flowerSize/cp*i);
      petal.quadTo(fx[2*i+1],fy[2*i+1],fx[2*i],fy[2*i]);
    }
    // Connecting quad
    petal.quadTo(flowerSize/2,upsize+rnd.nextInt(upsize)-2*upsize,flowerSize-fx[0],upsize);
    
    // Compute reflected points
    for (int i = 0; i <= cp; i++) {
      petal.quadTo(flowerSize-fx[2*i+1],fy[2*i+1],flowerSize-fx[2*i+2],fy[2*i+2]);
    }
    petal.closePath();  
  
 

Once we have this path, we can proceed to make the flower by rotating the filled path around a central point located at (size/2, size). We can parametrize this process by deciding how many petals we want. Since we generally want all petals spread along the full circumferece, the rotation angle for each one will be 360/petals. Also, it helps if we fill each petal not with a solid color but  a gradient oriented diagonally.

Here's the part of the code that builds the flower:

 
    int kernelSize = 20;
    int petals = 10;
    Color flowerColor = new Color(0x00AAFF);
    Color kernelColor = new Color(0x00FFFF);
    BufferedImage flowerImage = 
       new BufferedImage(2*flowerSize,2*flowerSize,BufferedImage.TYPE_INT_ARGB);
    Graphics2D gFlower = flowerImage.createGraphics();
    double angle = 2*Math.PI/petals;
    gFlower.translate(flowerSize/2,0);
    
    // Draw the petals
    for (int i = 0; i <= petals; i++) {
      gFlower.setPaint(
         new GradientPaint(0,0,flowerColor,flowerSize,flowerSize,new Color(0)));
      gFlower.fill(petal);
      gFlower.setColor(new Color(0));
      gFlower.draw(petal);
      gFlower.rotate(-angle,flowerSize/2,flowerSize);
    }
    
    // Draw the kernel
    if (kernelSize != 0) {
      gFlower = flowerImage.createGraphics();
      gFlower.setColor(new Color(0));
      gFlower.fillOval( flowerSize-kernelSize,flowerSize-kernelSize,
                        2*kernelSize,2*kernelSize);
      gFlower.setColor(kernelColor);
      gFlower.fillOval( flowerSize-kernelSize+1,flowerSize-kernelSize+1,
                        2*kernelSize-2,2*kernelSize-2);
    }    

 

Here are some results that you can obtain with the above two snippets combined:

Sample Flower 1
Sample Flower 2
Sample Flower 3

The FlowerTutorial.java application included contains the above code and is a fully-working application.

Source code



 

Comments

 

Add a Comment

Name (optional)
EMail (optional, will not be displayed)

Text