4

次のコードを実装しました。

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();
}

サイズ変更処理 (partialDisk オブジェクトの形状を引き伸ばさずに維持する) にさまざまな方法を試しましたが、すべての方法が失敗しました。また、単位円の座標処理を維持したい (測定値を正規化し、極座標プロットに描画できるようにするため)。

4

1 に答える 1

2

縦横比を維持するには、一般的にいくつかのオプションがあります。

  1. 常に 1 次元にスケーリングします。たとえば、水平範囲 [-0.5,0.5] を常に表示するように定義します。この場合、係数 (1/aspect_viewport) で垂直方向の範囲を修正する必要があります。
  2. レターボックスに相当するものを使用します。したがって、常に完全に表示したい「関心領域」を定義しますが、ウィンドウのアスペクトによっては、幅または高さがより多く表示される場合があります (これは基本的に、レターボックス映画を見るときの黒いバーに相当します)。考慮すべき 2 つのケースがあります。ビューポートの縦横比が領域の縦横比よりも大きいため、領域が広くなります。その場合、高さ全体をマッピングし、水平方向の範囲を (aspect_viewport/aspect_region) 倍に拡大する必要があります。それ以外の場合、ウィンドウの縦横比は領域の縦横比よりも低いため、全幅を使用して縦方向の範囲を (aspect_region/aspect_viewport) だけ拡大する必要があります。どちらの場合も、係数は >= 1 であることに注意してください。

あなたのコードでは、メソッド 2 をほぼ実装していますが、aspectRatio < 1 のケースが間違っています。

   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);
于 2013-05-11T16:07:59.723 に答える