affine_identity
result = affine_identity()
Input: no input · Output: result
What it is
Takes no arguments.
Overloads
One call shape — this function is not overloaded.
| Code | Input | Output | Description |
result = affine_identity() | no input | result Mat | Returns the 3x3 identity Mat — a no-op transform, useful as a composition base case. |
Examples
From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.
img = image_new(20, 20, r=0, g=0, b=0)
shifted = imtranslate(img, 5, 3, fill=255)
scaled = imscale(img, 1.5, fill=0)
imshow(shifted)
M = affine_scale(2, 1.5) * affine_shear(0.2, 0) * affine_identity()
print(shifted.width, scaled.width, M)
20 30 [2, 0.4, 0; 0, 1.5, 0; 0, 0, 1]
from images
How it works
pass, 2026-08-24). Real, composable geometric transforms unified through actual 3x3 homogeneous-coordinate matrices — Qu's OWN */matmul (already dispatching to Matrix::matmul at the matrix boundary — see binop/ matrix_binop above) composes them, not a separate composition mechanism invented for this feature. Convention (the one genuinely easy-to-get-backwards design decision here, pinned down by affine_composition_translate_then_rotate_... in this module's own test suite, below): a point transforms as M @ [x, y, 1]^T. Composing A = affine_translate(...) * affine_rotate(...) * affine_scale(...) and applying A @ p computes translate(rotate(scale(p))) — scale happens FIRST (the rightmost/innermost factor), then rotate, then translate LAST (the leftmost/outermost factor) — the same right-to-left application order as OpenGL's own M = T*R*S convention, not a Qu-specific choice. affine_rotate's matrix is the plain textbook CCW rotation matrix in a standard (x right, y up) coordinate system — deliberately NOT special-cased for image pixel coordinates (y increasing downward), unlike imrotate's own internal sign negation. Applied to image pixel coordinates via imwarp, a positive angle therefore appears CLOCKWISE on screen, not counterclockwise like imrotate — an intentional, documented consequence of keeping this builder mathematically general-purpose (usable for any point transform, not just images) rather than silently flipping its sign to match one particular downstream consumer.
From the note above this builtin in the interpreter, where the reasoning was written down as it was built.