如何将 gl_lines 与贝塞尔曲线相结合?

Posted

技术标签:

【中文标题】如何将 gl_lines 与贝塞尔曲线相结合?【英文标题】:How to combine gl_lines with bezier? 【发布时间】:2014-04-22 14:38:45 【问题描述】:

我正在尝试将贝塞尔点与 gl_lines 结合起来创建一张脸。 当我尝试代码时,它显示的输出如下所示。 我尝试了两种方法,将贝塞尔代码放置在面多边形之后和面多边形之前。它给出了两个不同的答案。我正在尝试将嘴线画到脸上。

// COLORFACE.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include<windows.h>
#include<GL/glut.h> // GL means folder. glut.h is in folder GL.
#include<GL/gl.h> // used in system
#include<math.h>

//angle of rotation for the camera direction
//float angle = 0.0f;
//actual vector representing the camera's direction
//float lx=0.0f,ly=0.0,lz=-10.0f;
//XZ position of the camera
//float x=0.0f,y=1.0f, z=-10.0f;

        float angle = 0.0f;
        float lx=0.0f,ly=0.0,lz=1.0f;
        float x=0.0f,y=1.0f, z=5.0f;
        float deltaAngle = 0.0f;
        float deltaMove = 0;
        float deltaMoveLR = 0;
        float deltaZoom=0.0f;
        float shearx=0.0f;
        float sheary=0.0f;
        float scalex=0.0f;
        float scaley=0.0f;
      /*  float mmx =-80;
        float mmy =-40;
        float mmx1 =4;
        float mmy1 =3;*/

        float mmx =70;
        float mmy =100;
        float mmz = 1000;
        float mmx1 =4;
        float mmy1 =3;
        float mmz1 = 1;
        float upperlip=0.0f;
        float lowerlip=0.0f;
        float upperleftlip=0.0;
        float lowerleftlip=0.0f;
        float upperrightlip=0.0f;
        float lowerrightlip=0.0f;

        int w=640;
        int h=480;

 // Initial display-window size
        GLsizei winWidth =800, winHeight=4000;
        // Set coordinate limits for the clipping window
        GLfloat xwcMin = 10.0, xwcMax = 500.0;
        GLfloat ywcMin = 0.0, ywcMax = 500.0;
        GLfloat zwcMin = 0.0, zwcMax = 500.0;

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

void myInit(void)

glClearColor(1.0, 1.0, 1.0, 1.0); // set the background to white
//glColor3f(0.0, 0.0, 0.0); // set the drawing color to black
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,640.0,0.0,480.0);
// Set the correct perspective.
gluPerspective(0.0f, 0.0f, 0.0f, 0.0f);


  void plotPoint (wcPt3D bezCurvePt)
        
        glBegin (GL_POINTS); // Plot control points
        glVertex2f(bezCurvePt.x, bezCurvePt.y);
        glEnd(); // Done drawing the GL_POINTS
        

        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 u, 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 blen control points
        for (k=0; k<nCtrlPts; k++)
        
        bezBlendFcn = C[k] *pow(u,k) * pow (1-u,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 u;
        GLint *C, k;
        // Allocate space for binomial coefficients
        C=new GLint [nCtrlPts];
        binomialCoeffs (nCtrlPts - 1,C);
        for (k=0; k<=nBezCurvePts; k++)
        
        u=GLfloat (k) / GLfloat (nBezCurvePts);
        computeBezPt (u, &bezCurvePt, nCtrlPts, ctrlPts, C);
        plotPoint (bezCurvePt);
        
        delete [] C;
        

void hardwiredHouse()

GLint nCtrlPts27 = 3, nBezCurvePts = 10000;         //draw mouth line
        wcPt3D ctrlPts27 [3] =
        
        (-50+mmx)*mmx1+upperleftlip,(-75+mmy)*mmy1,10000,
        (0+mmx)*mmx1,(-75+mmy)*mmy1+upperlip,10000,        
        (50+mmx)*mmx1+upperrightlip,(-75+mmy)*mmy1,10000,
        ;

        GLint nCtrlPts28 = 3;       //draw lower lip 
        wcPt3D ctrlPts28 [3] =
        
        (-50+mmx)*mmx1+lowerleftlip,(-75+mmy)*mmy1,10000,
        (0+mmx)*mmx1,(-110+mmy)*mmy1+lowerlip,10000,        
        (50+mmx)*mmx1+lowerrightlip,(-75+mmy)*mmy1,10000
        ;      

        glClear (GL_COLOR_BUFFER_BIT); // Clear display window.
        glPointSize (4);
        glColor3f (0.0, 0.0, 0.0); // Set fill color = BLACK
        glRotatef(angle,0.0,0.0,1.0); // Create Rotation
        if(mmx1>0 && mmy1>0) // Limit Shear or Scale
        bezier (ctrlPts27, nCtrlPts27, nBezCurvePts);
        bezier (ctrlPts28, nCtrlPts28, nBezCurvePts);

//hair falling
glColor3ub(0,0,0);
glBegin(GL_POLYGON);
glVertex2i(300,131);
glVertex2i(321,113);
glVertex2i(352,108);
glVertex2i(380,108);
glVertex2i(412,118);
glVertex2i(441,142);
glVertex2i(458,180);
glVertex2i(458,215);
glVertex2i(457,243);
glVertex2i(449,284);
glVertex2i(447,306);
glVertex2i(443,334);
glVertex2i(441,388);
glVertex2i(422,422);
glVertex2i(392,449);
glVertex2i(352,463);
glVertex2i(320,472);
glVertex2i(268,483);
glVertex2i(250,484);
glVertex2i(224,484);
glVertex2i(155,474);
glVertex2i(112,454);
glVertex2i(77,417);
glVertex2i(73,404);
glVertex2i(66,362);
glVertex2i(45,299);
glVertex2i(35,266);
glVertex2i(32,231);
glVertex2i(27,198);
glVertex2i(35,164);
glVertex2i(57,132);
glVertex2i(81,115);
glVertex2i(101,106);
glVertex2i(126,103);
glVertex2i(148,107);
glVertex2i(169,113);
glVertex2i(186,126);
glVertex2i(189,132);
glEnd();

//face cutting
glColor3ub(210,137,0);
glBegin(GL_POLYGON);
glVertex2i(85,295);
glVertex2i(86,278);
glVertex2i(88,261);
glVertex2i(91,243);
glVertex2i(94,226);
glVertex2i(99,196);
glVertex2i(104,163);
glVertex2i(110,140);
glVertex2i(116,123);
glVertex2i(123,107);
glVertex2i(131,92);
glVertex2i(140,80);
glVertex2i(149,73);
glVertex2i(154,69);
glVertex2i(161,65);
glVertex2i(170,60);
glVertex2i(181,54);
glVertex2i(196,50);
glVertex2i(209,45);
glVertex2i(220,44);
glVertex2i(231,41);
glVertex2i(241,39);
glVertex2i(251,39);
glVertex2i(264,41);
glVertex2i(275,43);
glVertex2i(287,50);
glVertex2i(301,53);
glVertex2i(316,59);
glVertex2i(329,66);
glVertex2i(340,73);
glVertex2i(352,82);
glVertex2i(358,95);
glVertex2i(365,106);
glVertex2i(371,119);
glVertex2i(379,146);
glVertex2i(384,167);
glVertex2i(389,192);
glVertex2i(392,208);
glVertex2i(394,225);
glVertex2i(398,248);
glVertex2i(402,268);
glVertex2i(405,284);
glVertex2i(405,293);
glVertex2i(407,309);
glVertex2i(392,315);
glVertex2i(374,321);
glVertex2i(353,325);
glVertex2i(337,329);
glVertex2i(317,332);
glVertex2i(302,336);
glVertex2i(283,337);
glVertex2i(266,338);
glVertex2i(245,340);
glVertex2i(233,340);
glVertex2i(208,336);
glVertex2i(186,338);
glVertex2i(159,334);
glVertex2i(146,330);
glVertex2i(123,327);
glVertex2i(107,321);
glVertex2i(90,315);
glVertex2i(84,310);
glEnd();

//hair on face
glColor3ub(0,0,0);
glBegin(GL_POLYGON);
glVertex2i(90,342);
glVertex2i(87,336);
glVertex2i(84,323);
glVertex2i(83,305);
glVertex2i(83,276);
glVertex2i(107,270);
glVertex2i(108,250);
glVertex2i(133,251);
glVertex2i(137,273);
glVertex2i(161,273);
glVertex2i(163,251);
glVertex2i(183,255);
glVertex2i(199,261);
glVertex2i(212,272);
glVertex2i(226,278);
glVertex2i(236,287);
glVertex2i(242,293);
glVertex2i(263,278);
glVertex2i(275,270);
glVertex2i(295,262);
glVertex2i(315,254);
glVertex2i(322,251);
glVertex2i(323,271);
glVertex2i(351,269);
glVertex2i(351,249);
glVertex2i(376,249);
glVertex2i(378,270);
glVertex2i(411,268);
glVertex2i(413,286);
glVertex2i(415,304);
glVertex2i(413,321);
glVertex2i(398,336);
glVertex2i(355,348);
glVertex2i(305,366);
glVertex2i(266,370);
glVertex2i(234,373);
glVertex2i(193,375);
glVertex2i(154,369);
glVertex2i(117,354);
glVertex2i(94,338);
glVertex2i(90,334);
glEnd();

//hair
glColor3ub(0,0,0);
glBegin(GL_POLYGON);
glVertex2i(87,352);
glVertex2i(109,350);
glVertex2i(110,332);
glVertex2i(134,331);
glVertex2i(135,352);
glVertex2i(161,350);
glVertex2i(163,329);
glVertex2i(183,335);
glVertex2i(207,347);
glVertex2i(222,358);
glVertex2i(242,373);
glVertex2i(265,356);
glVertex2i(285,346);
glVertex2i(308,335);
glVertex2i(323,331);
glVertex2i(323,347);
glVertex2i(350,349);
glVertex2i(351,328);
glVertex2i(376,330);
glVertex2i(378,352);
glVertex2i(402,354);
glVertex2i(404,375);
glVertex2i(406,390);
glVertex2i(319,417);
glVertex2i(236,421);
glVertex2i(165,413);
glVertex2i(117,405);
glVertex2i(82,390);
glVertex2i(86,354);
glEnd();

//left eyebrow
glColor3ub(0,0,0);
glBegin(GL_LINE_STRIP);
glVertex2i(271,202);
glVertex2i(284,212);
glVertex2i(307,219);
glVertex2i(322,219);
glVertex2i(339,218);
glVertex2i(356,214);
glVertex2i(368,208);
glVertex2i(379,204);
glEnd();

//right eyebrow
glColor3ub(0,0,0);
glBegin(GL_LINE_STRIP);
glVertex2i(109,202);
glVertex2i(117,208);
glVertex2i(128,214);
glVertex2i(143,217);
glVertex2i(160,220);
glVertex2i(174,220);
glVertex2i(190,217);
glVertex2i(204,212);
glVertex2i(219,203);
glEnd();

//left eye
glColor3ub(255,255,255);
glBegin(GL_QUAD_STRIP);
glVertex2i(133,186);
glVertex2i(141,174);
glVertex2i(168,198);
glVertex2i(215,178);
glEnd();

//left eye lining
glColor3ub(0,0,0);
glBegin(GL_LINE_LOOP);
glVertex2i(133,186);
glVertex2i(141,174);
glVertex2i(215,178);
glVertex2i(168,198);
glEnd();

//right eye
glColor3ub(255,255,255);
glBegin(GL_QUAD_STRIP);
glVertex2i(360,186);
glVertex2i(352,174);
glVertex2i(325,198);
glVertex2i(278,178);
glEnd();

//right eye lining
glColor3ub(0,0,0);
glBegin(GL_LINE_LOOP);
glVertex2i(360,186);
glVertex2i(352,174);
glVertex2i(278,178);
glVertex2i(325,198);
glEnd();

    // right eye lens
    double radius=9.9; 
        glBegin(GL_POLYGON);
        glColor3f(0.0, 0.0, 0.0);
        for(float t=0; t<360; t++) 
        glVertex2f(325 + sin (t)*radius, (h-w/12.6*6+radius) + cos(t)*radius); //---500- x axis, 90 - y-axis
        
        glEnd();


    //left eye lens 

    double radius1=9.9; 
        glBegin(GL_POLYGON);
        glColor3f(0.0, 0.0, 0.0);
        for(float t=0; t<360; t++) 
        glVertex2f(168 + sin (t)*radius, (h-w/12.6*6+radius) + cos(t)*radius); //---500- x axis, 90 - y-axis
        
        glEnd();

//nose
glColor3ub(0,0,0);
glBegin(GL_LINE_STRIP);
glVertex2i(220,140);
glVertex2i(230,130);
glVertex2i(245,125);
glVertex2i(260,130);
glVertex2i(270,140);
glEnd();

////mouth
//glColor3ub(255,0,0);
//glBegin(GL_LINE_LOOP);
//glVertex2i(191,169);
//glVertex2i(292,169);
//glVertex2i(276,160);
//glVertex2i(245,153);
//glVertex2i(210,159);
//glVertex2i(189,170);
//glEnd();


  void winReshapeFcn (GLint newWidth, GLint newHeight)
        
        glViewport (0, 0, newHeight, newHeight); // Maintain an aspect ratio of 1.0
        glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();
        gluOrtho2D (xwcMin, xwcMax, ywcMin, ywcMax);
        glClear (GL_COLOR_BUFFER_BIT); // Clear display window
        

void myDisplay(void) //for screen display

glClear( GL_COLOR_BUFFER_BIT );
hardwiredHouse();
glFlush();


void main( int argc, char **argv)

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(640,480);
glutInitWindowPosition(100,100); // change posituon of window
glutCreateWindow("Chinese Girl");
glutDisplayFunc(myDisplay);
glutReshapeFunc (winReshapeFcn);
myInit();
glutMainLoop();

【问题讨论】:

【参考方案1】:

您的“两个不同的输出”图像丢失了,但可能是您在错误的位置插入了贝塞尔绘图代码;要么在绘制面部的大平面之前(因此它们被擦除),要么在它们得到错误颜色的时候(bezier 例程本身没有设置颜色,所以它使用之前设置的)。

您可以将它们放在//face cutting 段之后的任何位置。紧接在 //hair on face 行之前为我工作,尽管您需要在它之前插入一个额外的 glColor3ub(0,0,0); 以设置正确的颜色。


对您的代码的改进是这样的:而不是您自己的

void plotPoint (wcPt3D bezCurvePt)

    glBegin (GL_POINTS); // Plot control points
    glVertex2f(bezCurvePt.x, bezCurvePt.y);
    glEnd(); // Done drawing the GL_POINTS

考虑

void plotPoint (wcPt3D bezCurvePt)

    glVertex2f(bezCurvePt.x, bezCurvePt.y);

并在绘制nBezCurvePts 点的循环周围插入glBegin (GL_POINTS);glEnd();。 (另一种优化可能是使用GL_LINE_LOOPGL_LINE_LOOP,因此您可以计算出更少的贝塞尔点。)

【讨论】:

感谢您的帮助,先生。如果我将其更改为先生解释的方式,是否可以使唇线变形。最初我用贝塞尔线做了我的嘴唇变形。当我将线更改为点时,我无法进行嘴唇变形。 @user3557114:嘴巴是用points还是lines绘制的。对贝塞尔曲线进行动画处理是与绘制它不同的问题。这表明您的问题出在其他地方。 最初我只使用贝塞尔线做模型。考虑到使用贝塞尔线创建的模型不能完全着色,我想将模型更改为 gl_polygon。然而,我想保持贝塞尔曲线。所以我的目标是将嘴线带到脸上,而不是将其转换为 gl-Line 或 gl_polygon 并保持贝塞尔曲线。先生,这可能吗? 更改ctrlPts27ctrlPts28 中的坐标。 (说到这里,我不清楚你不清楚什么。这不是你自己的代码吗?)顺便说一句,当编码正确时,你可以填充由贝塞尔线组成的多边形。您的方法不起作用,因为您在贝塞尔代码内部开始和结束 GL 原语。 先生,我以前的型号是不同的。是的,这些是我自己的代码。我只使用贝塞尔线绘制。我现在将发布我的模型,包括贝塞尔曲线先生和标签先生的名字。请帮助先生。谢谢。

以上是关于如何将 gl_lines 与贝塞尔曲线相结合?的主要内容,如果未能解决你的问题,请参考以下文章

贝塞尔工具一半用来绘制啥及各种复杂的图形 ,他也可以绘制直线直线的方法与?

贝塞尔曲线原理

贝塞尔曲线~~~

用几何画板怎样制作贝塞尔曲线

如何计算三次贝塞尔曲线的长度

Android贝塞尔曲线的理解与应用