• Advertisement

Archived

This topic is now archived and is closed to further replies.

Bezier curve program... strange... HELP!

This topic is 5842 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've created a program for drawing bezier curves with points specified by mouse clicks.. the problem is that the curve has a gap in it. The more or less I put the Linestrip counter the greater the gap is... please view the code(run it if you must) and help me out if you can. And 1 thing I can't figure out is why a point turns red(becomes selected) when created. I set the selected flag of the point to false upon creation. Forgive my sloppy coding... I'm a newbie! Thanks for looking.
          
//include files

HDC g_HDC;	//global device context

bool fullScreen = false;		// true = fullscreen; false = windowed

bool keyPressed[256];			// holds true for keys that are pressed	

int mouseX,mouseY;

struct point //linked list for mouse points

{
	float x; 
	float y;
	bool sel; //selected flag

	point* next;
	point* prev;
};

point* head; //head of list

point* tail; //tail of list

double ControlPoints[4][3]={ {0,0,0},{0,0,0},{0,0,0},{0,0,0}}; //control points for bezier curve (quadratic)

float angle;

bool CheckPoints(point* p1) //function to check whether specified point already exists

{
	point *s=new point;
	s=head; 
	bool got=false; //return flag

	while(s!=NULL)
	{
		if((s->x==p1->x) && (s->y==p1->y)) //checking if x and y of specified point already exists

		{
			s->sel=true; //set the selected flag of specified point to true

			got=true;    //set return flag to true

		}
		else
			s->sel=false; 
//select return flag of point to 0 (in case it was previously selected)

			s=s->next; //traverse to the next list

	}	
	return got; //return the flag


}



void AddPoint(point* p1) //function appends a point to the end of the linked list

{
if(!CheckPoints(p1)) //if the point doesn't exist

	{
		if(head==NULL) //if list is empty

		{
		head=p1; //put current point to head

		p1->prev=NULL; //the previous point to null

		}
		else //if the list is not empty

		{
	
		tail->next=p1; //put the tail next pointer to p1

		p1->prev=tail; // put the previos pointer of p1 to tail

		}
	
	 tail=p1; // assign the end of the list point to p1

	 p1->next=NULL; // the next of the end is null

	 
	}	
}

void MovePoint() //function to move the point

{
	point* p1=new point; //pointer to traverse

	point* t1=new point; //pointer to hold selected point

	t1=head; //assign both pointers to the beginning of list

	p1=head; 
			while(p1!=NULL) 
			{	
				if(p1->sel==true)t1=p1; //assign the selected point to t1

				p1=p1->next;
				 
			}

			if(t1->sel==true) //check to see if we got a selected point

			{
				t1->x=mouseX; //assign the new coordinates

				t1->y=mouseY;
			}
}
void DeletePoint(point* p1)//function to delete point

{
	if(p1->prev==NULL)  //check to see if beginning of list

			head=p1->next; //put the head to the next point

	else //if not beginning of list

		p1->prev->next=p1->next; 
//assign the pointer to the previous points next point as the current points next point

		
	if(p1->next==NULL) //check to see if at end of the list

		tail=p1->prev; 
//assign the end of the list to the current points previous point

	else //if not the end of the list

		p1->next->prev=p1->prev; 
//assign the pointer to the next points previous point as the current points previous point 

}

void DeleteAllPoints() //function to delete all points

{
	while(head!=NULL)
			DeletePoint(head);
}



void Initialize()
{
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);		// clear to black


	glShadeModel(GL_SMOOTH);						// use smooth shading

	glEnable(GL_DEPTH_TEST);					// hidden surface removal


}







void Render()
{	

	GLint viewport[4]; 
	GLdouble mvmatrix[16], projmatrix[16];
	GLint realy; /* OpenGL y coordinate position */
	GLdouble wx, wy, wz; /* returned world x, y, z coords */
	glGetIntegerv (GL_VIEWPORT, viewport);
	glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
	glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
	int k;
	int c=0;
	point* p1=new point;
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		
	glLoadIdentity();
	glTranslatef(-5.0f,0,-10.0f);
	glColor3f(1.0f,1.0f,1.0f);
	 
	
	p1=head;
	glPointSize(3.0);
	
	while(p1!=NULL) //traverse the list
	{		
			
		glBegin(GL_POINTS); //following code specifies points
			if(p1->sel)glColor3f(1.0f,0.0,0.0); //if the point is a selected one change color to red
			else glColor3f(1.0f,1.0f,1.0f); //else change color to white
			/* note viewport[3] is height of window in pixels */
			realy = viewport[3] - (GLint) p1->y; //get the y coordinate

			gluUnProject ((GLdouble) p1->x, (GLdouble)realy, 0.0,
			mvmatrix, projmatrix, viewport, &wx, &wy, &wz); 
//convert the current coordinates to OpenGL world coordinates

			glVertex3d(wx,wy,wz); //draw point

		glEnd();
		ControlPoints[c][0]=wx; //set the control point coordinates with the world coordinates

		ControlPoints[c][1]=wy;
		ControlPoints[c][2]=wz;
		if(c==3) //if the point is the 4th point then draw the curve

		{
			
			glMap1d(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ControlPoints[0][0]);
			glEnable(GL_MAP1_VERTEX_3);
			glBegin(GL_LINE_STRIP);
				for (k = 0; k <= 20; k++)
					glEvalCoord1f((float)k/20.0f);
			glEnd();
			c=-1; //assign the ControlPoint counter to -1

		}
		p1=p1->next; //move to the next point on the list

		c++; //increment control point counter

	
	}

	glFlush();
	SwapBuffers(g_HDC);
}
void SetupPixelFormat(HDC hDC)
{
	.......
}

// the Windows Procedure event handler

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HGLRC hRC;					// rendering context

	static HDC hDC;						// device context

	int width, height;					// window width and height

    int oldMouseX, oldMouseY;
	static bool LButton;

point* p1=new point;
	switch(message)
	{
		case WM_CREATE:					// window is being created


			hDC = GetDC(hwnd);			// get current window's device context

			g_HDC = hDC;
			SetupPixelFormat(hDC);		// call our pixel format setup function


			// create rendering context and make it current

			hRC = wglCreateContext(hDC);
			wglMakeCurrent(hDC, hRC);

			return 0;
			break;

		case WM_CLOSE:					// windows is closing


			// deselect rendering context and delete it

			wglMakeCurrent(hDC, NULL);
			wglDeleteContext(hRC);

			// send WM_QUIT to message queue

			PostQuitMessage(0);

			return 0;
			break;

		case WM_SIZE:
			height = HIWORD(lParam);		// retrieve width and height

			width = LOWORD(lParam);

			if (height==0)					// don't want a divide by zero

			{
				height=1;					
			}

			glViewport(0, 0, width, height);	// reset the viewport to new dimensions

			glMatrixMode(GL_PROJECTION);		// set projection matrix current matrix

			glLoadIdentity();					// reset projection matrix


			// calculate aspect ratio of window

			gluPerspective(54.0f,(GLfloat)width/(GLfloat)height,1.0f,1000.0f);

			glMatrixMode(GL_MODELVIEW);			// set modelview matrix

			glLoadIdentity();					// reset modelview matrix


			return 0;
			break;

		case WM_KEYDOWN:					// is a key pressed?

			keyPressed[wParam] = true;
			return 0;
			break;

		case WM_KEYUP:
			keyPressed[wParam] = false;
			return 0;
			break;
		
		

			
		case WM_MOUSEMOVE:
			// save old mouse coordinates

			oldMouseX = mouseX;
			oldMouseY = mouseY;
	
			// get mouse coordinates from Windows

			mouseX = LOWORD(lParam);
			mouseY = HIWORD(lParam);
		

			if(LButton)//if the left mouse button is down attempt to move the point

				MovePoint(); 
			
	
		
			return 0;
			break;
		case WM_LBUTTONDOWN:
			LButton=true; //set the Left button down flag to true for WM_MOUSEMOVE

			p1->x=(float)mouseX; //assign the mouse coordinates to p1

			p1->y=(float)mouseY; 
			p1->sel=false; //set the selected flag to false

			AddPoint(p1); //add the point to the list

		
			return 0;
			break;
		case WM_LBUTTONUP:
			LButton=false; //set the Left button down flag to false for WM_MOUSEMOVE

			return 0;
			break;
		default:
			break;
	}

	return (DefWindowProc(hwnd, message, wParam, lParam));
}

// the main windows entry point

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	....................

	DeleteAllPoints();

	......................
}
          
----------------------------- "Give a man a fish and you feed him for a day, teach him to use the Net and he won't bother you for weeks." ~wUn LoVe tO aLl ThE mAlUs OuT tHeRe!~ Edited by - mAdMaLuDaWg on February 25, 2002 3:01:05 PM Edited by - mAdMaLuDaWg on February 25, 2002 3:11:23 PM Edited by - mAdMaLuDaWg on February 25, 2002 3:13:09 PM Edited by - mAdMaLuDaWg on February 25, 2002 11:39:07 PM

Share this post


Link to post
Share on other sites
Advertisement
I haven''t got through all the code yet, but it looks like you have a nasty memory leak in your wndProc. Everytime you enter it you are making a new point, and assigning its address to p1, but p1 only gets used if the left mouse button was clicked. When you exit the function the address of the point is thrown away without deleting the point.

It''s only a small structure, but you lose one every time the mouse moves, a key is pressed, the window needs repainting....

Share this post


Link to post
Share on other sites
Thanks for pointing that out... but still didn't fix it ;-(. So setting p1=NULL at the end of WNDProc should fix it, and this should be done at the end of functions which use pointers as well. Right?
BTW, how many points do you think would take up a considerable amount of memory.

Edited by - mAdMaLuDaWg on February 25, 2002 4:13:13 PM

Share this post


Link to post
Share on other sites
quote:
Original post by mAdMaLuDaWg
Thanks for pointing that out... but still didn''t fix it ;-(. So setting p1=NULL at the end of WNDProc should fix it, and this should be done at the end of functions which use pointers as well. Right?


Aiiieee! not quite
If you have created a point like this:
point *ptr = new point;

And you don''t need it anymore, use:
delete ptr;

Then set ptr=NULL to prevent yourself from trying to access the point (which is no longer there).

You don''t happen to be switching from Java to c++ do you? Its just that in a lot of cases you are using new to create a point when it isnt needed. At the start of CheckPoints you create a new point and store its address in s, then you overwrite s with the value of head. All you need to do is point *s = head. There are quite a few places where you''re doing something like that.

quote:

BTW, how many points do you think would take up a considerable amount of memory.



One point is 2 floats, 2 pointers and a boolean. Odds are that''ll come to 20 bytes (depending on the alignment). It''s insignificant on its own, but if you leak enough of them you''ll have trouble. I mainly picked up on it for neatness, and it probably won''t cause you trouble right now. That said, it would be wise to learn how to avoid leaking resources, because the next structure you leak might be a lot bigger.

Now I have to admit that fixing all this probably wont fix the symptoms you described. I couldn''t see any reason for the curves to have gaps in, or for the points to always be selected. I''m not too well up on OpenGL though - I know the basics, but switched to DirectX before learning about evaluators.

PS: Could you edit your post and break some of the longer comments into two lines? The source block goes off the edge of my browser. Ta

Share this post


Link to post
Share on other sites
Thanks. No I haven''t switched from java it''s just that I haven''t programmed in C++ for quite some time and I''m a bit rusty on the edges.
Could someone else give it a shot. Why does my bezier curves have gaps in them?

-----------------------------
"Give a man a fish and you feed him for a day, teach him to use the Net and he won''t bother you for weeks."

~wUn LoVe tO aLl ThE mAlUs OuT tHeRe!~

Share this post


Link to post
Share on other sites
Someone please try to help me. I have gone over my code like a million times. Moreover, I created a program to draw bezier surfaces in a similar way but I''m getting gaps in it too. So could some kindly tell me why is there a gap in my Bezier line, when created in the program. I''ve noticed that the more or less I change k in the linestrip loop the greater the gaps become.
Thanks a lot.

-----------------------------
"Give a man a fish and you feed him for a day, teach him to use the Net and he won''t bother you for weeks."

~wUn LoVe tO aLl ThE mAlUs OuT tHeRe!~

Share this post


Link to post
Share on other sites

  • Advertisement