vtgyrlz619
April 27th, 2004, 01:34 PM
I posted code that draws 3 lines using a parametric incremental line drawing algorithm. The default shows the REAL lines (just using GL_LINES) toggle by pressing "L" and it will show the scan converted lines.
The problem is:
Notice how the color is jus a solid red (or sometimes blue) I'm supposed to add a different color to each endpoint of the line
and color the intermediary points (between the two endpoints)
using linear interpolation. I used an incremental algorithm, if you look for r, r0, r1, dr .. and so on (those lines of code has to do with the attempted coloring of the line), but not working..
also the reshape function decided not to work one day. I had it working and somehow modifying the lines of code NOT a part of the reshape function affected it somehow, if ne one can help me, please, thanks.
........
.....
//global variables - necessary evil when using GLUT
//global width and height
int GW;
int GH;
//current mouse position in pixel coordinate
int x;
int y;
//a structure to store 2D points - this could also be a class
typedef struct vector2 {
float x;
float y;
} vector2;
//an array to store ten 2D points
vector2 points[6];
typedef struct scans{
vector2 coord[2];
} scans;
scans scanLine[3];
//keep track of the number of points stored thus far
int num_pts;
int mode;
//converts x pixel coordinate to world coordinate
float p2w_x(int p_x){
float l = ((float)GW*(-1.0))/(float)GH;
float r = (float)GW/(float)GH;
float x_i = (2.0*((float)p_x - ((float)GW - 1.0)/2.0))/(float)GW;
return(((r-l)*(x_i - ((-r-l)/(r-l))))/2.0);
}
//converts y pixel coordinate to world coordinate
float p2w_y(int p_y){
float t = 1.0;
float b = -1.0;
float x_i = (2.0*((float)p_y - ((float)GH - 1.0)/2.0))/(float)GH;
return(((t-b)*(x_i - ((-t-b)/(t-b))))/2.0);
}
void draw_real(){
int i;
glClear(GL_COLOR_BUFFER_BIT);
// Draw the line segments
glColor3f(0.0, 0.0, 1.0);
if ( num_pts>1 ) {
glBegin( GL_LINES );
for ( i=0; i<num_pts; i++ ) {
glVertex2f(p2w_x(points[i].x), p2w_y(GH-1-points[i].y) );
}
glEnd();
}
glPointSize(4.0);
// Draw the interpolated points second.
glColor3f( 0.0f, 0.0f, 0.0f);
glBegin( GL_POINTS );
for ( int i=0; i<num_pts; i++ ) {
glVertex2f( p2w_x(points[i].x), p2w_y(GH-1-points[i].y) );
}
glEnd();
glFlush();
}
//draw scan converting lines
void draw_lines(){
int x1;
int y1;
int x2;
int y2;
int dy;
int dx;
float m;
float x;
float y;
float dr;
float dg;
float db;
float r1 = 2.0;
float r2 = 0.0;
float g1 = 0.0;
float g2 = 0.0;
float b1 = 0.0;
float b2 = 1.0;
float r = r1;
float g = g1;
float b = b1;
for(int i=0; i<3; i++){
x1 = scanLine[i].coord[0].x;
y1 = scanLine[i].coord[0].y;
x2 = scanLine[i].coord[1].x;
y2 = scanLine[i].coord[1].y;
x = x1;
y = y1;
dy = y2-y1;
dx = x2-x1;
m = (float)dy/dx;
dr = (r2-r1)/(x2-x1);
dg = (g2-g1)/(x2-x1);
db = (b2-b1)/(x2-x1);
glPointSize(2.0);
glColor3f(r, g, b);
glBegin(GL_POINTS);
//for near horizontal lines
if ( m >= -1 && m<=1 ) {
printf("x1:%d x2:%d", x1,x2);
printf("y1:%d y2:%d", y1,y2);
if(x1>=x2){ //supposed to work bc all mouse coords are same
y = y2;
for(int l = x2; l<=x1; l++) {
glVertex2f(p2w_x(l), p2w_y(GH-1-(int)(y)));
y = y + m;
r = r + dr;
g = g + dg;
b = b + db;
}
}
else{
for(int j = x1; j<=x2; j++) {
glVertex2f(p2w_x(j), p2w_y(GH-1-(int)(y)));
y = y + m;
r = r + dr;
g = g + dg;
b = b + db;
}
}
}
else{ //near vertical lines
if(y2>y1){ //for lines that look like this ==> \ or / with the end points at the bottom
float tmp = (float)(x2-x1)/(y2-y1);
x=x1;
for(int k = y1; k<=y2; k++){
glVertex2f(p2w_x(x), p2w_y(GH-1-(int)(k)));
x=x+tmp;
}
}
else{
float tmp = (float)(x2-x1)/(y2-y1);
x=x2;
for(int k = y2; k<=y1; k++){
glVertex2f(p2w_x(x), p2w_y(GH-1-(int)(k)));
x=x+tmp;
}
}
}
glEnd();
}
}
//the reshape callback
//this maintains the shape regardless of the window size
void reshape(int w, int h) {
GW = w;
GH = h;
glViewport(0, 0, w, h);
glLoadIdentity();
gluOrtho2D( -(float)w/h, (float)w/h, -1, 1);
}
//the display call back - all drawing should be done in this function
void display() {
glClear(GL_COLOR_BUFFER_BIT);
if(mode==0)
draw_real();
else if(mode==1)
draw_lines();
glFlush();
}
void mouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON) {
if (state == GLUT_DOWN ) { /* if the left button is clicked */
printf("mouse clicked at %d %d\n", x, y);
if (num_pts < 6 ) {
points[num_pts].x = x;
points[num_pts].y = y;
num_pts++;
if(num_pts%2 == 0){
scanLine[(num_pts/2)-1].coord[0].x = points[num_pts-2].x;
scanLine[(num_pts/2)-1].coord[0].y = points[num_pts-2].y;
scanLine[(num_pts/2)-1].coord[1].x = points[num_pts-1].x;
scanLine[(num_pts/2)-1].coord[1].y = points[num_pts-1].y;
}
glutPostRedisplay();
}
else{
int x0, x1, y0, y1;
x0 = scanLine[2].coord[0].x;
y0 = scanLine[2].coord[0].y;
x1 = scanLine[2].coord[1].x;
y1 = scanLine[2].coord[1].y;
if(((y0 - y1)*x + (x1-x0)*y + x0*y1 - x1*y0)<0){
printf("User clicked below last drawn line");
}
else
printf("User clicked above last drawn line");
} //end else
}
} //end outermost if
glutPostRedisplay();
}
//the mouse move callback
void mouseMove(int x, int y) {
printf("mouse moved at %d %d\n", x, y);
}
void keyboard(unsigned char key, int x, int y ){
switch( key ) {
case 'l':
mode = !mode;
glutPostRedisplay();
break;
case 'q':
exit( EXIT_SUCCESS );
}
}
int main( int argc, char** argv ){
glutInit( &argc, argv );
//intializations
glutInitWindowSize(200, 200);
glutInitWindowPosition(100, 100);
glutCreateWindow( "Lab 4" );
glClearColor(1.0, 1.0, 1.0, 1.0);
//global variable intialization
GW = GH = 200;
mode = 0; //real lines
num_pts = 0;
//register the callback functions
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
glutMouseFunc( mouse );
glutMotionFunc( mouseMove );
glutReshapeFunc( reshape );
glutMainLoop();
}
The problem is:
Notice how the color is jus a solid red (or sometimes blue) I'm supposed to add a different color to each endpoint of the line
and color the intermediary points (between the two endpoints)
using linear interpolation. I used an incremental algorithm, if you look for r, r0, r1, dr .. and so on (those lines of code has to do with the attempted coloring of the line), but not working..
also the reshape function decided not to work one day. I had it working and somehow modifying the lines of code NOT a part of the reshape function affected it somehow, if ne one can help me, please, thanks.
........
.....
//global variables - necessary evil when using GLUT
//global width and height
int GW;
int GH;
//current mouse position in pixel coordinate
int x;
int y;
//a structure to store 2D points - this could also be a class
typedef struct vector2 {
float x;
float y;
} vector2;
//an array to store ten 2D points
vector2 points[6];
typedef struct scans{
vector2 coord[2];
} scans;
scans scanLine[3];
//keep track of the number of points stored thus far
int num_pts;
int mode;
//converts x pixel coordinate to world coordinate
float p2w_x(int p_x){
float l = ((float)GW*(-1.0))/(float)GH;
float r = (float)GW/(float)GH;
float x_i = (2.0*((float)p_x - ((float)GW - 1.0)/2.0))/(float)GW;
return(((r-l)*(x_i - ((-r-l)/(r-l))))/2.0);
}
//converts y pixel coordinate to world coordinate
float p2w_y(int p_y){
float t = 1.0;
float b = -1.0;
float x_i = (2.0*((float)p_y - ((float)GH - 1.0)/2.0))/(float)GH;
return(((t-b)*(x_i - ((-t-b)/(t-b))))/2.0);
}
void draw_real(){
int i;
glClear(GL_COLOR_BUFFER_BIT);
// Draw the line segments
glColor3f(0.0, 0.0, 1.0);
if ( num_pts>1 ) {
glBegin( GL_LINES );
for ( i=0; i<num_pts; i++ ) {
glVertex2f(p2w_x(points[i].x), p2w_y(GH-1-points[i].y) );
}
glEnd();
}
glPointSize(4.0);
// Draw the interpolated points second.
glColor3f( 0.0f, 0.0f, 0.0f);
glBegin( GL_POINTS );
for ( int i=0; i<num_pts; i++ ) {
glVertex2f( p2w_x(points[i].x), p2w_y(GH-1-points[i].y) );
}
glEnd();
glFlush();
}
//draw scan converting lines
void draw_lines(){
int x1;
int y1;
int x2;
int y2;
int dy;
int dx;
float m;
float x;
float y;
float dr;
float dg;
float db;
float r1 = 2.0;
float r2 = 0.0;
float g1 = 0.0;
float g2 = 0.0;
float b1 = 0.0;
float b2 = 1.0;
float r = r1;
float g = g1;
float b = b1;
for(int i=0; i<3; i++){
x1 = scanLine[i].coord[0].x;
y1 = scanLine[i].coord[0].y;
x2 = scanLine[i].coord[1].x;
y2 = scanLine[i].coord[1].y;
x = x1;
y = y1;
dy = y2-y1;
dx = x2-x1;
m = (float)dy/dx;
dr = (r2-r1)/(x2-x1);
dg = (g2-g1)/(x2-x1);
db = (b2-b1)/(x2-x1);
glPointSize(2.0);
glColor3f(r, g, b);
glBegin(GL_POINTS);
//for near horizontal lines
if ( m >= -1 && m<=1 ) {
printf("x1:%d x2:%d", x1,x2);
printf("y1:%d y2:%d", y1,y2);
if(x1>=x2){ //supposed to work bc all mouse coords are same
y = y2;
for(int l = x2; l<=x1; l++) {
glVertex2f(p2w_x(l), p2w_y(GH-1-(int)(y)));
y = y + m;
r = r + dr;
g = g + dg;
b = b + db;
}
}
else{
for(int j = x1; j<=x2; j++) {
glVertex2f(p2w_x(j), p2w_y(GH-1-(int)(y)));
y = y + m;
r = r + dr;
g = g + dg;
b = b + db;
}
}
}
else{ //near vertical lines
if(y2>y1){ //for lines that look like this ==> \ or / with the end points at the bottom
float tmp = (float)(x2-x1)/(y2-y1);
x=x1;
for(int k = y1; k<=y2; k++){
glVertex2f(p2w_x(x), p2w_y(GH-1-(int)(k)));
x=x+tmp;
}
}
else{
float tmp = (float)(x2-x1)/(y2-y1);
x=x2;
for(int k = y2; k<=y1; k++){
glVertex2f(p2w_x(x), p2w_y(GH-1-(int)(k)));
x=x+tmp;
}
}
}
glEnd();
}
}
//the reshape callback
//this maintains the shape regardless of the window size
void reshape(int w, int h) {
GW = w;
GH = h;
glViewport(0, 0, w, h);
glLoadIdentity();
gluOrtho2D( -(float)w/h, (float)w/h, -1, 1);
}
//the display call back - all drawing should be done in this function
void display() {
glClear(GL_COLOR_BUFFER_BIT);
if(mode==0)
draw_real();
else if(mode==1)
draw_lines();
glFlush();
}
void mouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON) {
if (state == GLUT_DOWN ) { /* if the left button is clicked */
printf("mouse clicked at %d %d\n", x, y);
if (num_pts < 6 ) {
points[num_pts].x = x;
points[num_pts].y = y;
num_pts++;
if(num_pts%2 == 0){
scanLine[(num_pts/2)-1].coord[0].x = points[num_pts-2].x;
scanLine[(num_pts/2)-1].coord[0].y = points[num_pts-2].y;
scanLine[(num_pts/2)-1].coord[1].x = points[num_pts-1].x;
scanLine[(num_pts/2)-1].coord[1].y = points[num_pts-1].y;
}
glutPostRedisplay();
}
else{
int x0, x1, y0, y1;
x0 = scanLine[2].coord[0].x;
y0 = scanLine[2].coord[0].y;
x1 = scanLine[2].coord[1].x;
y1 = scanLine[2].coord[1].y;
if(((y0 - y1)*x + (x1-x0)*y + x0*y1 - x1*y0)<0){
printf("User clicked below last drawn line");
}
else
printf("User clicked above last drawn line");
} //end else
}
} //end outermost if
glutPostRedisplay();
}
//the mouse move callback
void mouseMove(int x, int y) {
printf("mouse moved at %d %d\n", x, y);
}
void keyboard(unsigned char key, int x, int y ){
switch( key ) {
case 'l':
mode = !mode;
glutPostRedisplay();
break;
case 'q':
exit( EXIT_SUCCESS );
}
}
int main( int argc, char** argv ){
glutInit( &argc, argv );
//intializations
glutInitWindowSize(200, 200);
glutInitWindowPosition(100, 100);
glutCreateWindow( "Lab 4" );
glClearColor(1.0, 1.0, 1.0, 1.0);
//global variable intialization
GW = GH = 200;
mode = 0; //real lines
num_pts = 0;
//register the callback functions
glutDisplayFunc( display );
glutKeyboardFunc( keyboard );
glutMouseFunc( mouse );
glutMotionFunc( mouseMove );
glutReshapeFunc( reshape );
glutMainLoop();
}