Draw a curve with control points

 

Environment: VC++ 6.0

One friend asks me how to draw a curve with a couple of mouse clicking. I know there is way called "cubic spline" to draw the curve based on the control points. I search through the internet, try to find out a piece of existing code. Unfortunately, though there are plenty of webpage talking about it, but few sites really give out the working code. I did found some Java code was presented with mess of the other UI handling code; however, I have not found any C/C++ code to finish this job so far. And I am not really a Java lover....

So I finish this piece of C++ header file called "spline.h". Which is easy to use and light weight. All you need to do is:
  1. Include this header file into your C++ file.
  2. Create a spline object.
  3. Pump in the control points.
  4. Gernearte a curve by a simple code line: spline.generate();
  5. Get the curve points to your array.
  6. Paint the curve to your DC.

This is so easy and handy for my future UI curve drawing, and you can also adjust the curve smoothness degree by setting a defined factor in spline.h.

A known bug: the control points should be more than one, if only one control point are pass to the spline, it will crash, I will appreciate it if anybody fix the bug.

Here is the code where I generate the curve, MFC CArray is used for my points array

//create a spline object
Spline spline(m_ControlPoints.GetData(), 
              m_ControlPoints.GetSize());
//generate a curve
spline.Generate();
//get the curve points number
m_CurvePoints.SetSize(spline.GetCurveCount());
//get the points number
int PointCount = 0;
spline.GetCurve(m_CurvePoints.GetData(), 
                PointCount);
//paint the curve
UpdateDialog(pDC->m_hDC);

Downloads

Download source - 34 Kb


Comments

  • How can I do for 3D courbe (with x,y and z)

    Posted by ybenaabud on 09/02/2009 08:35am

    Hi, it is possible to make changes to the source code for doing the same thing but with 3D courbes think you

    Reply
  • How to copy the points to my array?

    Posted by nidolap on 05/20/2007 07:38am

    Hi! Can anyone tell me how can I get the curve points to my own array? Here is my source code : #include "stdafx.h" #include #include "spline.h" int main(int argc, char* argv[]) { float pontox[5] = {2, 4, 5, 8, 12}; float pontoy[5] = {300, 123, 250, 456, 111}; int n = 6; Spline spline(pontox, pontoy, n); spline.Generate(); int p = spline.GetCurveCount(); //spline.GetCurve(); ????? cout << p << "\n"; cout << "\n"; return 0; } Thanks a lot in advance!!!

    Reply
  • I am very grateful for your work!!!

    Posted by kuelite on 03/13/2005 08:38am

    the header file does work perfectly!! i am excited!! thanks !! Good luck!!

    Reply
  • how to move a point using x,y,z co-ordinates

    Posted by lakme2india.com on 03/06/2005 01:35am

    how can i plot a point using x,y,z co-ordinates

    • hi

      Posted by letathien on 04/12/2005 10:32pm

      friend

      Reply
    Reply
  • How to draw closed splines?

    Posted by sunkingac on 12/12/2004 01:06pm

    Hi , I want to draw closed splines using a given set of points... How can i do that...? Actually , I don't know how to use the GenClosed() and drawClosed()functions. Thanks in advance... Arun Chakaravarthy

    Reply
  • how to use this header file in IDC_Static of FormView

    Posted by country0boy on 03/24/2004 10:46am

    how to use this header file in IDC_Static of FormView the curve is not in the IDC_BITMAP why?????? This is my code: ////////////////////////////////////////////// void CTestView3::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here CFormView::OnPaint(); // Do not call CFormView::OnPaint() for painting messages } void CTestView3::OnLButtonDown(UINT nFlags, CPoint point) { //check if the mouse left clicking into one of the control points int index = IsInsideControlPoint(point); if(index >= 0) { //we are moving a control point around m_MoveIndex = index; } else //we are adding control points { CDC* pDC =m_bitmap.GetDC();//right?? DrawCross(point, RGB(255,0,0), 4, pDC->m_hDC); m_ControlPoints.Add(point); if(m_ControlPoints.GetSize()>1) { //create a spline object Spline spline(m_ControlPoints.GetData(), m_ControlPoints.GetSize()); //generate a curve spline.Generate(); //get the curve points number m_CurvePoints.SetSize(spline.GetCurveCount()); //get the points number int PointCount = 0; spline.GetCurve(m_CurvePoints.GetData(), PointCount); //paint the curve UpdateFormView(pDC->m_hDC); } //ReleaseDC(pDC); } CFormView::OnLButtonDown(nFlags, point); } void CTestView3::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if(m_MoveIndex >= 0) { m_ControlPoints[m_MoveIndex] = point; if(m_ControlPoints.GetSize()>1) { Spline spline(m_ControlPoints.GetData(), m_ControlPoints.GetSize()); spline.Generate(); m_CurvePoints.SetSize(spline.GetCurveCount()); int PointCount = 0; spline.GetCurve(m_CurvePoints.GetData(), PointCount); } CDC* pDC = m_bitmap.GetDC(); UpdateFormView(pDC->m_hDC); ReleaseDC(pDC); } CFormView::OnMouseMove(nFlags, point); } void CTestView3::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default m_MoveIndex = -1; CFormView::OnLButtonUp(nFlags, point); } void CTestView3::UpdateFormView(HDC &hDC) { //brush the DC RECT rect; GetDlgItem(IDC_BITMAP)->GetClientRect(&rect);//right?? FillRect(hDC, &rect, (HBRUSH)GetStockObject(IDC_BITMAP));//right?? //draw the control points for(int i=0; i1) Polyline(hDC, m_CurvePoints.GetData(), m_CurvePoints.GetSize()); } int CTestView3::IsInsideControlPoint(POINT& point) { int count = m_ControlPoints.GetSize(); if(count>0) { for(int i=0; i Reply

  • Can you fix Closed Spline case?

    Posted by Legacy on 10/23/2003 12:00am

    Originally posted by: Youngsub Ahn

    Program does not work properly when I changed spline.generate() to spline.genClosed().
    Can you fix this?

    Thank you.

    • How to change the knots

      Posted by Jenniflower on 07/09/2004 05:26am

      I want to smooth a closed curve using this method and I am really a green hand. How can I make it work ? Do appreciate your help!

      Reply
    • It works

      Posted by arereal on 06/05/2004 06:33am

      Hi Raffy, yes, that worked. I changed the code to use GenClosed and drawClosed and bingo! Cheers :)

      Reply
    • end point

      Posted by raffy on 06/02/2004 06:03pm

      Hi Arereal, maybe your end point coincides with the starting point. Try to use the functions for closed splines with n-1 knots and let me know. raffy

      Reply
    • closed splines

      Posted by arereal on 05/27/2004 02:21pm

      Hi Raffy,
      
      I too was looking at making this a closed spline, I applied your change and it doesn't seem to make a difference, here's the code snippet...
      
      // Matrix
      for(i=1; i<=NP-1;i++) 
      {
      	Mat[0][i] = 1.0f;
      //	Mat[1][1] = 2.0f*k[i-1]*(1.0f + k[i-1]);
      	Mat[1][i] = 2.0f*k[i-1]*(1.0f + k[i-1]);
      	Mat[2][i] = k[i-1]*k[i-1]*k[i];
      }
      
      Arereal

      Reply
    • closed splines

      Posted by raffy on 05/24/2004 11:05am

      You only need to replace the line:
       Mat[1][1] = 2.0f*k[i-1]*(1.0f + k[i-1]);
      with
       Mat[1][i] = 2.0f*k[i-1]*(1.0f + k[i-1]);
      
      Raffy

      Reply
    Reply
  • bug NP == 1

    Posted by Legacy on 07/14/2003 12:00am

    Originally posted by: Esther

    Thanks a lot for your work!
    I've searched long and hard for a working solution that
    involves the drawing of curves.
    Your solution matched my needs perfectly!
    I managed to find your bug:
    The function Generate contains the following line:

    k[NP-2] = 1.0f;

    At NP == 1 this means accessing k at index -1.

    Reply
  • is it all needed?

    Posted by Legacy on 11/11/2002 12:00am

    Originally posted by: wadim

    ever heard of windows GDI function named PolyBezier()?
    :-)

    wadim

    Reply
  • Draw a tangent on a spline.

    Posted by Legacy on 09/28/2002 12:00am

    Originally posted by: Raman

    We are doing something similar in a graphics project, where we require to draw a tangent at any of the user selected points generated for the spline. please help with ideas.

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • CentreCorp is a fully integrated and diversified property management and real estate service company, specializing in the "shopping center" segment, and is one of the premier retail service providers in North America. Company executives travel a great deal, carrying a number of traveling laptops with critical current business data, and no easy way to back up to the network outside the office. Read this case study to learn how CentreCorp implemented a suite of business continuity services that included …

Most Popular Programming Stories

More for Developers

RSS Feeds