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:
- Include this header file into your C++ file.
- Create a spline object.
- Pump in the control points.
- Gernearte a curve by a simple code line: spline.generate();
- Get the curve points to your array.
- 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);

Comments
How can I do for 3D courbe (with x,y and z)
Posted by ybenaabud on 09/02/2009 08:35amHi, it is possible to make changes to the source code for doing the same thing but with 3D courbes think you
ReplyHow to copy the points to my array?
Posted by nidolap on 05/20/2007 07:38amHi! 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!!!
ReplyI am very grateful for your work!!!
Posted by kuelite on 03/13/2005 08:38amthe header file does work perfectly!! i am excited!! thanks !! Good luck!!
Replyhow to move a point using x,y,z co-ordinates
Posted by lakme2india.com on 03/06/2005 01:35amhow can i plot a point using x,y,z co-ordinates
-
Replyhi
Posted by letathien on 04/12/2005 10:32pmfriend
ReplyHow to draw closed splines?
Posted by sunkingac on 12/12/2004 01:06pmHi , 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
Replyhow to use this header file in IDC_Static of FormView
Posted by country0boy on 03/24/2004 10:46amhow 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:00amOriginally posted by: Youngsub Ahn
Program does not work properly when I changed spline.generate() to spline.genClosed().
Can you fix this?
Thank you.
-
-
-
-
-
Reply
ReplyHow to change the knots
Posted by Jenniflower on 07/09/2004 05:26amI 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!
ReplyIt works
Posted by arereal on 06/05/2004 06:33amHi Raffy, yes, that worked. I changed the code to use GenClosed and drawClosed and bingo! Cheers :)
Replyend point
Posted by raffy on 06/02/2004 06:03pmHi 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
Replyclosed splines
Posted by arereal on 05/27/2004 02:21pmHi 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]; } ArerealReplyclosed splines
Posted by raffy on 05/24/2004 11:05ambug NP == 1
Posted by Legacy on 07/14/2003 12:00amOriginally 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.
Replyis it all needed?
Posted by Legacy on 11/11/2002 12:00amOriginally posted by: wadim
ever heard of windows GDI function named PolyBezier()?
:-)
wadim
ReplyDraw a tangent on a spline.
Posted by Legacy on 09/28/2002 12:00amOriginally 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.
ReplyLoading, Please Wait ...