20
edits
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 | 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! |
edits