Cross-platform C SDK logo

Cross-platform C SDK

2D Transformations

❮ Back
Next ❯
This page has been automatically translated using the Google Translate API services. We are working on improving texts. Thank you for your understanding and patience.

Functions

voidt2d_tof (...)
voidt2d_tod (...)
voidt2d_move (...)
voidt2d_rotate (...)
voidt2d_scale (...)
voidt2d_invfast (...)
voidt2d_inverse (...)
voidt2d_mult (...)
voidt2d_vmult (...)
voidt2d_vmultn (...)
voidt2d_decompose (...)

Types and Constants

T2DkIDENT

Affine transformations are a type of mathematical operation that allows coordinate changes between different reference systems. For example in (Figure 1) (a) we construct a polygon expressing the coordinates of its vertices in a Cartesian system: [ (4,1), (2,5), (-3,5), (-4,2), (0, -3) ]. Now let's imagine that we want to draw several instances of our model on a plane, each with a different position, orientation and size (Figure 1) (b). We would need to calculate the coordinates of the points of the polygon in the new locations, in order to correctly draw the lines that delimit them.

Drawing of a polygon in a Cartesian system and drawing of the same polygon in different positions and orientations.
Figure 1: Geometric model (a) Expressed in a Cartesian system. (b) After applying transformations.

Vector Algebra gives us a powerful tool with which the relationship between two systems can be expressed using six real numbers (Figure 2). The first four values correspond to a 2x2 matrix with the coordinates of the vectors X=[1,0] and Y=[0,1] in the new reference system. This matrix integrates a possible rotation and scaling of the axes. The last two values indicate a displacement in the origin of coordinates. In (Formula 1) we have the mathematical development to transform the point [4.1] to a new base rotated 25° with respect to the origin and displaced 11 units on the X axis and -5 on the Y axis. Applying the same operation to all points, we would transform the object.

Geometric representation of a point expressed in two reference systems.
Figure 2: Change of base. Relationship of a point in two different reference systems.
Point [4,1] transformation.
Formula 1: Point [4,1] transformation.

1. Elementary transformations

In principle, any combination of values ​​[i.x, i.y, j.x, j.y, p.x, p.y] would provide a valid transformation, although if we do not choose them with certain criteria we will obtain aberrations that are not very useful in practice. The most used transformations in graphic and engineering applications are (Figure 3) (Figure 4) (Formula 2):

  • Translation (a): Moves the origin of the object to another point.
  • Rotation (b): Rotates the object on the origin of its local system.
  • Scaling (c): Change the size. If sx < 1, reduce. sx > 1, increase. sx = 1, does not vary. In non-uniform scales, sx and sy have different values, which will produce a distortion in the aspect ratio.
  • Identity (d): It is the null transformation. When applied, the vectors remain unchanged.
  • Grouped affine transformation.
    Figure 3: Classification of affine transformations.
    Geometric representation of a translation, rotation, scaling and identity.
    Figure 4: Geometric representation of elementary transformations. (a) Translation, (b) Rotation, (c) Scaling, (d) Identity.
    Translation, Rotation, Scaling and Identity.
    Formula 2: Translation, Rotation, Scaling and Identity.

2. Composition of transformations

It is possible to compose or accumulate transformations by matrix multiplication (Formula 3). The usual thing in 2d models will be to obtain the final location of an object from the elementary transformations translation, rotation and scaling. The accumulation is also useful for positioning elements in hierarchical structures, where the location of each object depends directly on that of its upper node (parent).

  • Use t2d_movef to add a displacement to an existing transformation.
  • Use t2d_rotatef to add a rotation.
  • Use t2d_scalef to add a scaling.
  • Use t2d_multf to add a transformation.
  • Use t2d_vmultf to apply a transformation to a vector.
  • Use t2d_vmultnf to apply a transformation to several vectors.
  • Use kT2D_IDENTf to reference the identity transformation.
  • Composition of two arbitrary transformations.
    Formula 3: Composition of two arbitrary transformations.

Matrix multiplication is not commutative, but the order in which the operations are applied will affect the final result. For example in (Figure 5) (a), the origin has been moved and then applied a rotation. In (Figure 5) (b) it has been done on the contrary, first rotate and then move.

Listing 1: Acumulación de transformaciones.
1
2
3
4
5
6
7
8
9
// (a) First move, then rotate
T2Df t2d;
t2d_movef(&t2d, kT2D_IDENTf, 11, 0);
t2d_rotatef(&t2d, &t2d, kBMATH_PIf / 4);

// (b) First rotate, then move
T2Df t2d;
t2d_rotatef(&t2d, kT2D_IDENTf, kBMATH_PIf / 4);
t2d_movef(&t2d, &t2d, 11, 0);
Geometric representation of applying a translation and a rotation. And on the contrary, rotation and translation.
Figure 5: Effect of the order of application of transformations.

3. Decomposition and inverse

Any chain of translations, rotations, and scales defines an affine reference frame that can be expressed in terms of a single traslation, rotation, and scale (Figure 6). We can "undo" this transformation and return to the origin through the inverse transformation (Listing 2).

❮ Back
Next ❯

kIDENT

const T2Df kT2D_IDENTf;

const T2Dd kT2D_IDENTd;

const T2D T2D::kIDENT;

Represents the identity transformation.


t2d_tof ()

Converts a transformation from double to float.

void
t2d_tof(T2Df *dest,
        const T2Dd *src);
dest

Destination transformation.

src

Origin transformation.


t2d_tod ()

Converts a transform from float to double.

void
t2d_tod(T2Dd *dest,
        const T2Df *src);
dest

Destination transformation.

src

Origin transformation.


t2d_move ()

Multiply a transformation by a translation t2d = src * move(x,y).

void
t2d_movef(T2Df *dest,
          const T2Df *src,
          const real32_t x,
          const real32_t y);

void
t2d_moved(T2Dd *dest,
          const T2Dd *src,
          const real64_t x,
          const real64_t y);

void
T2D::move(T2D *dest,
          const T2D *src,
          const real x,
          const real y);
dest

Result transformation.

src

Initial transformation.

x

X coordinate of displacement.

y

Y coordinate of displacement.

Remarks

dest and src can point to the same matrix.


t2d_rotate ()

Multiply a transformation by a rotation dest = src * rotate(a).

void
t2d_rotatef(T2Df *dest,
            const T2Df *src,
            const real32_t a);

void
t2d_rotated(T2Dd *dest,
            const T2Dd *src,
            const real64_t a);

void
T2D::rotate(T2D *dest,
            const T2D *src,
            const real a);
dest

Result transformation.

src

Initial transformation.

a

Rotation angle in radians. Positive angles are those that rotate from the X axis to the Y axis.

Remarks

dest and src can point to the same matrix.


t2d_scale ()

Multiply a transformation by an scale dest = src * scale(sx,sy).

void
t2d_scalef(T2Df *dest,
           const T2Df *src,
           const real32_t sx,
           const real32_t sy);

void
t2d_scaled(T2Dd *dest,
           const T2Dd *src,
           const real64_t sx,
           const real64_t sy);

void
T2D::scale(T2D *dest,
           const T2D *src,
           const real sx,
           const real sy);
dest

Result transformation.

src

Initial transformation.

sx

Scaling on the x axis.

sy

Scaling on the y axis.

Remarks

dest and src can point to the same matrix.


t2d_invfast ()

Calculate the inverse transformation, assuming the input is orthogonal.

void
t2d_invfastf(T2Df *dest,
             const T2Df *src);

void
t2d_invfastd(T2Dd *dest,
             const T2Dd *src);

void
T2D::invfast(T2D *dest,
             const T2D *src);
dest

Inverse transformation.

src

Initial transformation.

Remarks

The transformation will be orthogonal only if it contains rotations and translations, otherwise the result of applying it will be unpredictable. dest and src can point to the same matrix.


t2d_inverse ()

Calculate the inverse transformation.

void
t2d_inversef(T2Df *dest,
             const T2Df *src);

void
t2d_inversed(T2Dd *dest,
             const T2Dd *src);

void
T2D::inverse(T2D *dest,
             const T2D *src);
dest

Inverse transformation.

src

Initial transformation.

Remarks

dest and src can point to the same matrix.


t2d_mult ()

Multiply two transformations dest = src1 * src2.

void
t2d_multf(T2Df *dest,
          const T2Df *src1,
          const T2Df *src2);

void
t2d_multd(T2Dd *dest,
          const T2Dd *src1,
          const T2Dd *src2);

void
T2D::mult(T2D *dest,
          const T2D *src1,
          const T2D *src2);
dest

Result transformation.

src1

First operating.

src2

Second operating.

Remarks

dest, src1 and src2 can point to the same matrix.


t2d_vmult ()

Transform a vector dest = t2d * src.

void
t2d_vmultf(V2Df *dest,
           const T2Df *t2d,
           const V2Df *src);

void
t2d_vmultd(V2Dd *dest,
           const T2Dd *t2d,
           const V2Dd *src);

void
T2D::vmult(V2D *dest,
           const T2D *t2d,
           const V2D *src);
dest

Transformed vector.

t2d

Transformation.

src

Original vector.

Remarks

dest and src can point to the same vector.


t2d_vmultn ()

Transform a vector list dest[i] = t2d * src[i].

void
t2d_vmultnf(V2Df *dest,
            const T2Df *t2d,
            const V2Df *src,
            const uint32_t n);

void
t2d_vmultnd(V2Dd *dest,
            const T2Dd *t2d,
            const V2Dd *src,
            const uint32_t n);

void
T2D::vmultn(V2D *dest,
            const T2D *t2d,
            const V2D *src,
            const uint32_t n);
dest

Transformed vector array.

t2d

Transformation.

src

Original vector array.

n

Number of vectors in src.

Remarks

dest and src can point to the same array.


t2d_decompose ()

Gets the position, rotation, and scaling of a transformation.

void
t2d_decomposef(const T2Df *t2d,
               V2Df *pos,
               real32_t *a,
               V2Df *sc);

void
t2d_decomposed(const T2Dd *t2d,
               V2Dd *pos,
               real64_t *a,
               V2Dd *sc);

void
T2D::decompose(const T2D *t2d,
               V2D *pos,
               real *a,
               V2D *sc);
t2d

Transformation.

pos

Position. Can be NULL.

a

Angle in radians (-π/2, π/2). Can be NULL.

sc

Scaled. Can be NULL.

Remarks

If the transformation is not made up of a sequence of translations, rotations, and scales, the result will not be valid.

❮ Back
Next ❯