AffineTransform


public abstract class AffineTransform

Known direct subclasses
ImmutableAffineTransform

An affine transformation in the plane.

MutableAffineTransform

An affine transformation in the plane.


An affine transformation in the plane. The transformation can be thought of as a 3x3 matrix:

⎡m00  m10  m20⎤
⎢m01 m11 m21⎥
⎣ 0 0 1 ⎦

Applying the transformation can be thought of as a matrix multiplication, with the to-be-transformed point represented as a column vector with an extra 1:

⎡m00  m10  m20⎤   ⎡x⎤   ⎡m00*x + m10*y + m20⎤
⎢m01 m11 m21⎥ * ⎢y⎥ = ⎢m01*x + m11*y + m21⎥
⎣ 0 0 1 ⎦ ⎣1⎦ ⎣ 1 ⎦

Transformations are composed via multiplication. Multiplication is not commutative (i.e. AB != BA), and the left-hand transformation is composed "after" the right hand transformation. E.g., if you have:

val rotate = ImmutableAffineTransform.rotate(Angle.degreesToRadians(45))
val translate = ImmutableAffineTransform.translate(Vec(10, 0))

then rotate * translate first translates 10 units in the positive x-direction, then rotates 45° about the origin.

ImmutableAffineTransform and MutableAffineTransform are the two concrete implementations of this.

Summary

Public fields

static final @NonNull ImmutableAffineTransform

Constant representing an identity transformation, which maps a point to itself, i.e. it leaves it unchanged.

Public methods

final @NonNull ImmutableParallelogram

Returns an ImmutableParallelogram containing the result of applying the AffineTransform to box.

final @NonNull ImmutableParallelogram

Returns an ImmutableParallelogram containing the result of applying the AffineTransform to parallelogram.

final @NonNull ImmutableVec

Returns an ImmutableVec containing the result of applying the AffineTransform to point.

final @NonNull ImmutableSegment

Returns an ImmutableSegment containing the result of applying the AffineTransform to segment.

final @NonNull ImmutableTriangle

Returns an ImmutableTriangle containing the result of applying the AffineTransform to triangle.

final @NonNull MutableParallelogram
applyTransform(
    @NonNull Box box,
    @NonNull MutableParallelogram outParallelogram
)

Apply the AffineTransform to the Box and store the result in the MutableParallelogram.

final @NonNull MutableParallelogram
applyTransform(
    @NonNull Parallelogram parallelogram,
    @NonNull MutableParallelogram outParallelogram
)

Apply the AffineTransform to the Parallelogram and store the result in the MutableParallelogram.

final @NonNull MutableVec

Apply the AffineTransform to the Vec and store the result in the MutableVec.

final @NonNull MutableSegment
applyTransform(
    @NonNull Segment segment,
    @NonNull MutableSegment outSegment
)

Apply the AffineTransform to the Segment and store the result in the MutableSegment.

final @NonNull MutableTriangle
applyTransform(
    @NonNull Triangle triangle,
    @NonNull MutableTriangle outTriangle
)

Apply the AffineTransform to the Triangle and store the result in the MutableTriangle.

final @NonNull ImmutableAffineTransform

Returns the inverse of the AffineTransform.

final @NonNull MutableAffineTransform

Populates outAffineTransform with the inverse of this AffineTransform.

final @Size(min = 6) @NonNull float[]
getValues(@Size(min = 6) @NonNull float[] outArray)

Populates the first 6 elements of outArray with the values of this transform, starting with the top left corner of the matrix and proceeding in row-major order.

final boolean
isAlmostEqual(
    @NonNull AffineTransform other,
    @FloatRange(from = 0.0) float tolerance
)

Compares this AffineTransform with other, and returns true if each component of the transform matrix is within tolerance of the corresponding component of other.

static final void

Multiplies the lhs transform by the rhs transform as matrices, and stores the result in output.

Extension functions

final void

Writes the values from this AffineTransform to out.

final @NonNull Matrix

Constructs a Matrix with the values from the AffineTransform.

Public fields

IDENTITY

public static final @NonNull ImmutableAffineTransform IDENTITY

Constant representing an identity transformation, which maps a point to itself, i.e. it leaves it unchanged.

Public methods

applyTransform

Added in 1.0.0-alpha06
public final @NonNull ImmutableParallelogram applyTransform(@NonNull Box box)

Returns an ImmutableParallelogram containing the result of applying the AffineTransform to box.

Note that applying an AffineTransform to a Box results in a Parallelogram. If you need a Box, use Parallelogram.computeBoundingBox to get the minimum bounding box of the result.

Performance-sensitive code should use the applyTransform overload that takes a pre-allocated MutableParallelogram, so that instance can be reused across multiple calls.

applyTransform

Added in 1.0.0-alpha06
public final @NonNull ImmutableParallelogram applyTransform(@NonNull Parallelogram parallelogram)

Returns an ImmutableParallelogram containing the result of applying the AffineTransform to parallelogram.

Performance-sensitive code should use the applyTransform overload that takes a pre-allocated MutableParallelogram, so that instance can be reused across multiple calls.

applyTransform

Added in 1.0.0-alpha06
public final @NonNull ImmutableVec applyTransform(@NonNull Vec point)

Returns an ImmutableVec containing the result of applying the AffineTransform to point.

Note that this treats point as a location, not an offset. If you want to transform an offset, you must also transform the origin and subtract that from the result, e.g.:

val result = MutableVec()
Vec.subtract(
transform.applyTransform(vec),
transform.applyTransform(Vec.ORIGIN),
result
)

Performance-sensitive code should use the applyTransform overload that takes a pre-allocated MutableVec, so that instance can be reused across multiple calls.

applyTransform

Added in 1.0.0-alpha06
public final @NonNull ImmutableSegment applyTransform(@NonNull Segment segment)

Returns an ImmutableSegment containing the result of applying the AffineTransform to segment.

Performance-sensitive code should use the applyTransform overload that takes a pre-allocated MutableSegment, so that instance can be reused across multiple calls.

applyTransform

Added in 1.0.0-alpha06
public final @NonNull ImmutableTriangle applyTransform(@NonNull Triangle triangle)

Returns an ImmutableTriangle containing the result of applying the AffineTransform to triangle.

Performance-sensitive code should use the applyTransform overload that takes a pre-allocated MutableTriangle, so that instance can be reused across multiple calls.

applyTransform

Added in 1.0.0-alpha06
public final @NonNull MutableParallelogram applyTransform(
    @NonNull Box box,
    @NonNull MutableParallelogram outParallelogram
)

Apply the AffineTransform to the Box and store the result in the MutableParallelogram. This is the only Apply function where the input cannot also be the output, as applying an Affine Transform to a Box makes a Parallelogram.

applyTransform

Added in 1.0.0-alpha06
public final @NonNull MutableParallelogram applyTransform(
    @NonNull Parallelogram parallelogram,
    @NonNull MutableParallelogram outParallelogram
)

Apply the AffineTransform to the Parallelogram and store the result in the MutableParallelogram. The same MutableParallelogram can be used as both the input and output to avoid additional allocations.

applyTransform

Added in 1.0.0-alpha06
public final @NonNull MutableVec applyTransform(@NonNull Vec point, @NonNull MutableVec outVec)

Apply the AffineTransform to the Vec and store the result in the MutableVec. The same MutableVec can be used as both the input and output to avoid additional allocations. Returns outVec.

Note that this treats point as a location, not an offset. If you want to transform an offset, you must also transform the origin and subtract that from the result, e.g.:

Vec.subtract(
transform.applyTransform(vec, scratchPoint1),
transform.applyTransform(Vec.ORIGIN, scratchPoint2),
result
)

applyTransform

Added in 1.0.0-alpha06
public final @NonNull MutableSegment applyTransform(
    @NonNull Segment segment,
    @NonNull MutableSegment outSegment
)

Apply the AffineTransform to the Segment and store the result in the MutableSegment. The same MutableSegment can be used as both the input and output to avoid additional allocations. Returns outSegment.

applyTransform

Added in 1.0.0-alpha06
public final @NonNull MutableTriangle applyTransform(
    @NonNull Triangle triangle,
    @NonNull MutableTriangle outTriangle
)

Apply the AffineTransform to the Triangle and store the result in the MutableTriangle. The same MutableTriangle can be used as both the input and output to avoid additional allocations. Returns outTriangle.

computeInverse

Added in 1.0.0-alpha06
public final @NonNull ImmutableAffineTransform computeInverse()

Returns the inverse of the AffineTransform.

Performance-sensitive code should use the computeInverse overload that takes a pre-allocated MutableAffineTransform, so that instance can be reused across multiple calls.

Throws
kotlin.IllegalArgumentException

if the AffineTransform cannot be inverted.

computeInverse

Added in 1.0.0-alpha06
public final @NonNull MutableAffineTransform computeInverse(@NonNull MutableAffineTransform outAffineTransform)

Populates outAffineTransform with the inverse of this AffineTransform. The same MutableAffineTransform instance can be used as the output to avoid additional allocations. Returns outAffineTransform.

Throws
kotlin.IllegalArgumentException

if the AffineTransform cannot be inverted. .

getValues

Added in 1.0.0-alpha06
public final @Size(min = 6) @NonNull float[] getValues(@Size(min = 6) @NonNull float[] outArray)

Populates the first 6 elements of outArray with the values of this transform, starting with the top left corner of the matrix and proceeding in row-major order.

In performance-sensitive code, prefer to pass in an array that has already been allocated and is being reused, rather than relying on the default behavior of allocating a new instance for each call.

Prefer to apply this transform to an object, such as with applyTransform, rather than accessing the actual numeric values of this transform. This function is useful for when the values are needed in bulk but not to apply a transform, for example for serialization.

To set these values on a transform in the same order that they are retrieved here, use the ImmutableAffineTransform constructor or use MutableAffineTransform.setValues.

isAlmostEqual

Added in 1.0.0-alpha06
public final boolean isAlmostEqual(
    @NonNull AffineTransform other,
    @FloatRange(from = 0.0) float tolerance
)

Compares this AffineTransform with other, and returns true if each component of the transform matrix is within tolerance of the corresponding component of other.

multiply

Added in 1.0.0-alpha06
public static final void multiply(
    @NonNull AffineTransform lhs,
    @NonNull AffineTransform rhs,
    @NonNull MutableAffineTransform output
)

Multiplies the lhs transform by the rhs transform as matrices, and stores the result in output. Note that, when performing matrix multiplication, the lhs transform is applied after the rhs transform; i.e., after calling this method, output contains a transform equivalent to applying rhs, then lhs.

Extension functions

AndroidGraphicsConverter.populateMatrix

public final void AndroidGraphicsConverter.populateMatrix(
    @NonNull AffineTransform receiver,
    @NonNull Matrix out
)

Writes the values from this AffineTransform to out.

Returns the modified Matrix to allow chaining calls.

Returns
void

out

AndroidGraphicsConverter.toMatrix

public final @NonNull Matrix AndroidGraphicsConverter.toMatrix(@NonNull AffineTransform receiver)

Constructs a Matrix with the values from the AffineTransform.

Performance-sensitive code should use the populateMatrix overload that takes a pre-allocated Matrix, so that the instance can be reused across multiple calls.