Nothing
#' Affine transformer
#'
#' @param trans_matrix A 3x3 transformation matrix
#' @param x A [wk_trans_affine()]
#' @param dx,dy Coordinate offsets in the x and y direction
#' @param scale_x,scale_y Scale factor to apply in the x and y directions, respectively
#' @param rct_in,rct_out The input and output bounds
#' @param rotation_deg A rotation to apply in degrees counterclockwise.
#' @param src,dst Point vectors of control points used to estimate the affine mapping
#' (using [base::qr.solve()]).
#' @param ... Zero or more transforms in the order they should be applied.
#'
#' @export
#'
wk_trans_affine <- function(trans_matrix) {
new_wk_trans(.Call(wk_c_trans_affine_new, trans_matrix), "wk_trans_affine")
}
#' @export
wk_trans_inverse.wk_trans_affine <- function(trans, ...) {
wk_affine_invert(trans)
}
#' @rdname wk_trans_affine
#' @export
wk_affine_identity <- function() {
wk_affine_translate(0, 0)
}
#' @rdname wk_trans_affine
#' @export
wk_affine_rotate <- function(rotation_deg) {
theta <- -rotation_deg * pi / 180
trans_matrix <- matrix(
c(
cos(theta), +sin(theta), 0,
-sin(theta), cos(theta), 0,
0, 0, 1
),
nrow = 3,
byrow = TRUE
)
wk_trans_affine(trans_matrix)
}
#' @rdname wk_trans_affine
#' @export
wk_affine_scale <- function(scale_x = 1, scale_y = 1) {
wk_trans_affine(matrix(c(scale_x, 0, 0, 0, scale_y, 0, 0, 0, 1), ncol = 3))
}
#' @rdname wk_trans_affine
#' @export
wk_affine_translate <- function(dx = 0, dy = 0) {
wk_trans_affine(matrix(c(1, 0, 0, 0, 1, 0, dx, dy, 1), ncol = 3))
}
#' @rdname wk_trans_affine
#' @export
wk_affine_fit <- function(src, dst) {
src <- as_xy(src)
dst <- as_xy(dst)
n <- length(src)
stopifnot(length(src) == length(dst))
src <- unclass(src)
dst <- unclass(dst)
src_mat <- cbind(src$x, src$y, rep_len(1, n))
dst_mat <- cbind(dst$x, dst$y, rep_len(1, n))
wk_trans_affine(t(qr.solve(src_mat, dst_mat)))
}
#' @rdname wk_trans_affine
#' @export
wk_affine_rescale <- function(rct_in, rct_out) {
# use bbox to sanitize input as rct of length 1
rct_in <- unclass(wk_bbox(rct_in))
rct_out <- unclass(wk_bbox(rct_out))
width_in <- rct_in$xmax - rct_in$xmin
height_in <- rct_in$ymax - rct_in$ymin
width_out <- rct_out$xmax - rct_out$xmin
height_out <- rct_out$ymax - rct_out$ymin
dx <- rct_out$xmin - rct_in$xmin
dy <- rct_out$ymin - rct_in$ymin
wk_affine_compose(
wk_affine_scale(width_out / width_in, height_out / height_in),
wk_affine_translate(dx, dy)
)
}
#' @rdname wk_trans_affine
#' @export
wk_affine_compose <- function(...) {
trans_matrix <- Reduce(
`%*%`,
lapply(rev(list(...)), as.matrix),
init = as.matrix(wk_affine_identity())
)
wk_trans_affine(trans_matrix)
}
#' @rdname wk_trans_affine
#' @export
wk_affine_invert <- function(x) {
wk_trans_affine(solve(as.matrix(x)))
}
#' @export
as.matrix.wk_trans_affine <- function(x, ...) {
.Call(wk_c_trans_affine_as_matrix, x)
}
#' @export
format.wk_trans_affine <- function(x, ...) {
format(as.matrix(x), ...)
}
#' @export
print.wk_trans_affine <- function(x, ...) {
cat("<wk_trans_affine>\n")
print(as.matrix(x), ...)
invisible(x)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.