我的图纸有坐标/ glortho 问题

Posted

技术标签:

【中文标题】我的图纸有坐标/ glortho 问题【英文标题】:having coordinates/ glortho issues with my drawings 【发布时间】:2020-11-30 18:22:27 【问题描述】:

在过去的几个小时里,我对我的代码做了一些改动,因为我的网格很乱,所以我把它变成了一个空白,我确保我得到了我首先被绘制出来的边界现在放置在我想要的位置,但是我的网格现在位于下图中显示的错误位置

我认为这是一个 glortho 问题,但我不知道输入什么代码会改变我想要放置我的绘图的位置。

#include "include\freeglut.h"   // OpenGL toolkit - in the local shared folder
#include <iostream>

using namespace std;

#define X_CENTRE 0.0            /* 0,0 */
#define Y_CENTRE 0.0

#define LENGTH   20.0 

GLboolean grid = false;

int w;
int h;


/* reshape callback function executed when window is moved or resized */
void reshape(int width, int height)

h = width;
w = height;
//set the matrix mode to PROJECTION
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
// use orthographic (parallel) projection
glOrtho(-200.0, 200.0, -200.0, 200.0, -200.0, 200.0);
//set the matrix mode to MODEL
glMatrixMode(GL_MODELVIEW);



void drawGrid() 
GLint i;

glEnable(GL_LINE_STIPPLE); //Activates the line-style feature

glLineStipple(1, 0xAAAA);  // Plots a dashed polyline

glColor3f(0.8, 0.8, 0.8);

if (grid) 
    glBegin(GL_LINES);
    for (i = 2; i <= 9; i++)
    
        glVertex3f(i * 0.1 * w, 0.0, 0.0);
        glVertex3f(i * 0.1 * w, 0.9 * h, 0.0);
    

    for (i = 1; i <= 9; i++)
    
        glVertex3f(0.1 * w, i * 0.1 * h, 0.0);
        glVertex3f(w, i * 0.1 * h, 0.0);
    
    glEnd();
    glDisable(GL_LINE_STIPPLE);




void drawBoundary(float length, float x, float y)


glBegin(GL_LINE_LOOP);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(X_CENTRE - length - 20, Y_CENTRE - length);   //these 4 points 
draw the game boundary
glVertex2f(X_CENTRE - length - 20, Y_CENTRE + length);   //these 4 points 
draw the game boundary
glVertex2f(X_CENTRE + length + 20, Y_CENTRE + length);   //these 4 points 
draw the game boundary
glVertex2f(X_CENTRE + length + 20, Y_CENTRE - length);   //these 4 points 
draw the game boundary
glEnd();

glFlush();     /* execute drawing commands in buffer */

   

/*     



    /* display callback function called whenever contents of window need 
to be re-displayed     */
void display(void)

glClear(GL_COLOR_BUFFER_BIT);   /* clear window */
glLoadIdentity();

drawGrid();

drawBoundary(170, 0, 0);

glutSwapBuffers();





GLvoid IdleFunc(GLvoid)

glutPostRedisplay();


void myGridmenu(GLint id)

if (id == 1)

    grid = 1.0;

else

    grid = 0.0;

glutPostRedisplay();


/* graphics initialisation */
void init(void)

glClearColor(0.0, 0.0, 0.0, 0.0);   /* window will be cleared to black */



int main(int argc, char* argv[])//standard c entry signature

/* window management code ... */
/* initialises GLUT and processes any command line arguments */
glutInit(&argc, argv);
/* use double-buffered window and RGBA colour model */
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
/* window width = 400 pixels, height = 400 pixels */
glutInitWindowSize(500, 500);
/* window upper left corner at (100, 100) */
glutInitWindowPosition(100, 100);
/* creates an OpenGL window and set its title bar*/
glutCreateWindow("Coursework 1");
init();

glutDisplayFunc(display);

//glutSpecialFunc(specialKeys);
//  glutSpecialUpFunc(keyGoneUp);

glutReshapeFunc(reshape);

//Create a grid that the user can turn on and off
glutCreateMenu(myGridmenu);

glutAddMenuEntry("Grid on", 1);
glutAddMenuEntry("Grid off", 2);
glutAttachMenu(GLUT_RIGHT_BUTTON);


//  SetupRC();
glutIdleFunc(IdleFunc);
glutMainLoop();

return 0;


【问题讨论】:

【参考方案1】:

wh 取决于正交投影而不是视口。由于投影不是从 (0, 0) 开始,而是从 (-200, -200) 开始,因此您必须添加 2 个附加变量startXstartY

int w = 1;
int h = 1;
int startX = 0;
int startY = 0;


/* reshape callback function executed when window is moved or resized */
void reshape(int width, int height)

    startX = -200;
    startY = -200;
    h = 400;
    w = 400;
    //set the matrix mode to PROJECTION
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0, 0, width, height);
    // use orthographic (parallel) projection
    glOrtho(-200.0, 200.0, -200.0, 200.0, -200.0, 200.0);
    //set the matrix mode to MODEL
    glMatrixMode(GL_MODELVIEW);

void drawGrid() 
    GLint i;

    glEnable(GL_LINE_STIPPLE); //Activates the line-style feature
    glLineStipple(1, 0xAAAA);  // Plots a dashed polyline

    glColor3f(0.8, 0.8, 0.8);

    if (grid) 
        glBegin(GL_LINES);
        for (i = 1; i <= 9; i++)
        
            glVertex3f(startX + i * 0.1 * w, startY, 0.0);
            glVertex3f(startX + i * 0.1 * w, h - startY, 0.0);
        

        for (i = 1; i <= 9; i++)
        
            glVertex3f(startX, startY + i * 0.1 * h, 0.0);
            glVertex3f(w - startX, startY + i * 0.1 * h, 0.0);
        
        glEnd();
        glDisable(GL_LINE_STIPPLE);
    

【讨论】:

非常感谢,非常感谢【参考方案2】:

去掉 void drawBoundary(...) 中的 20 并使用 drawBounndary(w/2, 0, 0) 调用。

我还怀疑你真的希望 (X_CENTRE, Y_CENTRE) 有 (x,y)?!

void display(void)

    glClear(GL_COLOR_BUFFER_BIT);   /* clear window */
    //glColor3f(red, green, blue);        /* white drawing objects */
    glColor3f(0.8, 0.8, 0.8);

    GLint i;

    glEnable(GL_LINE_STIPPLE); //Activates the line-style feature

    glLineStipple(1, 0xAAAA);  // Plots a dashed polyline

    if (grid) 
        glBegin(GL_LINES);
        for (i = 1; i <= 9; i++)
        
            glVertex3f((i * 0.1 - 0.5 ) * w , 0.0, 0.0);
            glVertex3f((i * 0.1 - 0.5 ) * w, 0.9 * h, 0.0);
        

        for (i = 1; i <= 9; i++)
        
            glVertex3f(0.1 * w, (i * 0.1 - 0.5 ) * h, 0.0);
            glVertex3f(w, (i * 0.1 - 0.5 )* h, 0.0);
        
        glEnd();
        glDisable(GL_LINE_STIPPLE);
    

    drawBoundary(w/2, 0, 0);

    glFlush();     /* execute drawing commands in buffer */

【讨论】:

我对我的代码做了一些改动,我将再次编辑这个问题 对不起,如果我不清楚,请检查已编辑的问题。【参考方案3】:

这里的问题是您计算边界位置的方式与计算网格位置的方式完全不同,例如:

边界的最左边点似乎计算为:

X_CENTRE - length - 20

等于0 - 170 - 20 或-190

但网格中水平线最左边的位置计算为:

0.1 * w

等于0.1 * 500 或 50

当你对这些点使用如此截然不同的方程时,你永远不会让它们排成一行。

编辑:回答评论:

从边界开始,您需要先使用上面的首选方程计算左下角的 x 坐标:

x = //your preferred equation here

然后使用上面首选方程的 y 等效项对左下角的 y 坐标执行相同的操作。您需要的信息在您已经发布的代码中,因此您可以自行解决。

y = //your preferred equation here

接下来计算出边界右上角的 x 和 y 坐标

x2 = x + ?? //你需要在这里做些什么改变? y2 = y + ?? //你需要在这里做些什么改变?

同样,此信息包含在您已经发布的代码中,因此您可以自己弄清楚。

现在您可以使用以下对确定需要将哪些值传递给 glVertex2f:

(x, y) //bottom left (x, y2) //top left (x2, y2) //top right (x2, y) //bottom right

这是使用任一方程绘制边界所需的全部知识。

对于网格的水平线,您将使用与计算边界相同的 x 和 x2,但 y 在循环的每次迭代中都会发生变化,因此您需要表格中的方程

yi = y + (i * ??? /* what goes here */)

那么对于网格的垂直线 y 和 y2 将与边界相同,并且 x 以如下形式改变循环的每次迭代:

xi = x + (i * ??? /* what goes here */)

然后绘制线条只是将以下对传递给glVertex2f:

(x, yi) //left of line (x2, yi) //right of line

(xi, y) //bottom of line (xi, y2) //top of line

重要的是您要与计算边界和网格的 x 和 y 的方式保持一致,并且您需要执行此操作的所有信息都已在您发布的代码中提供。

【讨论】:

所以它们必须相同?我该怎么做呢

以上是关于我的图纸有坐标/ glortho 问题的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL glOrtho 设置匹配窗口大小

OpenGL 中的可视化问题(glOrtho 和投影)

我的 glOrtho 怎么了?负零而不是零

opengl 高级技巧

怎么在CAD中给图纸设置地理坐标

帮助使用 GLOrtho