Nothing
Matrix4 <- R6::R6Class(
classname = "Matrix4",
portable = TRUE,
cloneable = FALSE,
lock_objects = FALSE,
private = list(
.extern_ptr = NULL
),
active = list(
is_matrix4 = function() { TRUE },
pointer = function() { private$.extern_ptr },
elements = function() {
self$to_array()
}
),
public = list(
initialize = function() {
private$.extern_ptr <- Matrix4__new()
},
format = function(...) {
m <- self$to_array()
c(
"<Matrix4>",
utils::capture.output({
print(m)
})
)
},
clone2 = function(...) {
Matrix4$new()$copy(self)
},
set = function(n11, ..., byrow = TRUE) {
if(is.matrix(n11)) {
data <- n11
} else {
data <- matrix(c(n11, ...), nrow = 4, byrow = byrow)
}
if(!is.numeric(data)) {
data <- as.numeric(data)
}
if(length(data) != 16) {
stop("Matrix4$set() requires 16 elements")
}
Matrix4__from_array(private$.extern_ptr, data)
self
},
to_array = function() {
Matrix4__to_array(private$.extern_ptr)
},
identity = function() {
Matrix4__identity(private$.extern_ptr)
self
},
copy = function(m) {
stopifnot(R6::is.R6(m) && isTRUE(m$is_matrix4))
Matrix4__copy(private$.extern_ptr, m$pointer)
self
},
copy_position = function(m) {
m <- as_matrix4(m)
Matrix4__copy_position(private$.extern_ptr, m$pointer)
self
},
extract_basis = function(x_axis = NULL, y_axis = NULL, z_axis = NULL) {
if(is.null(x_axis)) {
x_axis <- new_vector3()
} else {
x_axis <- as_vector3(x_axis)
}
if(is.null(y_axis)) {
y_axis <- new_vector3()
} else {
y_axis <- as_vector3(y_axis)
}
if(is.null(z_axis)) {
z_axis <- new_vector3()
} else {
z_axis <- as_vector3(z_axis)
}
Matrix4__extract_basis(private$.extern_ptr, x_axis$pointer, y_axis$pointer, z_axis$pointer)
self
},
make_basis = function(x_axis = NULL, y_axis = NULL, z_axis = NULL) {
if(is.null(x_axis)) {
x_axis <- new_vector3()
} else {
x_axis <- as_vector3(x_axis)
}
if(is.null(y_axis)) {
y_axis <- new_vector3()
} else {
y_axis <- as_vector3(y_axis)
}
if(is.null(z_axis)) {
z_axis <- new_vector3()
} else {
z_axis <- as_vector3(z_axis)
}
Matrix4__make_basis(private$.extern_ptr, x_axis$pointer, y_axis$pointer, z_axis$pointer)
self
},
extract_rotation = function(m) {
m <- as_matrix4(m)
Matrix4__extract_rotation(private$.extern_ptr, m$pointer)
self
},
look_at = function(eye, target, up) {
eye <- as_vector3(eye)
target <- as_vector3(target)
up <- as_vector3(up)
Matrix4__look_at(private$.extern_ptr, eye$pointer, target$pointer, up$pointer)
self
},
multiply_matrices = function(a, b) {
a <- as_matrix4(a)
b <- as_matrix4(b)
Matrix4__multiply_matrices(private$.extern_ptr, a$pointer, b$pointer)
self
},
multiply = function(m) {
m <- as_matrix4(m)
Matrix4__multiply_matrices(private$.extern_ptr, private$.extern_ptr, m$pointer)
self
},
premultiply = function(m) {
m <- as_matrix4(m)
Matrix4__multiply_matrices(private$.extern_ptr, m$pointer, private$.extern_ptr)
self
},
multiply_scalar = function(scalar) {
if(!is.numeric(scalar)) {
scalar <- as.numeric(scalar[[1]])
} else {
scalar <- scalar[[1]]
}
Matrix4__multiply_scalar(private$.extern_ptr, scalar)
self
},
determinant = function() {
Matrix4__determinant(private$.extern_ptr)
},
transpose = function() {
Matrix4__transpose(private$.extern_ptr)
self
},
set_position = function(v, ...) {
if(R6::is.R6(v) && isTRUE(v$is_vector3)) {
v <- as.numeric(v[,1])
} else {
v <- as.numeric(c(v, ...))[1:3]
}
Matrix4__set_position(private$.extern_ptr, v[[1]], v[[2]], v[[3]])
self
},
invert = function() {
Matrix4__invert(private$.extern_ptr)
self
},
scale = function(v, ...) {
if(!R6::is.R6(v) || !isTRUE(v$is_vector3)) {
v <- as_vector3(c(v, ...))
}
Matrix4__scale(private$.extern_ptr, v$pointer)
self
},
get_max_scale_on_axis = function() {
Matrix4__get_max_scale_on_axis(private$.extern_ptr)
},
make_translation = function(x, y = NULL, z = NULL) {
if(R6::is.R6(x) && isTRUE(x$is_vector3)) {
x <- as.numeric(x[,1])
} else {
x <- as.numeric(c(x, y, z))[1:3]
}
Matrix4__make_translation(private$.extern_ptr, x[[1]], x[[2]], x[[3]])
self
},
make_rotation_x = function(theta) {
theta <- as.double(theta)[[1]]
Matrix4__make_rotation_x(private$.extern_ptr, theta)
self
},
make_rotation_y = function(theta) {
theta <- as.double(theta)[[1]]
Matrix4__make_rotation_y(private$.extern_ptr, theta)
self
},
make_rotation_z = function(theta) {
theta <- as.double(theta)[[1]]
Matrix4__make_rotation_z(private$.extern_ptr, theta)
self
},
make_rotation_axis = function(axis, angle) {
axis <- as_vector3(axis)
angle <- as.double(angle)[[1]]
Matrix4__make_rotation_axis(private$.extern_ptr, axis$pointer, angle)
self
},
make_scale = function(x, y = NULL, z = NULL) {
if(R6::is.R6(x) && isTRUE(x$is_vector3)) {
x <- as.numeric(x[,1])
} else {
x <- as.numeric(c(x, y, z))[1:3]
}
Matrix4__make_scale(private$.extern_ptr, x[[1]], x[[2]], x[[3]])
self
},
make_shear = function(xy, xz, yx, yz, zx, zy) {
xy <- as.double(xy)[[1]]
xz <- as.double(xz)[[1]]
yx <- as.double(yx)[[1]]
yz <- as.double(yz)[[1]]
zx <- as.double(zx)[[1]]
zy <- as.double(zy)[[1]]
Matrix4__make_shear(private$.extern_ptr, xy, xz, yx, yz, zx, zy)
self
},
make_perpective = function(left, right, top, bottom, near, far) {
left <- as.double(left)[[1]]
right <- as.double(right)[[1]]
top <- as.double(top)[[1]]
bottom <- as.double(bottom)[[1]]
near <- as.double(near)[[1]]
far <- as.double(far)[[1]]
Matrix4__make_perspective(private$.extern_ptr, left, right, top, bottom, near, far)
self
},
make_orthographic = function(left, right, top, bottom, near, far) {
left <- as.double(left)[[1]]
right <- as.double(right)[[1]]
top <- as.double(top)[[1]]
bottom <- as.double(bottom)[[1]]
near <- as.double(near)[[1]]
far <- as.double(far)[[1]]
Matrix4__make_orthographic(private$.extern_ptr, left, right, top, bottom, near, far)
self
}
)
)
#' Create a \code{Matrix4} instance for \code{'Affine'} transform
#' @param m a matrix or a vector to be converted to the \code{Matrix4} instance;
#' \code{m} must be one of the followings: for matrices, the dimension must be
#' \code{4x4}, \code{3x4} (the last row will be \code{0 0 0 1}), or
#' \code{3x3} (linear transform); for vectors, the length must be
#' \code{16}, \code{12} (will append \code{0 0 0 1} internally),
#' \code{3} (translation), or \code{1} (scale).
#' @returns A \code{Matrix4} instance
#' @seealso \code{\link{new_vector3}}, \code{\link{new_quaternion}}
#' @export
new_matrix4 <- function() {
Matrix4$new()
}
#' @export
as.matrix.Matrix4 <- function(x, ...) {
if(R6::is.R6(x) && isTRUE(x$is_matrix4)) {
return(x$to_array())
}
NextMethod("as.matrix")
}
#' @export
`[.Matrix4` <- function(x, i, ..., drop = TRUE) {
if(missing(i)) {
x$to_array()[, ..., drop = drop]
} else {
x$to_array()[i, ..., drop = drop]
}
}
#' @export
dim.Matrix4 <- function(x) {
if(R6::is.R6(x) && isTRUE(x$is_matrix4)) {
return(c(4L, 4L))
}
NextMethod("dim")
}
#' @export
`==.Matrix4` <- function(e1, e2) {
e2 == e1$to_array()
}
#' @rdname new_matrix4
#' @export
as_matrix4 <- function(m) {
if(R6::is.R6(m) && isTRUE(m$is_matrix4)) { return(m) }
if(is.matrix(m)) {
nc <- ncol(m)
nr <- nrow(m)
if(!nc %in% c(3, 4)) {
stop("`as_matrix4`: when input `m` is a matrix, its column numbers must be 3 or 4")
}
if(!nr %in% c(3, 4)) {
stop("`as_matrix4`: when input `m` is a matrix, its row numbers must be 3 or 4")
}
if( nc == 3 && nr == 3 ) {
m <- cbind(rbind(m, c(0, 0, 0)), c(0, 0, 0, 1))
} else if ( nc == 3 ) {
m <- cbind(m, c(0, 0, 0, 1))
} else if ( nr == 3 ){
m <- rbind(m, c(0, 0, 0, 1))
}
return(new_matrix4()$set(m))
}
m <- as.numeric(m)
if(length(m) == 12) {
m <- c(m, 0, 0, 0, 1)
} else if(length(m) == 3) {
m <- matrix(c(
1,0,0,m[[1]],
0,1,0,m[[2]],
0,0,1,m[[3]],
0,0,0,1
), nrow = 4, byrow = TRUE)
return(new_matrix4()$set(m))
}
new_matrix4()$set(m)
}
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.