AffineTransform
public abstract class AffineTransform
ImmutableAffineTransform |
An immutable affine transformation in the plane. |
MutableAffineTransform |
A mutable 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.rotateDegrees(45f)
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 |
applyTransform(@NonNull Box box)Returns an |
final @NonNull ImmutableParallelogram |
applyTransform(@NonNull Parallelogram parallelogram)Returns an |
final @NonNull ImmutableVec |
applyTransform(@NonNull Vec point)Returns an |
final @NonNull ImmutableSegment |
applyTransform(@NonNull Segment segment)Returns an |
final @NonNull ImmutableTriangle |
applyTransform(@NonNull Triangle triangle)Returns an |
final @NonNull MutableParallelogram |
applyTransform(Apply the |
final @NonNull MutableParallelogram |
applyTransform(Apply the |
final @NonNull MutableVec |
applyTransform(@NonNull Vec point, @NonNull MutableVec outVec)Apply the |
final @NonNull MutableSegment |
applyTransform(Apply the |
final @NonNull MutableTriangle |
applyTransform(Apply the |
final @NonNull ImmutableAffineTransform |
Returns the inverse of the |
final @NonNull MutableAffineTransform |
computeInverse(@NonNull MutableAffineTransform outAffineTransform)Populates |
final @Size(min = 6) @NonNull float[] |
Populates the first 6 elements of |
final boolean |
isAlmostEqual(Compares this |
static final void |
multiply(Multiplies the |
Extension functions |
|
|---|---|
final void |
AndroidGraphicsConverter.populateMatrix(Writes the values from this |
final @NonNull Matrix |
AndroidGraphicsConverter.toMatrix(@NonNull AffineTransform receiver)Constructs a |
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
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
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
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
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
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
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
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
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
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
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
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 |
computeInverse
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 |
getValues
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
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
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 |
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.