Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Drawing Qubic Bezier-splines on Pocket PC

0.00/5 (No votes)
16 Mar 2005 1  
Functions for drawing Bezier splines on Pocket PC. Since they are missing in GDI for Pocket PC.

BezierCETest application.

Introduction

When I started coding a CAD-application program for Pocket PC, I soon found out that GDI on the Pocket PC was limited compared to ordinary Windows GDI. I was in need of drawing splines. So I tried to find a simple, easy to use algorithm on the net, but did not find anything useful.

I looked around for information on Bezier-splines since that is what GDI on Windows uses and I wanted a replacement function for that. And after reading in the book Computer Graphics by Donald Hern and M. Pauline baker, I got an understanding how Bezier-splines worked.

So how does it work?

The code provided uses Qubic Bezier-splines which takes four control points and generates the curve using four blending functions:

  • f1(u) = (1 - u)³
  • f2(u) = 3u(1 - u)²
  • f3(u) = 3u²(1 - u)
  • f4(u) = u³

where 0 <= u <= 1

Below, the function that computes points in the curve is shown. fPoint is just a struct that contains two floats x and y. The blending functions multiplied with the control points are added to the pDstPoint.

void BezierComputePoint(float fU, fPoint* pDstPoint, CPoint* pSrcPoints)
{
    //
    //    Add up all the blending functions multiplied with the control points
    //
    float fBlend;
    float f1subu = 1.0f - fU;

    //
    //    First blending function (1-u)^3
    //
    fBlend = f1subu * f1subu * f1subu;
    pDstPoint->x = fBlend * pSrcPoints[0].x;
    pDstPoint->y = fBlend * pSrcPoints[0].y;

    //
    //    Second blending function 3u(1-u)^2
    //
    fBlend = 3 * fU * f1subu * f1subu;
    pDstPoint->x += fBlend * pSrcPoints[1].x;
    pDstPoint->y += fBlend * pSrcPoints[1].y;

    //
    //    Third blending function 3u^2 * (1-u)
    //
    fBlend = 3 * fU * fU * f1subu;
    pDstPoint->x += fBlend * pSrcPoints[2].x;
    pDstPoint->y += fBlend * pSrcPoints[2].y;

    //
    //    Fourth blending function u^3
    //
    fBlend = fU * fU * fU;
    pDstPoint->x += fBlend * pSrcPoints[3].x;
    pDstPoint->y += fBlend * pSrcPoints[3].y;
}

The next code snippet shows the DrawBezier function. It takes a CDC pointer as input, four control points and how many segments the spline should be divided in. The more segments you use, the better the result but this will take more time. So it's best to experiment for the best results.

Iterate over all the segments and generate a point on the curve. Draw a line between the previous point and the one computed. And at last, draw a line to the ending point.

void DrawBezier(CDC *pDC, CPoint *pPoints, int nSegments)
{
    pDC->MoveTo(pPoints[0]);
    fPoint fPointBezier;
    for(int i = 0; i < nSegments; i++)
    {
        BezierComputePoint(i / (float)nSegments, &fPointBezier, pPoints);
        pDC->LineTo(ROUND(fPointBezier.x), ROUND(fPointBezier.y));
    }
    pDC->LineTo(pPoints[3]);
}

Using the code

Include the Bezier.h in your project and call the functions. Look into the example project for tips. I used PPC 2003 when testing this example but it should not be a problem with older PPC SDKs.

And that's it! Hope you find it useful. Comments and constructive criticism appreciated.

History

2005-03-15 - First release.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here