通过负数翻转没有比例的Opengl绘图

时间:2018-03-05 12:06:17

标签: c++ opengl graphics coordinate-transformation

我正在尝试绘制两个彼此面对的2D钻石。 所以我画了第一颗钻石然后在使用后画了第二颗钻石:

glTranslated(0, -150, 0);

所以它可以出现在我的第一颗钻石下面。 然而,我遇到了一个问题,我无法翻转第二颗钻石,所以它看起来像一面镜子。

以下是我要做的事情:

What i am trying to do

我在网上搜索解决方案,他们都提到我应该 使用

glScalef(1.0f,-1.0f,1.0f); 

但每次使用时图纸都会消失。

功能

glRotatef(angle,x,y,z); 

引起了我的注意,但我无法正确使用它导致错误的指示。

以下是我的图片在没有glRotate()的情况下的样子:

Without glRotate()

所以我认为我需要适当的技术来使用这些功能。

注意:我使用很多线环和顶点来绘制。

  #include <windows.h>  // For MS Windows
  #include <GL/glut.h>   // (or others, depending on the system in use)
  void init(void)
  {
     glClearColor(1.0, 1.0, 1.0, 0.0);  // Set display-window color to 
      white.
    glMatrixMode(GL_PROJECTION);       // Set projection parameters.
    gluOrtho2D(0.0, 400.0, 0.0, 400.0);
  }
  void drawDiamond()
     {
  glBegin(GL_LINE_LOOP);
  glVertex2f(125, 350);
  glVertex2f(245, 350);
  glVertex2f(290, 300);
  glVertex2f(182, 200);
  glVertex2f(75, 300);
  glEnd();


 glBegin(GL_LINE_LOOP);
 glVertex2f(109, 333);
 glVertex2f(138, 350);
 glVertex2f(159, 337);
 glVertex2f(123, 300);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(109, 333);
glVertex2f(123, 300);
glVertex2f(154, 225);
glVertex2f(92, 300);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(290, 300);
glVertex2f(75, 300);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(123, 300);
glVertex2f(159, 337);
glVertex2f(154, 300);
glVertex2f(171, 225);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(181, 300);
glVertex2f(159, 337);
glVertex2f(181, 350);
glVertex2f(209, 337);
glVertex2f(181, 300);
glVertex2f(171, 225);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(181, 300);
glVertex2f(209, 337);
glVertex2f(219, 300);
glVertex2f(195, 225);
glVertex2f(181, 300);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(209, 337);
glVertex2f(243, 300);
glVertex2f(195, 225);
glVertex2f(219, 300);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(209, 337);
glVertex2f(229, 350);
glVertex2f(260, 333);
glVertex2f(243, 300);
glVertex2f(209, 337);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(260, 333);
glVertex2f(278, 300);
glVertex2f(210, 225);
glVertex2f(243, 300);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(195, 225);
glVertex2f(182, 200);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(171, 225);
glVertex2f(182, 200);
glEnd();

}

void display()
{
glClear(GL_COLOR_BUFFER_BIT);  // Clear display window.
glColor3f(0.0, 0.0, 0.0);      // Set line segment color to blue.

                               // your code goes here
drawDiamond();
glTranslatef(0.0f, -150, 0.0f);
drawDiamond();
glFlush();     // Process all OpenGL routines as quickly as possible.

}
void main(int argc, char** argv)
{
glutInit(&argc, argv);                         // Initialize GLUT.
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);   // Set display mode.
glutInitWindowPosition(50, 100);   // Set top-left display-window 
position.
glutInitWindowSize(400, 400);      // Set display-window width and 
height. 
glutCreateWindow("Diamond Project"); // Create display window. 

init();                            // Execute initialization procedure. 
glutDisplayFunc(display);       // Send graphics to display window. 


glutMainLoop();                    // Display everything and wait.      

}

3 个答案:

答案 0 :(得分:1)

您要做的是围绕与X轴平行的轴镜像(翻转)对象,并穿过对象的底部边界(菱形)。

要执行此操作,必须找到底部Y坐标(bottomY),并且必须在相反方向上转换对象。注意模型坐标(顶点)的底部和视口上最终坐标的底部:

float bottomY = 200.0f;
glTranslatef( 0.0f, -bottomY , 0.0f );

接下来必须翻转对象。这可以通过

完成
glRotatef(180.0f, 1.0f, 0.0f, 0.0f);

glScalef(1.0f, -1.0f, 0.0f)

注意,两个操作都会产生相同的变换矩阵,因为 cos(90°)= cos(-90°) sin(90°)= -sin(90°)

然后必须颠倒bottomY翻译:

glTranslatef( 0.0f, bottomY, 0.0f );

但请注意,OpenGL固定功能管道堆栈的操作顺序相反,因为当前矩阵乘以新操作指定的矩阵。

翻译:请参阅glTranslate的文档:

  

glTranslatex y z生成翻译。当前矩阵(参见glMatrixMode)乘以此平移矩阵,产品替换当前矩阵。

轮换:请参阅glRotate的文档:

  

glRotate围绕向量x y z产生角度旋转。当前矩阵(参见glMatrixMode)乘以旋转矩阵,产品替换当前矩阵。

缩放:请参阅glScale的文档:

  

glScale会在xyz轴上产生不均匀的缩放。这三个参数表示沿三个轴中的每个轴的所需比例因子。   当前矩阵(参见glMatrixMode)乘以该比例矩阵。


这意味着以下内容应该符合您的要求:

float bottomY = 200.0f;

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

drawDiamond();

glTranslatef( 0.0f, bottomY , 0.0f );
glRotatef( 180.0f, 1.0f, 0.0f, 0.0f );
glTranslatef( 0.0f, -bottomY , 0.0f );

drawDiamond();

与以下内容相同:

glTranslatef( 0.0f, bottomY , 0.0f );
glScalef( 1.0f, -1.0f, 1.0f );
glTranslatef( 0.0f, -bottomY , 0.0f );  

答案 1 :(得分:0)

根据顶点的设置方式而定,并且根据您是否启用了背面剔除,您可能需要将钻石或(模型)中心点更改为底部尖端,然后您可以简单地旋转X轴表示您将其声明为水平轴。要做到这一点不应该那么难。它看起来像是:

glRotatef( 180.0f, 1, 0, 0 );

如果您以度数而不是弧度旋转。

答案 2 :(得分:0)

对于每个顶点(我假设您使用立即模式指定顶点),您可以glVertex2i(myVertex.x, symmetryLine - myVertex.y, 0)其中myVertex是您之前使用的x和y值,而symmetryLine是您希望镜像的值。最好的方法是使用负glScale。你的钻石是旋转对称的glRotate也可以,但你知道,这不是一种非常优雅的方式。