4

I implemented the following code:

void TestGlPlot::resizeGL(int width, int height) 
{
   setupViewport(width, height);
}

void TestGlPlot::setupViewport(int width, int height)
{
   /* Prevent divide by zero --------------------------------------------------------------------*/
   if (height == 0) height = 1;
   /* Calculate aspect ratio --------------------------------------------------------------------*/
   float aspectRatio = (float)width / (float)height;

   /* Set viewport to cover the window ----------------------------------------------------------*/
   glViewport(0, 0, width, height);

   /* Set aspect ratio --------------------------------------------------------------------------*/
   glMatrixMode(GL_PROJECTION); /* switch to projection matrix */
   glLoadIdentity();
   /*
   if (width >= height)
   {
   gluOrtho2D(-0.5*aspectRatio, 0.5*aspectRatio, 0.0, 1.0);
   }
   else
   {
   gluOrtho2D(-0.5, 0.5, 0.0*aspectRatio, 1.0*aspectRatio);
   }
   glMatrixMode(GL_MODELVIEW);
   */
   gluOrtho2D(-1, 1, 0.0, 1.0);
   glMatrixMode(GL_MODELVIEW);
}

void TestGlPlot::paintEvent(QPaintEvent *event) {
   makeCurrent();
   setupViewport(width(), height());

   glMatrixMode(GL_MODELVIEW);

   /* Set white background ----------------------------------------------------------------------*/
   glClear(GL_COLOR_BUFFER_BIT);
   glClearColor(255,255,255,0);

   /* Paint OpenGL events -----------------------------------------------------------------------*/
   glColor4f(1.0, 0.0, 0.0, 1.0);

   /* light grey */
   glColor4f(0.0, 0.0, 0.0, 0.3); 
   gluPartialDisk(plainQuad, 0.1, 1, 20, 4, -60, 120);

   /* Paint QPainter events ---------------------------------------------------------------------*/
   QPainter painter(this);

   /* Draw grey border around plot --------------------------------------------------------------*/
   painter.setPen(QColor("#808080"));
   painter.drawRect(0, 0, width()-1, height()-1);

   painter.setFont(font);

   /* Translate coordinate system to (0,0) center -----------------------------------------------*/
   QMatrix m;
   m.translate(width()*0.5, height()*0.5);   
   painter.setMatrix(m);

   /* Left side descriptions for radius ---------------------------------------------------------*/
   painter.drawText(-0.17*width(), 0.38*height(), tr("100m"));
   painter.drawText(-0.27*width(), 0.28*height(), tr("200m"));
   painter.drawText(-0.37*width(), 0.18*height(), tr("300m"));
   painter.drawText(-0.47*width(), 0.08*height(), tr("400m"));

   painter.drawText(0.45*width(), -0.01*height(), tr("60°"));
   painter.drawText(0.26*width(), -0.38*height(), tr("30°"));

   painter.drawText(-0.47*width(), -0.01*height(), tr("300°"));
   painter.drawText(-0.28*width(), -0.38*height(), tr("330°"));

   painter.end();
}

i tried different methods for resize handling (keeping the shape of the partialDisk object without stretching it) but every method failed. I also want to keep the coordinate handling of the unit-circle (so i can normalize my measurements and draw them into a polar-plot).

genpfault
  • 51,148
  • 11
  • 85
  • 139
omgodie
  • 209
  • 1
  • 2
  • 13

1 Answers1

2

To keep the aspect ratio, you have several options in general:

  1. Always scale to one dimension. For example, you just define that you want always see the horizontal range [-0.5,0.5]. In this case, you have to correct the vertical range by the factor (1/aspect_viewport).
  2. Use some equivalent of letterboxing. So you define a "region of interest" which you always want to see completely, but you might see more in width or height, depending on the window aspect (that would be basically equivalent to the black bars when watching letterboxed movies). There are two cases to consider: the aspect of the viewport is greater than the aspect of your region, so it is wider. In that case, you should map the full height and increase the horitonal range by a factor of (aspect_viewport/aspect_region). Otherwise, the aspect of the window is lower than aspect of your region, so you should use the full width and scale up the vertical range by (aspect_region/aspect_viewport). Note that in both cases, the factor is >= 1.

In your code, you almost have implemented method 2, but you got the aspectRatio < 1 case wrong, it should be

   if (width >= height)
           gluOrtho2D(-0.5f*aspectRatio, 0.5f*aspectRatio, 0.0f, 1.0f); 
   else 
           gluOrtho2D(-0.5f, 0.5f, 0.0, 1.0/aspectRatio);
derhass
  • 43,833
  • 2
  • 57
  • 78
  • Thanks for your help. The rendered image now doesn't stretch on resize but its clinched without resizing. I think i have to adapt the ratios of plainQuad for gluPartialDisk(plainQuad, 0.1, 1, 20, 4, -60, 120); – omgodie May 11 '13 at 16:20
  • Also if i just use your suggested changes with dividing through the aspectRatio, the rendered partial disk extends over the clipping (which is logical, as the outer radius 1.0f and the clipping area stops at 0.5f) – omgodie May 11 '13 at 16:28
  • i also want to mention that when i choose: gluOrtho2D(-1.0f*aspectRatio, 1.0f*aspectRatio, 1.0f, 1.0f); everything is working fine, but the image is smaller and i just want to see the top part of my window and it should adjust the size accordingly (with top part i mean everything on x from -1.0 to +1.0, y from 0.0 to +1.0) – omgodie May 11 '13 at 16:48