Hg200

Joined 29 March 2020
2,827 bytes added ,  2 January 2021
no edit summary
Tags: Mobile edit Mobile web edit Advanced mobile edit
No edit summary
Line 1: Line 1:
= Investigations on update_camera() =
= Investigations on update_camera() =


In the second part of <math display="inline">\rightarrow</math> axes::properties::update_camera () the view transformation "x_gl_mat1" and projection matrix "x_gl_mat2" are put together. The following images illustrate some of the properties of "x_gl_mat1".
In the second part of <math display="inline">\rightarrow</math> "axes::properties::update_camera ()" the view transformation "x_gl_mat1" and projection matrix "x_gl_mat2" are put together. The following images illustrate some of the properties of "x_gl_mat1" and "x_gl_mat2".


== The Octave coordinate system ==
== The Octave coordinate system ==
Line 8: Line 8:


[[File:Octave_view_point_setup_to_scale.png|center|750px]]
[[File:Octave_view_point_setup_to_scale.png|center|750px]]
== OpenGL coordinate systems ==
[[File:Octave_coordinate_systems.png|center|750px]]


== The role of "x_gl_mat1" ==
== The role of "x_gl_mat1" ==


The following section of code assembles the matrix "x_view", which is a subset of "x_gl_mat1". The matrix "x_gl_mat1" consists of multiple translations, scales and one rotation operation.
The following section of code composes the matrix "x_view", which is a subset of "x_gl_mat1". The matrix "x_gl_mat1" consists of multiple translations, scales and one rotation operation.


{{Code|Section of axes::properties::update_camera ()"|<syntaxhighlight lang="C" style="font-size:13px">
{{Code|Section of axes::properties::update_camera ()"|<syntaxhighlight lang="C" style="font-size:13px">
Line 57: Line 61:


[[File:Octave_x_gl_mat1_steps.png|center|1100px]]
[[File:Octave_x_gl_mat1_steps.png|center|1100px]]
== The role of "x_gl_mat2" ==
The matrix "x_gl_mat2" is composed of the sub matrices "x_viewport" and "x_projection". The purpose of these matrices is to fit the 2D image of the above transformation result into a "bounding box". The bounding box is defined as follows:
  bb(0), bb(1): Position of the "viewport"
  bb(2), bb(3): Width and height of the "viewport"
In the following simplified code section, the field of view (FOV) is determined such that the image is fitted into the bounding box of the window:
{{Code|Section of axes::properties::update_camera ()"|<syntaxhighlight lang="C" style="font-size:13px">
  if (cameraviewanglemode_is ("auto"))
    {
      if ((bb(2)/bb(3)) > (xM/yM))
        // When the image is scaled to the size of the bounding box,
        // the height collides with the bounding box first. Therefore,
        // the camera view angle is defined by the image height yM.
        af = 1.0 / yM;
      else
        // The image width collides with the bounding box.
        af = 1.0 / xM;
      // The view angle "v_angle", also called field of view "FOV",
      // is formed by the hypotenuse and the adjacent side, which is given by
      // the distance between the view point and the camera target "norm (F)".
      // The ratio of the opposite side, given by "af", to the adjacent side in
      // a right-angled triangle is the tangent of the view angle.
      v_angle = 2 * (180.0 / M_PI) * atan (1 / (2 * af * norm (F)));
      cameraviewangle = v_angle;
    }
  else
    v_angle = get_cameraviewangle ();
  // Calculate backwards from the angle to the ratio. This step
  // is necessary because "v_angle" can be set manually.
  double pf = 1 / (2 * tan ((v_angle / 2) * M_PI / 180.0) * norm (F));
  // Normalize to one. Resulting coordinates are "normalized device coordinates".
  scale (x_projection, pf, pf, 1);
</syntaxhighlight>}}
x_viewport is a 2D transformation used to place the "normalized" plot box in the center of the bounding box:
{{Code|Section of axes::properties::update_camera ()"|<syntaxhighlight lang="C" style="font-size:13px">
  double pix = 1;
  if (autocam)
    {
      if ((bb(2)/bb(3)) > (xM/yM))
        pix = bb(3);
      else
        pix = bb(2);
    }
  else
    pix = (bb(2) < bb(3) ? bb(2) : bb(3));
  // Move to the center of the bounding box inside the figure.
  translate (x_viewport, bb(0)+bb(2)/2, bb(1)+bb(3)/2, 0);
  // Scale either to width or height, to fit correctly into the bounding box
  scale (x_viewport, pix, -pix, 1);
  x_gl_mat2 = x_viewport * x_projection;
</syntaxhighlight>}}
Note: The projection and viewport matrix just scales x, y so that the image fits tightly into the bounding box. The z-coordinate is not modified!
20

edits