diff --git a/R/xform.R b/R/xform.R index 4a766445..178052ab 100644 --- a/R/xform.R +++ b/R/xform.R @@ -423,8 +423,12 @@ mirror.neuronlist<-function(x, subset=NULL, OmitFailures=NA, ...){ #' plot(da2pns.R.L, col='blue', add=TRUE) #' } tpsreg<-function(sample, reference, ...){ - structure(list(refmat=data.matrix(sample), tarmat=data.matrix(reference), ...), + reg=structure(list(refmat=data.matrix(sample), tarmat=data.matrix(reference), ...), class='tpsreg') + # precompute forward and reverse + attr(reg,'fwd')=Morpho::computeTransform(x=reg$tarmat, y=reg$refmat, type = "tps", ...) + attr(reg,'rev')=Morpho::computeTransform(x=reg$refmat, y=reg$tarmat, type = "tps", ...) + reg } #' @description \code{xformpoints.tpsreg} enables \code{\link[nat]{xform}} and @@ -436,12 +440,21 @@ tpsreg<-function(sample, reference, ...){ #' @param points The 3D points to transform #' @param swap Whether to change the direction of registration (default of #' \code{NULL} checks if reg has a \code{attr('swap'=TRUE)}) otherwise +#' @param FallBackToAffine,na.action Not applicable to this function #' @export -xformpoints.tpsreg <- function(reg, points, swap=NULL, ...){ - if(isTRUE(swap) || isTRUE(attr(reg, 'swap'))) { - tmp=reg$refmat - reg$refmat=reg$tarmat - reg$tarmat=tmp +xformpoints.tpsreg <- function(reg, points, swap=NULL, FallBackToAffine = NULL, na.action = NULL, ...){ + + dir <- ifelse(isTRUE(swap) || isTRUE(attr(reg, 'swap')), 'rev', 'fwd') + trafo <- attr(reg, dir) + if(is.null(trafo)) { + warning("Incomplete thin plate splines registration!\n", + "I am recomputing, but please use `tpsreg()` to make a new registration") + trafo <- if(dir=='fwd') Morpho::computeTransform(x=reg$tarmat, y=reg$refmat, type = "tps", ...) + else + Morpho::computeTransform(x=reg$refmat, y=reg$tarmat, type = "tps", ...) } - do.call(Morpho::tps3d, c(list(x=points), reg, list(...))) + + Morpho::applyTransform(points, trafo, ...) } + + diff --git a/man/tpsreg.Rd b/man/tpsreg.Rd index 2ae39c72..f5c8c08d 100644 --- a/man/tpsreg.Rd +++ b/man/tpsreg.Rd @@ -7,7 +7,14 @@ \usage{ tpsreg(sample, reference, ...) -\method{xformpoints}{tpsreg}(reg, points, swap = NULL, ...) +\method{xformpoints}{tpsreg}( + reg, + points, + swap = NULL, + FallBackToAffine = NULL, + na.action = NULL, + ... +) } \arguments{ \item{sample, reference}{Matrices defining the sample (or floating) and @@ -21,6 +28,8 @@ reference (desired target after transformation) spaces. See details.} \item{swap}{Whether to change the direction of registration (default of \code{NULL} checks if reg has a \code{attr('swap'=TRUE)}) otherwise} + +\item{FallBackToAffine, na.action}{Not applicable to this function} } \description{ \code{tpsreg} creates an object encapsulating a thin plate spine diff --git a/tests/testthat/test-xformpoints.R b/tests/testthat/test-xformpoints.R index 14cb48c0..dda690df 100644 --- a/tests/testthat/test-xformpoints.R +++ b/tests/testthat/test-xformpoints.R @@ -92,7 +92,7 @@ test_that("Thin plate spine registration", { landmarks=xyz[sids,] #take some points as landmarks landmarkst=scale(xyz[sids,], center = T, scale = rep(1.5, 3)) #now scale the landmarks.. - #compute a transformation with sameple as scaled landmarks and reference as the original landmarks + #compute a transformation with sample as scaled landmarks and reference as the original landmarks mytps=tpsreg(sample=landmarkst, reference = landmarks) kcs20.t=xform(kcs20, mytps)