Merge pull request #7486 from akien-mga/math-tweaks

Tweak Vector math page (style, links, more notes)
This commit is contained in:
Rémi Verschelde
2023-06-14 09:35:17 +02:00
committed by GitHub
4 changed files with 76 additions and 55 deletions

View File

@@ -1,6 +1,6 @@
.. _docs_image_guidelines: .. _docs_image_guidelines:
Creating Documentation Images Creating documentation images
============================= =============================
Throughout documentation images are often needed to make the explanation 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 Format conversion
----------------- -----------------
The current format for images in Godot's documentation is WebP (.webp). While some The current format for images in Godot's documentation is WebP (``.webp``).
Linux programs will support saving screenshots in this format, macOS and the While some Linux programs will support saving screenshots in this format, macOS
Snip & Sketch program on Windows do not. For images that don't need editing, and the Snip & Sketch program on Windows do not. For images that don't need
such as precise cropping or adding outlines, Squoosh can be used. editing, such as precise cropping or adding outlines, Squoosh can be used.
`Squoosh <https://squoosh.app/>`_ is a converter developed by Google, is open `Squoosh <https://squoosh.app/>`_ is a converter developed by Google, is open
source, and doesn't give Google any image rights by using it. 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 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 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 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 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 sure the **Constrain Proportions** box at the bottom of the menu is checked so you only have
to change 1 value. to change 1 value.
@@ -107,14 +107,14 @@ Outlines arrows and text
Sometimes an image needs something extra to properly direct the readers Sometimes an image needs something extra to properly direct the readers
attention, or make something clear. Outlines and arrows can be used attention, or make something clear. Outlines and arrows can be used
for this purpose. For these types of edits Inkscape is the recommended open 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/>`_. 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 Like Krita, if you're on Linux you can also check your distributions repository
or get it from Flathub. or get it from Flathub.
A full tutorial on creating outlines is not provided here, we recommend searching 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 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 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 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 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 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 Adding an image to a documentation page
--------------------------------------- ---------------------------------------
Once you've finished working on your image it can be added to the documentation. 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 All images are stored in folders named ``img`` next to the page they are used in.
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 To add your image, add it to the ``img`` folder that's in the same folder as the
`documentation_image.webp` would be whatever your image is named. ``.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 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 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 angle ``θ`` (theta) and a length (or magnitude) ``m``. In this case, the arrow
**position vector** - it denotes a position in space, relative to the origin. 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 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 **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 Godot supports both :ref:`Vector2 <class_Vector2>` and :ref:`Vector3
<class_Vector3>` for 2D and 3D usage, respectively. The same mathematical rules <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 Member access
------------- -------------
@@ -84,18 +87,18 @@ The individual components of the vector can be accessed directly by name.
.. tabs:: .. tabs::
.. code-tab:: gdscript GDScript .. code-tab:: gdscript GDScript
# create a vector with coordinates (2, 5) # Create a vector with coordinates (2, 5).
var a = Vector2(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() var b = Vector2()
b.x = 3 b.x = 3
b.y = 1 b.y = 1
.. code-tab:: csharp .. code-tab:: csharp
// create a vector with coordinates (2, 5) // Create a vector with coordinates (2, 5).
var a = new Vector2(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(); var b = new Vector2();
b.X = 3; b.X = 3;
b.Y = 1; b.Y = 1;
@@ -125,7 +128,8 @@ Scalar multiplication
--------------------- ---------------------
.. note:: Vectors represent both direction and magnitude. A value representing .. 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**: 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 A vector can represent **any** quantity with a magnitude and direction. Typical
examples are: position, velocity, acceleration, and force. In this image, the 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 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 ``(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. can find the position for step 2 by adding the velocity to the current position.
.. image:: img/vector_movement1.png .. image:: img/vector_movement1.png
.. tip:: Velocity measures the **change** in position per unit of time. The new .. 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 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 Subtracting the tank's position from the robot's position gives the vector
pointing from the tank to the robot. 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 Unit vectors
~~~~~~~~~~~~ ~~~~~~~~~~~~
@@ -187,8 +198,8 @@ Normalization
**Normalizing** a vector means reducing its length to ``1`` while preserving its **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. 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 Because this is such a common operation, Godot provides a dedicated
method for normalizing: :ref:`normalized() <class_Vector2_method_normalized>` method for this:
.. tabs:: .. tabs::
.. code-tab:: gdscript GDScript .. code-tab:: gdscript GDScript
@@ -199,12 +210,11 @@ method for normalizing:
a = a.Normalized(); a = a.Normalized();
.. warning:: Because normalization involves dividing by the vector's length, you .. warning:: Because normalization involves dividing by the vector's length, you
cannot normalize a vector of length ``0``. Attempting to do so cannot normalize a vector of length ``0``. Attempting to do so
would normally result in an error. In GDScript though, trying to would normally result in an error. In GDScript though, trying to
call the ``normalized()`` method on a ``Vector2`` or ``Vector3`` of call the ``normalized()`` method on a vector of length 0 leaves the
length 0 leaves the value untouched and avoids the error for you. value untouched and avoids the error for you.
Reflection Reflection
---------- ----------
@@ -220,17 +230,15 @@ other object:
The surface normal has a value of ``(0, -1)`` because this is a horizontal 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 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 over when it hits the surface) and reflect it using the normal. In Godot, there
:ref:`Vector2 <class_Vector2>` class has a ``bounce()`` method to handle this. is a :ref:`bounce() <class_Vector2_method_bounce>` method to handle this.
Here is a GDScript example of the diagram above using a :ref:`CharacterBody2D Here is a code example of the above diagram using a :ref:`CharacterBody2D
<class_CharacterBody2D>`: <class_CharacterBody2D>`:
.. tabs:: .. tabs::
.. code-tab:: gdscript GDScript .. code-tab:: gdscript GDScript
# object "collision" contains information about the collision var collision: KinematicCollision2D = move_and_collide(velocity * delta)
var collision = move_and_collide(velocity * delta)
if collision: if collision:
var reflect = collision.get_remainder().bounce(collision.get_normal()) var reflect = collision.get_remainder().bounce(collision.get_normal())
velocity = velocity.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 .. code-tab:: csharp
// KinematicCollision2D contains information about the collision
KinematicCollision2D collision = MoveAndCollide(_velocity * (float)delta); KinematicCollision2D collision = MoveAndCollide(_velocity * (float)delta);
if (collision != null) if (collision != null)
{ {
@@ -263,22 +270,25 @@ and
.. image:: img/vector_dot2.png .. image:: img/vector_dot2.png
However, in most cases it is easiest to use the built-in method. Note that the The mathematical notation *||A||* represents the magnitude of vector ``A``, and
order of the two vectors does not matter: *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:: .. tabs::
.. code-tab:: gdscript GDScript .. code-tab:: gdscript GDScript
var c = a.dot(b) var c = a.dot(b)
var d = b.dot(a) # These are equivalent. var d = b.dot(a) # These are equivalent.
.. code-tab:: csharp .. code-tab:: csharp
float c = a.Dot(b); 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 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: us something about the angle between two vectors:
.. image:: img/vector_dot3.png .. image:: img/vector_dot3.png
@@ -297,11 +307,12 @@ player?
.. image:: img/vector_facing2.png .. image:: img/vector_facing2.png
The green arrows ``fA`` and ``fB`` are **unit vectors** representing the 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 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 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 called :ref:`direction_to() <class_Vector2_method_direction_to>`. If the angle
is less than 90°, then the zombie can see the player. 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: 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.Y = (a.Z * b.X) - (a.X * b.Z);
c.Z = (a.X * b.Y) - (a.Y * b.X); c.Z = (a.X * b.Y) - (a.Y * b.X);
With Godot, you can use the built-in :ref:`Vector3.cross() <class_Vector3_method_cross>`
method:
With Godot, you can use the built-in method:
.. tabs:: .. tabs::
.. code-tab:: gdscript GDScript .. code-tab:: gdscript GDScript
@@ -362,6 +372,10 @@ With Godot, you can use the built-in method:
var c = a.Cross(b); 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 .. 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 same result as ``b.cross(a)``. The resulting vectors point in
**opposite** directions. **opposite** directions.
@@ -371,8 +385,8 @@ Calculating normals
One common use of cross products is to find the surface normal of a plane or 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 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 subtraction to find two edges ``AB`` and ``AC``. Using the cross product,
AC`` produces a vector perpendicular to both: the surface normal. ``AB × AC`` produces a vector perpendicular to both: the surface normal.
Here is a function to calculate a triangle's 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 .. code-tab:: gdscript GDScript
func get_triangle_normal(a, b, c): 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 side1 = b - a
var side2 = c - a var side2 = c - a
var normal = side1.cross(side2) 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) 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 side1 = b - a;
var side2 = c - a; var side2 = c - a;
var normal = side1.Cross(side2); var normal = side1.Cross(side2);