Улучшение документации
This commit is contained in:
parent
b5aa39c145
commit
c7e39e1527
13 changed files with 439 additions and 239 deletions
|
@ -1,78 +1,48 @@
|
|||
# Versors
|
||||
|
||||
Quaternions are complex numbers which have one real component and three
|
||||
imaginary components.
|
||||
[Quaternions](./quaternion-eng.md) are complex numbers which have one real component and three imaginary components.
|
||||
|
||||
A quaternion can be viewed as a four-dimensional vector:
|
||||

|
||||
|
||||
1. summation and subtraction of quaternions are same as for four-dimensional
|
||||
vectors in Euclidean space;
|
||||
Quaternions were discovered by mathematician William Hamilton and introduced to the public in 1843.
|
||||
|
||||
2. quaternions can be multiplied by real numbers the same way as
|
||||
four-dimensional vectors;
|
||||
In the same way, William Hamilton proposed a special class of quaternions, which he called versors.
|
||||
|
||||
3. the modulus of a quaternion is calculated in exactly the same way as
|
||||
the modulus of a vector in four-dimensional Euclidean space;
|
||||
A versor is a quaternion whose modulus is equal to one. That is, the formulas defining quaternions must be supplemented with the condition that the modulus of a quaternion is equal to one.
|
||||
|
||||
4. the multiplication of two quaternions can be represented as the product
|
||||
of a 4x4 matrix and a four-dimensional vector.
|
||||

|
||||
|
||||
A quaternion has four degrees of freedom. But if we introduce a constraint in
|
||||
the form of a requirement that the modulus of this quaternion be equal to one,
|
||||
then such a set of quaternions will have only three degrees of freedom.
|
||||
The name comes from the Latin verb "versare", meaning "to turn", "to rotate", to which is added the Latin ending -or, which denotes the subject performing the action.
|
||||
|
||||
These quaternions represent a sphere of radius 1 in four-dimensional space.
|
||||
The "surface" of this sphere has a dimension equal to three.
|
||||
Literally, the Latin word "versor" can be translated as "rotator" or "turner".
|
||||
|
||||
Quaternions of unit length describe rotations in three-dimensional space very
|
||||
well. And this is logical, because rotations in three-dimensional space have
|
||||
three degrees of freedom, just like a sphere in four-dimensional space.
|
||||
Versors turned out to be a pretty good tool for describing rotations in three-dimensional space.
|
||||
|
||||
There is a special name for a quaternion of unit length: versor.
|
||||
For the combination of two consecutive rotations, the operation of multiplying quaternions has proven useful, and for obtaining the inverse rotation, the operation of obtaining the conjugate quaternion.
|
||||
|
||||
Versors are quaternions of unit length.
|
||||
When multiplying two versors (quaternions of unit length) and taking the conjugate versor, the result will also be a versor, that is, a quaternion of unit length.
|
||||
|
||||
Addition and subtraction of two quaternions, as well as multiplication and division of a quaternion by a number, turned out to be unnecessary for describing rotations in three-dimensional space.
|
||||
|
||||
## Advantages of versors over quaternions
|
||||
|
||||
The main advantage of versors is that they do not degrade.
|
||||
The main advantage of isolating versors as a separate abstraction from quaternions is that versors retain a modulus equal to one, i.e., versors do not degenerate.
|
||||
|
||||
If you multiply two quaternions whose moduli are equal to one, the result will
|
||||
also be a quaternion with a modulus equal to one. While the product of two
|
||||
quaternions whose moduli differ from one will yield a quaternion whose modulus
|
||||
will most likely also differ from one. And the product of several quaternions
|
||||
can yield a quaternion whose modulus will be close to zero.
|
||||
Quaternions whose modulus is not equal to one can, as a result of many multiplication operations, yield a quaternion whose modulus can be so close to zero that it will be comparable to the magnitude of the error.
|
||||
|
||||
Thus, the modulus of a versor is always equal to one, unlike a regular
|
||||
quaternion.
|
||||
In practice, the versor module is not always equal to one, but is close to one due to the presence of the **float** and **double** (**binary32** and **binary64**) error types. But the BGC library functions ensure that the modulus of the vertex obtained as a result of some operation does not deviate from unity by an amount not exceeding a specified error.
|
||||
|
||||
In practice, the modulus of a versor is not always equal to one, but is close
|
||||
to one due to the presence of an error in the **float** and **double**
|
||||
(**binary32** and **binary64**) types.
|
||||
And this is the second advantage of using versors to describe rotations. The developer who uses the library does not need to perform normalization, as would have to be done with ordinary quaternions.
|
||||
|
||||
The second advantage of versors is that the library functions take on the task
|
||||
of maintaining the versor modulus so that it does not deviate too much from one.
|
||||
But the library functions do not always perform versor normalization, but only when necessary. The library functions normalize the resulting versor only when the versor module deviates from unity by more than a predetermined error value (epsilon).
|
||||
|
||||
Thus, the developer does not need to perform normalization, as he would have
|
||||
to do with regular quaternions.
|
||||
|
||||
The third advantage of versors is that the library functions do not always
|
||||
perform versor normalization, but only when it is necessary.
|
||||
|
||||
The library functions check the difference between the versor modulus and 1, and
|
||||
if the error is greater than a predefined threshold (epsilon), the function
|
||||
normalizes the resulting versor.
|
||||
|
||||
In most cases, when the input parameters are versors (normalized quaternions),
|
||||
there is no need to normalize the function result. This way, time-consuming
|
||||
operations such as square root calculations and division can be avoided. This
|
||||
approach allows to improve performance and keep versions normalized.
|
||||
In most cases, when the input parameters are versors (normalized quaternions), the magnitude of the resulting versor also does not deviate much from one, and therefore there is no need to perform normalization. Thus, time-consuming operations such as calculating square roots and division can be avoided. This approach improves performance and keeps versors normalized.
|
||||
|
||||
## Implementation of versors in the library
|
||||
|
||||
The library has a separate implementation for versors in the form of special
|
||||
structures and a set of functions that keep the modulus of a versorclose to one.
|
||||
The library has a separate implementation for versors in the form of special structures and a set of functions that support the versor module close to one, since it is necessary to support the versor module close to one, and versors do not need addition and subtraction, as well as multiplication and division by a number.
|
||||
|
||||
There are two structures for versors: **BgcVersorFP32** and **BgcVersorFP64**:
|
||||
There are two structures for describing a versor:
|
||||
|
||||
typedef struct {
|
||||
const float s0, x1, x2, x3;
|
||||
|
@ -82,63 +52,27 @@ There are two structures for versors: **BgcVersorFP32** and **BgcVersorFP64**:
|
|||
const double s0, x1, x2, x3;
|
||||
} BgcVersorFP64;
|
||||
|
||||
The fields are deliberately declared const so that a developer using these
|
||||
structures is not tempted to change the values of the fields directly.
|
||||
The field **s0** is the real part of the versor (normalized quaternion), and the fields **x1**, **x2**, and **x3** are the imaginary components of the versor.
|
||||
|
||||
With these structures, it is better to use special functions that allow you
|
||||
to save new values in the structure fields of **BgcVersorFP32** and
|
||||
**BgcVersorFP64**.
|
||||
The fields of the structures are intentionally declared as const to encourage the developer to use functions for working with versors, instead of directly setting the field values. The functions responsible for operations on versors maintain the module of the obtained versors equal to one.
|
||||
|
||||
With these structures, it is better to use special functions that allow setting new values in the fields of the **BgcVersorFP32** and **BgcVersorFP64** structures.
|
||||
|
||||
## Operation with versors
|
||||
|
||||
- Resetting the state to idle (reset)
|
||||
- Setting the values of components (set values)
|
||||
- Copying the state (copy)
|
||||
- Swapping the states (swap)
|
||||
- Making a versor with turn (set turn)
|
||||
- Checking the state is idle (is idle)
|
||||
- Convertation of type (convert)
|
||||
- Shortening of the turn (shorten)
|
||||
- Inversion (invert)
|
||||
- Combination (combine)
|
||||
- Getting description of the turn (get rotation)
|
||||
- Getting the rotation matrix (get rotation matrix)
|
||||
- Getting the reverse rotation matrix (get reverse matrix)
|
||||
- Turning a vector (turn vector)
|
||||
- Turning a vector backward (turn vector back)
|
||||
- Comparsion (are close)
|
||||
|
||||
### Resetting the state to idle
|
||||
|
||||
A versor which describes an idle turn has these values of the components:
|
||||
|
||||
s0 = 1, x1 = 0, x2 = 0, x3 = 0
|
||||
|
||||
There is a function which resets the state of a versor to that state.
|
||||
|
||||
For **BgcVersorFP32**:
|
||||
|
||||
inline void bgc_versor_reset_fp32(BgcVersorFP32* versor);
|
||||
|
||||
For **BgcVersorFP64**:
|
||||
|
||||
inline void bgc_versor_reset_fp64(BgcVersorFP64* versor);
|
||||
|
||||
Example of usage:
|
||||
|
||||
#include <stdio.h>
|
||||
#include <basic-geometry.h>
|
||||
|
||||
int main() {
|
||||
BgFP32Versor versor;
|
||||
|
||||
bgc_versor_reset_fp32(&versor);
|
||||
|
||||
printf("Versor: (%f, %f, %f, %f)\n", versor.s0, versor.x1, versor.x2, versor.x3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result:
|
||||
|
||||
Versor: (1.000000, 0.000000, 0.000000, 0.000000)
|
||||
- [Reset state](./versor-reset-eng.md)
|
||||
- [Specify component values](./versor-set-values-eng.md)
|
||||
- Copy component values
|
||||
- Swap component values
|
||||
- Build based on rotation
|
||||
- Check for absence of rotation
|
||||
- Type conversion
|
||||
- Rotation reduction
|
||||
- Inversion
|
||||
- Combination
|
||||
- Get rotation description
|
||||
- Get rotation matrix
|
||||
- Get inverse rotation matrix
|
||||
- Rotate vector
|
||||
- Inverse vector rotation
|
||||
- Compare
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue