Rubber-band method drawing lines ??

Does anyone know how to use the rubber-band
method when drawing lines. You click the left mouse button to set the starting point and then makes the line stretches until you release the button.

The line should be like a rubber-band which can be stretched in the direction and the length you want.

PLEASE HELP ME d97opi@du.se

I guess you mean bezier curves…
try a tutorial on http://www.flipcode.com for that.
maybe someone here now knows to tell you some more?

John

Hello

As I understand, you want to click with the mouse for initial position, then the line will follow the mouse until you release the button?

You can do this with GLUT using glutMouseFunc() for handle mousebuttons, and glutMotionFunc() for handle mouse movements.

When you press a mousebutton, set the initial position.
When you move the mouse (with one button down) you draw the line from the initial position, to mouse position.
When you release the button, you can set the end position, and you got a line.

Hi, Bob:

I think what theoden asked is drawing a line in rubber-band method ---- that means if drawing a line from p1 to p2, then you might go back to the position (p1+p2)/2, and you just want the line be drawn from p1 to (p1+p2)/2, you should erase the half from (p1+p2)/2 to p2, Will the way you suggested still work? MotionFunc will draw all the way you moved but only initial to end.

similarly, if I want to move a object from p1 to p2 using mouse to hold the object and do not draw the moving track, what function
and stratage will you recommend?

thank you very much!

Well, Ana

You can use the functions I mentioned above. When glutMotionFunc() is called you get the coordinates of the mouse, then it’s up to you to something with it. I said you draw a line from p1 to mouseposition. If you just want to draw the line from p1 halfway to p2, then calculate another value for p2, thats all.

p1 = valid point on screen
mp = mouseposition

p2.x = p1.x + (mp.x - p1.x)/2
p2.y = p1.y + (mp.y - p1.y)/2

draw line from p1 to p2

Most kind of mousemovements can be done with these functions. However, glutMouseFunc() will only be called when you move the mouse with one or more buttons pressed. There is also a function called glutPassiveMotionFunc() which work similar to glutMotionFunc(), but is called when you move your mouse without any buttons pressed.

Bob

Can’t you get the initial position of the mouse on a mousebutton down event, then get the final position of the mouse on the mousebutton up event?

In between you draw a rectangle every frame from original (mouse x, mouse y) to current (mouse x, mouse y).

Seems simple enough. On the mousebutton up event you have your bounding box which you can then project into the scene to see what you’ve actually selected.

Chris Rasmus
Florida, USA

[This message has been edited by Heaven (edited 01-17-2002).]

I have a rubbber band box example on my website. It is in MFC but the OpenGL code is the same.

http://pws.prserv.net/mfcogl/

//draw with open_gl & glut
#include <gl/glut.h>
#include <stdio.h>
int numLines;
#pragma comment( linker, “/subsystem:“windows” /entry:“mainCRTStartup”” )

typedef enum state
{
waitingforclick,
clickedonce,
};
typedef struct point
{
int x;
int y;
}point;

point lines[256][2] ;

int gState=waitingforclick;
bool lineisvalid=false;
int gHeight;
float gColor[3]={0,1,0};
void drawlines()
{
glColor3fv(gColor);
glBegin(GL_LINES);
for(int i=0; i<=numLines; i++)
{
glVertex2i(lines[i][0].x, gHeight-lines[i][0].y);
glVertex2i(lines[i][1].x, gHeight-lines[i][1].y);
}
glEnd();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
drawlines();
glutSwapBuffers();
}
void menufunc(int val)
{
switch (val)
{
case 0:
gColor[0]=1;
gColor[1]=0;
gColor[2]=0;
break;
case 1:
gColor[0]=0;
gColor[1]=1;
gColor[2]=0;
break;
case 2:
gColor[0]=0;
gColor[1]=0;
gColor[2]=1;
break;
}
}
void createMenu()
{
int menu=glutCreateMenu(menufunc);
glutAddMenuEntry(“Red”, 0);
glutAddMenuEntry(“Green”, 1);
glutAddMenuEntry(“Blue”, 2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
void init()
{
glClearColor(0,0,0,1);
glMatrixMode(GL_PROJECTION);
glOrtho(-1, 1.0, -1, 1.0, -1.0, 1.0);
numLines=-1;
glMatrixMode(GL_MODELVIEW);
createMenu();
}
void reshape(int width, int height)
{
gHeight=height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, 0,height);
glMatrixMode(GL_MODELVIEW);
}

void mouseclick(int button, int state,int x, int y)
{
if(button==GLUT_LEFT_BUTTON && state==GLUT_UP)
{
switch(gState)
{

case waitingforclick:
printf(“one clidk”);
++numLines;
lines[numLines][0].x=x;
lines[numLines][0].y=y;
lines[numLines][1].x=x;
lines[numLines][1].y=y;
gState++;
break;
case clickedonce:
printf(“2 clidk”);
lines[numLines][1].x=x;
lines[numLines][1].y=y;
gState=waitingforclick;
break;
}
}
glutPostRedisplay();
}
void mousedrag(int x, int y)
{
if(gState==clickedonce)
{lines[numLines][1].x=x;
lines[numLines][1].y=y;
}
glutPostRedisplay();
}
int main(int argc, char ** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(500,500);
glutCreateWindow(“My Drawing App”);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMouseFunc(mouseclick);
glutPassiveMotionFunc(mousedrag);
glutPostRedisplay(); //added function for speed and clarity
init();
glutMainLoop();
return 0;
}