Tweak Vector math page (style, links, more notes)

Also cleanup style issues in the docs image guidelines.
This commit is contained in:
Rémi Verschelde
2023-05-18 16:43:35 +02:00
parent 5a0916e5ac
commit c0761647f4
4 changed files with 76 additions and 55 deletions

View File

@@ -1,6 +1,6 @@
.. _docs_image_guidelines:
Creating Documentation Images
Creating documentation images
=============================
Throughout documentation images are often needed to make the explanation
@@ -36,10 +36,10 @@ on how to do this later on this page.
Format conversion
-----------------
The current format for images in Godot's documentation is WebP (.webp). While some
Linux programs will support saving screenshots in this format, macOS and the
Snip & Sketch program on Windows do not. For images that don't need editing,
such as precise cropping or adding outlines, Squoosh can be used.
The current format for images in Godot's documentation is WebP (``.webp``).
While some Linux programs will support saving screenshots in this format, macOS
and the Snip & Sketch program on Windows do not. For images that don't need
editing, such as precise cropping or adding outlines, Squoosh can be used.
`Squoosh <https://squoosh.app/>`_ is a converter developed by Google, is open
source, and doesn't give Google any image rights by using it.
@@ -87,9 +87,9 @@ Scaling down an image
As explained earlier on this page, all images taken on a screen that is a higher resolution
than 1080p should be scaled down. To do this in Krita click on **Image** on the top bar, and
from the dropdown menu select **Scale Image To New Size**. This menu can also be opened by
pressing :kbd: `ctrl + alt + I`. On this menu you want to adjust the pixel dimensions. For
pressing :kbd:`Ctrl + Alt + I`. On this menu you want to adjust the pixel dimensions. For
anything taken on a 4K monitor change the value of the width and height to half of its current
value, for anything taken on a 1440p monitor multiply the width and height by .75. Make
value, for anything taken on a 1440p monitor multiply the width and height by 0.75. Make
sure the **Constrain Proportions** box at the bottom of the menu is checked so you only have
to change 1 value.
@@ -107,14 +107,14 @@ Outlines arrows and text
Sometimes an image needs something extra to properly direct the readers
attention, or make something clear. Outlines and arrows can be used
for this purpose. For these types of edits Inkscape is the recommended open
source program, it can be downloaded from the `official Inkscape website <https://inkscape.org/release/inkscape-1.2.1/>`_.
Like Krita, if you're on linux you can also check your distributions repository
source program, it can be downloaded from the `official Inkscape website <https://inkscape.org/>`_.
Like Krita, if you're on Linux you can also check your distributions repository
or get it from Flathub.
A full tutorial on creating outlines is not provided here, we recommend searching
for various tutorials on how to use it online. However there are two standards
for doc image outlines and arrows. First, the color should be yellow, specifically
this hex color: fffb44 (fffb44ff if there is a transparency value like in inkscape).
this hex color: ``fffb44`` (``fffb44ff`` if there is a transparency value like in Inkscape).
This color was chosen specifically to make sure color blind people do not have
issues reading the documentation, other colors can be used in addition to this yellow
if multiple outlines on an image are needed, red should be avoided. The second standard
@@ -129,8 +129,15 @@ multiple outlines in multiple colors.
Adding an image to a documentation page
---------------------------------------
Once you've finished working on your image it can be added to the documentation.
All images are stored in folders named `img`. To add your image add it to the img
folder that's in the same folder as the rst file for the page. To add it in the
text yourself you would type this `.. image:: img/documentation_image.webp` and
`documentation_image.webp` would be whatever your image is named.
Once you've finished working on your image, it can be added to the documentation.
All images are stored in folders named ``img`` next to the page they are used in.
To add your image, add it to the ``img`` folder that's in the same folder as the
``.rst`` file for the page (create it if it doesn't exist). In the ``.rst`` page,
images should be included with the following code snippet::
.. image:: img/documentation_image.webp
Where ``documentation_image.webp`` would be changed to the name of the image you
created. Name your images in a way that makes their meaning clear, possibly with
a prefix that makes their relationship to a documentation page explicit.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -40,8 +40,9 @@ point:
This is a **vector**. A vector represents a lot of useful information. As well
as telling us that the point is at ``(4, 3)``, we can also think of it as an
angle ``θ`` and a length (or magnitude) ``m``. In this case, the arrow is a
**position vector** - it denotes a position in space, relative to the origin.
angle ``θ`` (theta) and a length (or magnitude) ``m``. In this case, the arrow
is a **position vector** - it denotes a position in space, relative to the
origin.
A very important point to consider about vectors is that they only represent
**relative** direction and magnitude. There is no concept of a vector's
@@ -74,7 +75,9 @@ pixels down, use the following code:
Godot supports both :ref:`Vector2 <class_Vector2>` and :ref:`Vector3
<class_Vector3>` for 2D and 3D usage, respectively. The same mathematical rules
discussed in this article apply to both types.
discussed in this article apply to both types, and wherever we link to
``Vector2`` methods in the class reference, you can also check out their
``Vector3`` counterparts.
Member access
-------------
@@ -84,18 +87,18 @@ The individual components of the vector can be accessed directly by name.
.. tabs::
.. code-tab:: gdscript GDScript
# create a vector with coordinates (2, 5)
# Create a vector with coordinates (2, 5).
var a = Vector2(2, 5)
# create a vector and assign x and y manually
# Create a vector and assign x and y manually.
var b = Vector2()
b.x = 3
b.y = 1
.. code-tab:: csharp
// create a vector with coordinates (2, 5)
// Create a vector with coordinates (2, 5).
var a = new Vector2(2, 5);
// create a vector and assign x and y manually
// Create a vector and assign x and y manually.
var b = new Vector2();
b.X = 3;
b.Y = 1;
@@ -125,7 +128,8 @@ Scalar multiplication
---------------------
.. note:: Vectors represent both direction and magnitude. A value representing
only magnitude is called a **scalar**.
only magnitude is called a **scalar**. Scalars use the
:ref:`class_float` type in Godot.
A vector can be multiplied by a **scalar**:
@@ -155,14 +159,21 @@ Movement
A vector can represent **any** quantity with a magnitude and direction. Typical
examples are: position, velocity, acceleration, and force. In this image, the
spaceship at step 1 has a position vector of ``(1,3)`` and a velocity vector of
``(2,1)``. The velocity vector represents how far the ship moves each step. We
spaceship at step 1 has a position vector of ``(1, 3)`` and a velocity vector of
``(2, 1)``. The velocity vector represents how far the ship moves each step. We
can find the position for step 2 by adding the velocity to the current position.
.. image:: img/vector_movement1.png
.. tip:: Velocity measures the **change** in position per unit of time. The new
position is found by adding velocity to the previous position.
position is found by adding the velocity multiplied by the elapsed time
(here assumed to be one unit, e.g. 1 s) to the previous position.
In a typical 2D game scenario, you would have a velocity in pixels per
second, and multiply it by the ``delta`` parameter (time elapsed since
the previous frame) from the :ref:`_process() <class_Node_method__process>`
or :ref:`_physics_process() <class_Node_method__physics_process>`
callbacks.
Pointing toward a target
------------------------
@@ -171,9 +182,9 @@ In this scenario, you have a tank that wishes to point its turret at a robot.
Subtracting the tank's position from the robot's position gives the vector
pointing from the tank to the robot.
.. image:: img/vector_subtract2.png
.. image:: img/vector_subtract2.webp
.. tip:: To find a vector pointing from ``A`` to ``B`` use ``B - A``.
.. tip:: To find a vector pointing from ``A`` to ``B``, use ``B - A``.
Unit vectors
~~~~~~~~~~~~
@@ -187,8 +198,8 @@ Normalization
**Normalizing** a vector means reducing its length to ``1`` while preserving its
direction. This is done by dividing each of its components by its magnitude.
Because this is such a common operation, ``Vector2`` and ``Vector3`` provide a
method for normalizing:
Because this is such a common operation, Godot provides a dedicated
:ref:`normalized() <class_Vector2_method_normalized>` method for this:
.. tabs::
.. code-tab:: gdscript GDScript
@@ -199,12 +210,11 @@ method for normalizing:
a = a.Normalized();
.. warning:: Because normalization involves dividing by the vector's length, you
cannot normalize a vector of length ``0``. Attempting to do so
would normally result in an error. In GDScript though, trying to
call the ``normalized()`` method on a ``Vector2`` or ``Vector3`` of
length 0 leaves the value untouched and avoids the error for you.
call the ``normalized()`` method on a vector of length 0 leaves the
value untouched and avoids the error for you.
Reflection
----------
@@ -220,17 +230,15 @@ other object:
The surface normal has a value of ``(0, -1)`` because this is a horizontal
surface. When the ball collides, we take its remaining motion (the amount left
over when it hits the surface) and reflect it using the normal. In Godot, the
:ref:`Vector2 <class_Vector2>` class has a ``bounce()`` method to handle this.
Here is a GDScript example of the diagram above using a :ref:`CharacterBody2D
over when it hits the surface) and reflect it using the normal. In Godot, there
is a :ref:`bounce() <class_Vector2_method_bounce>` method to handle this.
Here is a code example of the above diagram using a :ref:`CharacterBody2D
<class_CharacterBody2D>`:
.. tabs::
.. code-tab:: gdscript GDScript
# object "collision" contains information about the collision
var collision = move_and_collide(velocity * delta)
var collision: KinematicCollision2D = move_and_collide(velocity * delta)
if collision:
var reflect = collision.get_remainder().bounce(collision.get_normal())
velocity = velocity.bounce(collision.get_normal())
@@ -238,7 +246,6 @@ Here is a GDScript example of the diagram above using a :ref:`CharacterBody2D
.. code-tab:: csharp
// KinematicCollision2D contains information about the collision
KinematicCollision2D collision = MoveAndCollide(_velocity * (float)delta);
if (collision != null)
{
@@ -263,22 +270,25 @@ and
.. image:: img/vector_dot2.png
However, in most cases it is easiest to use the built-in method. Note that the
order of the two vectors does not matter:
The mathematical notation *||A||* represents the magnitude of vector ``A``, and
*A*\ :sub:`x` means the ``x`` component of vector ``A``.
However, in most cases it is easiest to use the built-in :ref:`dot()
<class_Vector2_method_dot>` method. Note that the order of the two vectors does not matter:
.. tabs::
.. code-tab:: gdscript GDScript
var c = a.dot(b)
var d = b.dot(a) # These are equivalent.
var d = b.dot(a) # These are equivalent.
.. code-tab:: csharp
float c = a.Dot(b);
float d = b.Dot(a); // These are equivalent.
float d = b.Dot(a); // These are equivalent.
The dot product is most useful when used with unit vectors, making the first
formula reduce to just ``cosθ``. This means we can use the dot product to tell
formula reduce to just ``cos(θ)``. This means we can use the dot product to tell
us something about the angle between two vectors:
.. image:: img/vector_dot3.png
@@ -297,11 +307,12 @@ player?
.. image:: img/vector_facing2.png
The green arrows ``fA`` and ``fB`` are **unit vectors** representing the
zombies' facing directions and the blue semicircle represents its field of view.
zombie's facing direction and the blue semicircle represents its field of view.
For zombie ``A``, we find the direction vector ``AP`` pointing to the player
using ``P - A`` and normalize it, however, Godot has a helper method to do this
called ``direction_to``. If the angle between this vector and the facing vector
is less than 90°, then the zombie can see the player.
called :ref:`direction_to() <class_Vector2_method_direction_to>`. If the angle
between this vector and the facing vector is less than 90°, then the zombie can
see the player.
In code it would look like this:
@@ -349,9 +360,8 @@ The cross product is calculated like this:
c.Y = (a.Z * b.X) - (a.X * b.Z);
c.Z = (a.X * b.Y) - (a.Y * b.X);
With Godot, you can use the built-in method:
With Godot, you can use the built-in :ref:`Vector3.cross() <class_Vector3_method_cross>`
method:
.. tabs::
.. code-tab:: gdscript GDScript
@@ -362,6 +372,10 @@ With Godot, you can use the built-in method:
var c = a.Cross(b);
The cross product is not mathematically defined in 2D. The :ref:`Vector2.cross()
<class_Vector2_method_cross>` method is a commonly used analog of the 3D cross
product for 2D vectors.
.. note:: In the cross product, order matters. ``a.cross(b)`` does not give the
same result as ``b.cross(a)``. The resulting vectors point in
**opposite** directions.
@@ -371,8 +385,8 @@ Calculating normals
One common use of cross products is to find the surface normal of a plane or
surface in 3D space. If we have the triangle ``ABC`` we can use vector
subtraction to find two edges ``AB`` and ``AC``. Using the cross product, ``AB x
AC`` produces a vector perpendicular to both: the surface normal.
subtraction to find two edges ``AB`` and ``AC``. Using the cross product,
``AB × AC`` produces a vector perpendicular to both: the surface normal.
Here is a function to calculate a triangle's normal:
@@ -380,7 +394,7 @@ Here is a function to calculate a triangle's normal:
.. code-tab:: gdscript GDScript
func get_triangle_normal(a, b, c):
# find the surface normal given 3 vertices
# Find the surface normal given 3 vertices.
var side1 = b - a
var side2 = c - a
var normal = side1.cross(side2)
@@ -390,7 +404,7 @@ Here is a function to calculate a triangle's normal:
Vector3 GetTriangleNormal(Vector3 a, Vector3 b, Vector3 c)
{
// find the surface normal given 3 vertices
// Find the surface normal given 3 vertices.
var side1 = b - a;
var side2 = c - a;
var normal = side1.Cross(side2);