0

下面是到目前为止的代码,我的问题在于在窗口周围拖动图形?我好像做不到?对我有什么建议吗??我想要的是当您单击并按住鼠标左键时,您应该能够在窗口周围拖动图形?

#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#if !defined(GLUT_WHEEL_UP)
# define GLUT_WHEEL_UP

# define GLUT_WHEEL_DOWN 4
#endif


/*  Set initial size of the display window.  */
GLsizei winWidth = 600, winHeight = 600;  

/*  Set size of world-coordinate clipping window.  */
GLfloat xwcMin = -50.0, xwcMax = 50.0;
GLfloat ywcMin = -50.0, ywcMax = 50.0;
bool leftButton;
int downX, downY;

class wcPt3D {
    public:
      GLfloat x, y, z;
};

void init (void) {    
    /*  Set color of display window to white.  */
    glClearColor (1.0, 1.0, 1.0, 0.0);
}

void plotPoint (wcPt3D bezCurvePt) {
    glBegin (GL_POINTS);
    glVertex2f (bezCurvePt.x, bezCurvePt.y);
    glEnd ( );
}

/*  Compute binomial coefficients C for given value of n.  */
void binomialCoeffs (GLint n, GLint * C) {    
    GLint k, j;

    for (k = 0;  k <= n;  k++) {
      /*  Compute n!/(k!(n - k)!).  */
      C [k] = 1;
      for (j = n;  j >= k + 1;  j--)
        C [k] *= j;
      for (j = n - k;  j >= 2;  j--)
        C [k] /= j;
    }
}

void computeBezPt (GLfloat t, wcPt3D * bezPt, GLint nCtrlPts,
                    wcPt3D * ctrlPts, GLint * C) {
    GLint k, n = nCtrlPts - 1;
    GLfloat bezBlendFcn;

    bezPt->x = bezPt->y = bezPt->z = 0.0;

    /*  Compute blending functions and blend control points. */
    for (k = 0; k < nCtrlPts; k++) {
        bezBlendFcn = C [k] * pow (t, k) * pow (1 - t, n - k);
        bezPt->x += ctrlPts [k].x * bezBlendFcn;
        bezPt->y += ctrlPts [k].y * bezBlendFcn;
        bezPt->z += ctrlPts [k].z * bezBlendFcn;
    }
}

void bezier (wcPt3D * ctrlPts, GLint nCtrlPts, GLint nBezCurvePts) {
    wcPt3D bezCurvePt;
    GLfloat t;
    GLint *C;

    /*  Allocate space for binomial coefficients  */
    C = new GLint [nCtrlPts];

    binomialCoeffs (nCtrlPts - 1, C);
    for (int i = 0;  i <= nBezCurvePts;  i++) {
        t = GLfloat (i) / GLfloat (nBezCurvePts);
        computeBezPt (t, &bezCurvePt, nCtrlPts, ctrlPts, C);
        plotPoint (bezCurvePt);
    }
    delete [ ] C;
}

void displayFcn (void) {
    glClear (GL_COLOR_BUFFER_BIT);   //  Clear display window.

    /*  Set example number of control points and number of
     *  curve positions to be plotted along the Bezier curve.
     */    GLint nCtrlPts = 4, nBezCurvePts = 1000;

    wcPt3D ctrlPts [4] = { {-40.0, -40.0, 0.0}, {-10.0, 200.0, 0.0},
                           {10.0, -200.0, 0.0}, {40.0, 40.0, 0.0} };

    glPointSize (4);
    glColor3f (1.0, 0.0, 0.0);      //  Set point color to red.

     bezier (ctrlPts, nCtrlPts, nBezCurvePts);
     glutSwapBuffers();
}

void winReshapeFcn (GLint newWidth, GLint newHeight) {
    /*  Maintain an aspect ratio of 1.0.  */
    glViewport (0, 0, xwcMin, ywcMin);

    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ( );

    gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax);

    glutPostRedisplay();
}

void MouseCallback(int button, int state, int x, int y) {
    downX = x;
    downY = y;
    leftButton = ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN));
    glutPostRedisplay();
}

void MotionCallback(int x, int y) {
    if (leftButton){ 
        downX=downX+x;
        downY=downY+y;
        gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax);
    }

    downX = x;
    downY = y;
    glutPostRedisplay();
}
/*
   void MouseCallback(int button, int state, int x, int y) {
       if (button == GLUT_WHEEL_UP && glutGetModifiers()==GLUT_ACTIVE_CTRL) {
       }else if (button == GLUT_WHEEL_DOWN)
           glutPostRedisplay();
       }
*/

int main (int argc, char** argv) {
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowPosition (50, 50);
    glutInitWindowSize (winWidth, winHeight);
    glutCreateWindow ("Bezier Curve");

    init ( );
    glutDisplayFunc (displayFcn);
    glutReshapeFunc (winReshapeFcn);
    glutMouseFunc(MouseCallback);
    glutMotionFunc(MotionCallback);
    glutMainLoop ( );
}
4

1 回答 1

0

尝试这个:

#include <GL/glut.h>
#include <cmath>

// Compute binomial coefficients C for given value of n.  
void binomialCoeffs
    (
    GLint   n, 
    GLint*  C
    ) 
{    
    for (GLint k = 0;  k <= n;  k++)
    {
        // Compute n!/(k!(n - k)!).  
        C [k] = 1;
        for (GLint j = n;  j >= k + 1;  j--)
            C [k] *= j;
        for (GLint j = n - k;  j >= 2;  j--)
            C [k] /= j;
    }
}

struct wcPt3D 
{
    GLfloat x, y, z;
};

void computeBezPt
    (
    GLfloat t, 
    wcPt3D* bezPt, 
    GLint   nCtrlPts, 
    wcPt3D* ctrlPts, 
    GLint*  C
    ) 
{
    GLint n = nCtrlPts - 1;
    GLfloat bezBlendFcn;

    bezPt->x = bezPt->y = bezPt->z = 0.0;

    // Compute blending functions and blend control points. 
    for (GLint k = 0; k < nCtrlPts; k++) 
    {
        bezBlendFcn = C [k] * pow (t, k) * pow (1 - t, n - k);
        bezPt->x += ctrlPts [k].x * bezBlendFcn;
        bezPt->y += ctrlPts [k].y * bezBlendFcn;
        bezPt->z += ctrlPts [k].z * bezBlendFcn;
    }
}

void bezier
    (
    wcPt3D* ctrlPts, 
    GLint   nCtrlPts, 
    GLint   nBezCurvePts
    ) 
{
    // Allocate space for binomial coefficients  
    GLint* C = new GLint [nCtrlPts];

    binomialCoeffs (nCtrlPts - 1, C);
    glBegin (GL_POINTS);
    for (int i = 0;  i <= nBezCurvePts;  i++) 
    {
        GLfloat t = GLfloat (i) / GLfloat (nBezCurvePts);
        wcPt3D bezCurvePt;
        computeBezPt (t, &bezCurvePt, nCtrlPts, ctrlPts, C);
        glVertex2f (bezCurvePt.x, bezCurvePt.y);
    }
    glEnd();
    delete [ ] C;
}

int btn;
int startMouseX = 0;
int startMouseY = 0;
int startTransX = 0;
int startTransY = 0;
int curTransX = 0;
int curTransY = 0;
void MouseCallback(int button, int state, int x, int y) 
{
    btn = button;
    if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
    {
        startMouseX = x;
        startMouseY = glutGet( GLUT_WINDOW_HEIGHT ) - y;
        startTransX = curTransX;
        startTransY = curTransY;
    }
    glutPostRedisplay();
}

void MotionCallback(int x, int y) 
{
    int curMouseX = x;
    int curMouseY = glutGet( GLUT_WINDOW_HEIGHT ) - y;
    if ( btn == GLUT_LEFT_BUTTON )
    { 
        curTransX = startTransX + ( curMouseX - startMouseX );
        curTransY = startTransY + ( curMouseY - startMouseY );
    }

    glutPostRedisplay();
}

// Set size of world-coordinate clipping window.  
GLfloat xwcMin = -50.0, xwcMax = 50.0;
GLfloat ywcMin = -50.0, ywcMax = 50.0;
void displayFcn () 
{
    // Clear display window.
    glClearColor (1.0, 1.0, 1.0, 0.0);
    glClear (GL_COLOR_BUFFER_BIT);   

    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ( );
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    glTranslatef( curTransX / w * 2, curTransY / h * 2, 0 );
    gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax);

    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity();

    // Set example number of control points and number of
    // curve positions to be plotted along the Bezier curve.
    GLint nCtrlPts = 4, nBezCurvePts = 1000;
    wcPt3D ctrlPts [4] = 
    { 
        {-40.0, -40.0, 0.0}, 
        {-10.0, 200.0, 0.0},
        {10.0, -200.0, 0.0}, 
        {40.0, 40.0, 0.0} 
    };

    // Set point color to red.
    glPointSize (4);
    glColor3f (1.0, 0.0, 0.0);      

    bezier (ctrlPts, nCtrlPts, nBezCurvePts);
    glutSwapBuffers();
}

int main (int argc, char** argv) 
{
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowPosition (50, 50);
    glutInitWindowSize (600, 600);
    glutCreateWindow ("Bezier Curve");

    glutDisplayFunc (displayFcn);
    glutMouseFunc(MouseCallback);
    glutMotionFunc(MotionCallback);
    glutMainLoop ( );
}

改编自我在这里的回答。

编辑:最小(-ish)差异版本:

#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#if !defined(GLUT_WHEEL_UP)
# define GLUT_WHEEL_UP

# define GLUT_WHEEL_DOWN 4
#endif


/*  Set initial size of the display window.  */
GLsizei winWidth = 600, winHeight = 600;  

/*  Set size of world-coordinate clipping window.  */
GLfloat xwcMin = -50.0, xwcMax = 50.0;
GLfloat ywcMin = -50.0, ywcMax = 50.0;

class wcPt3D {
    public:
      GLfloat x, y, z;
};

void init (void) {    
    /*  Set color of display window to white.  */
    glClearColor (1.0, 1.0, 1.0, 0.0);
}

void plotPoint (wcPt3D bezCurvePt) {
    glBegin (GL_POINTS);
    glVertex2f (bezCurvePt.x, bezCurvePt.y);
    glEnd ( );
}

/*  Compute binomial coefficients C for given value of n.  */
void binomialCoeffs (GLint n, GLint * C) {    
    GLint k, j;

    for (k = 0;  k <= n;  k++) {
      /*  Compute n!/(k!(n - k)!).  */
      C [k] = 1;
      for (j = n;  j >= k + 1;  j--)
        C [k] *= j;
      for (j = n - k;  j >= 2;  j--)
        C [k] /= j;
    }
}

void computeBezPt (GLfloat t, wcPt3D * bezPt, GLint nCtrlPts,
                    wcPt3D * ctrlPts, GLint * C) {
    GLint k, n = nCtrlPts - 1;
    GLfloat bezBlendFcn;

    bezPt->x = bezPt->y = bezPt->z = 0.0;

    /*  Compute blending functions and blend control points. */
    for (k = 0; k < nCtrlPts; k++) {
        bezBlendFcn = C [k] * pow (t, k) * pow (1 - t, n - k);
        bezPt->x += ctrlPts [k].x * bezBlendFcn;
        bezPt->y += ctrlPts [k].y * bezBlendFcn;
        bezPt->z += ctrlPts [k].z * bezBlendFcn;
    }
}

void bezier (wcPt3D * ctrlPts, GLint nCtrlPts, GLint nBezCurvePts) {
    wcPt3D bezCurvePt;
    GLfloat t;
    GLint *C;

    /*  Allocate space for binomial coefficients  */
    C = new GLint [nCtrlPts];

    binomialCoeffs (nCtrlPts - 1, C);
    for (int i = 0;  i <= nBezCurvePts;  i++) {
        t = GLfloat (i) / GLfloat (nBezCurvePts);
        computeBezPt (t, &bezCurvePt, nCtrlPts, ctrlPts, C);
        plotPoint (bezCurvePt);
    }
    delete [ ] C;
}

int curTransX = 0;
int curTransY = 0;
void displayFcn (void) {
    glClear (GL_COLOR_BUFFER_BIT);   //  Clear display window.

    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ( );
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    glTranslatef( curTransX / w * 2, curTransY / h * 2, 0 );
    gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax);

    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity();

    /*  Set example number of control points and number of
     *  curve positions to be plotted along the Bezier curve.
     */    GLint nCtrlPts = 4, nBezCurvePts = 1000;

    wcPt3D ctrlPts [4] = { {-40.0, -40.0, 0.0}, {-10.0, 200.0, 0.0},
                           {10.0, -200.0, 0.0}, {40.0, 40.0, 0.0} };

    glPointSize (4);
    glColor3f (1.0, 0.0, 0.0);      //  Set point color to red.

     bezier (ctrlPts, nCtrlPts, nBezCurvePts);
     glutSwapBuffers();
}

int btn;
int startMouseX = 0;
int startMouseY = 0;
int startTransX = 0;
int startTransY = 0;
void MouseCallback(int button, int state, int x, int y) {
    btn = button;
    if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
    {
        startMouseX = x;
        startMouseY = glutGet( GLUT_WINDOW_HEIGHT ) - y;
        startTransX = curTransX;
        startTransY = curTransY;
    }
    glutPostRedisplay();
}

void MotionCallback(int x, int y) {
    int curMouseX = x;
    int curMouseY = glutGet( GLUT_WINDOW_HEIGHT ) - y;
    if ( btn == GLUT_LEFT_BUTTON )
    { 
        curTransX = startTransX + ( curMouseX - startMouseX );
        curTransY = startTransY + ( curMouseY - startMouseY );
    }
    glutPostRedisplay();
}
/*
   void MouseCallback(int button, int state, int x, int y) {
       if (button == GLUT_WHEEL_UP && glutGetModifiers()==GLUT_ACTIVE_CTRL) {
       }else if (button == GLUT_WHEEL_DOWN)
           glutPostRedisplay();
       }
*/

int main (int argc, char** argv) {
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowPosition (50, 50);
    glutInitWindowSize (winWidth, winHeight);
    glutCreateWindow ("Bezier Curve");

    init ( );
    glutDisplayFunc (displayFcn);
    glutMouseFunc(MouseCallback);
    glutMotionFunc(MotionCallback);
    glutMainLoop ( );
}
于 2013-03-14T18:08:56.100 回答