The Allegro Wiki is migrating to github at https://github.com/liballeg/allegro_wiki/wiki

Bezigon drawing

From Allegro Wiki
Jump to: navigation, search

A VectorGraphics Subject.

What is a Bezigon

A bezigon is a closed 2d shape similar to a polygon, but with Bezier curves as edges.

Note

  • As bezier curves can be straight lines, a polygon is a special instance of a bezigon. Anyways, if you need to draw polygons, just use the polygon routine that comes with Allegro, is faster.

How Bezigons are drawn

Bezier curves can be approximated into short straight lines. A good algorithm can select the right step size to give a visually smooth curve without generating too many extra points, as this will affect performance.

Once you have subdivided the bezier curves, you are left with a polygon, which can be drawn like any other polygon, using Allegro functions.


Example in C

Kronoman's original C demo <highlightSyntax language="cpp">/* Bezigon drawing routines Experimental, not optimized By Kronoman - In loving memory of my father Aug-2003 Released under The MIT license

  • /
  1. include <allegro.h>
  1. include <stdlib.h>

/*

* Parameters:
* bmp      = bitmap: where to draw?
* point_c = how many control points (is the size of the points array) (must be multiple of 8!, minimun 8)
* points   = array of points [0]=x,[1]=y,[2]=x,[3]=y, etc... 
* color    = color to draw it
* res = resolution of drawing the bezier (bigger = +smooth), like 8,16,20,64 etc (try to keep it small)
  • /

void draw_bezigon(BITMAP *bmp, int point_c, const int *points, int color, int res) {

  int *polbuf = NULL; /* buffer to store the points for the polygon */
  int *bezbufx = NULL;  /* buffer for calc spline coords */
  int *bezbufy = NULL; 
  int spl[8] ; /* coords of the spline control points */
  int i = 0, cv = 0, poli = 0; /* aux vars */


  if (point_c < 8) return; /* we need at least 8!! */
  /* allocate the buffers */
  polbuf = (int *)malloc(sizeof(int) * (point_c * 2 * res)); 
  if (polbuf == NULL) return ; // ERROR, out of RAM - DEBUG - put a error message, or something
  bezbufx = (int *)malloc(sizeof(int) * (res*2));
  if (bezbufx == NULL) 
  {   
     free(polbuf);
     return; // ERROR 
  }
  bezbufy = (int *)malloc(sizeof(int) * (res*2));
  if (bezbufy == NULL) 
  {
     free(polbuf);
     free(bezbufx);
     return; // ERROR
  }
  /* take all the spline coords */
  cv = 0; /* when we take 8 points we calc a spline */
  poli = 0; /* poli buffer index */
  for (i=0; i < point_c; i ++)
  {
     spl[cv] = points[i];
     cv ++;
     if (cv == 8)
     {
        calc_spline(spl, res, bezbufx, bezbufy); /* rock 'n roll */
        /* add the points to the poly buffer */
        for (cv = 0; cv < res; cv ++)
        {
     
           circlefill(bmp, bezbufx[cv], bezbufy[cv], 1, makecol(255,255,255));  /* DEBUG - remove this line */
     
           polbuf[poli] = bezbufx[cv];
           polbuf[poli+1] = bezbufy[cv];
           poli += 2;
        }
     cv = 0;
     }
  }
  /* draw the poly */
  polygon(bmp, poli/2, polbuf, color );
  /* clean the mess */
  free(polbuf);
  free(bezbufx);
  free(bezbufy);

}

</highlightSyntax>


Example in C++

TODO: post kronoman's new C++ demo. (edit)


For now, the demo in C++ is inside this ZIP file. Notice that is old code, and the design may change at any moment.

To test the demo, use mouse left click to add nodes, right click to render, and SPACE to clear. ESC to quit (after render).