Nothing
#' Extracting a plane from a volume
#' @description The \code{get.plane} function extracts a plane from a "volume"
#' class object.
#' @param vol "volume" class object.
#' @param origin Vector of x, y, z coordinates, representing the origin of the
#' plane to extract. If \code{interpolate = FALSE}, these coordinates are replaced
#' by the coordinates of the voxel closest to \code{origin}.
#' @param plane.orientation Vector orientation of the plane in the \code{vol}
#' frame of reference, composed by the 2 vectors coordinates of the orthonormal
#' basis of the plane. First vector is x-axis, and second one is y-axis.
#' @param alias \code{$object.alias} of the created object.
#' @param xgrid Vector, representing the grid of the plane abscissa. See note.
#' @param ygrid Vector, representing the grid of the plane ordinates. See note.
#' If \code{ygrid = NULL}, the ordinate is the line intercepting the volume and the
#' step is set to the projection of \code{vol$dxyz} onto the ordinate orientation.
#' @param interpolate Boolean, default to \code{TRUE}.
#' @param method method of interpolation, defaulted to 'NN' ie 'Nearest Neighbor'. See Details.
#' @details The interpolation method is chosen from:
#' \itemize{
#' \item \code{'NN'}: the value of a voxel is calculated from its nearest adajcent neighbors.
#' \item \code{'Av'}: the value of a voxel is the weighted average of
#' the voxels contained in a box, whose sides are automatically calculated from
#' the \code{back.bol$dxyz} steps.
#' }
#' @note \emph{Determination of axes} :
#' \itemize{
#' \item the x-axis has \code{plane.orientation[1:3]} as unit vector.
#' \item the y-axis has \code{plane.orientation[4:6]} as unit vector.
#' \item If \code{xgrid} is not \code{NULL}, \code{origin + x.grid * plane.orientation[1:3]}
#' are the coordinates of the points on the x axis.
#' \item If \code{ygrid} is not \code{NULL}, \code{origin + y.grid * plane.orientation[4:6]}
#' are the coordinates of the points on the y axis.
#' \item If \code{xgrid} or \code{ygrid} are NULL, they are determined to represent
#' as closely as possible the initial volume in the required cut.
#' }
#' @return Returns a "volume" class object, containing only a single plane,
#' at \code{k = 0}, in the same frame of reference as \code{vol}.
#' This returned object has 2 new fields \code{local.xgrid}, and \code{local.ygrid},
#' representing the local grids of the abscissa (columns) and ordinate (rows)
#' of the plane.
#' @return Returns \code{NULL} if plane doesn't exist.
#' @examples
#' # loading of toy-patient objects (decrease dxyz for better result)
#' step <- 4
#' patient <- toy.load.patient(modality = "mr", dxyz = rep (step, 3))
#' MR <- patient$mr[[1]]
#'
#' # mid-volume point
#' mid.point <- apply(get.extreme.pt (MR),1,mean)
#'
#' plane <- get.plane(MR, origin = mid.point, interpolate = TRUE)
#' display.kplane(plane, interpolate = FALSE)
#'
#' plane <- get.plane(MR, origin = mid.point, xgrid = seq (-50, 50, 1),
#' ygrid = seq (-50, 50, 1), interpolate = TRUE)
#' display.kplane(plane, interpolate = FALSE)
#'
#' # 3 points on the inclined plane
#' pts <- t((MR$xyz.from.ijk %*% MR$cube.idx) [1:3 , c (1, 2, 7)])
#' orientation <- orientation.create(A = pts[1,], B = pts[2,], C = pts[3,])
#' origin <- apply(pts, 2, mean)
#' plane <- get.plane(MR, origin = origin,
#' plane.orientation = orientation, interpolate = TRUE)
#' display.kplane(plane, interpolate = FALSE)
#'
#' orientation <- orientation.create(A = c (0, 0, 0) , B = c (1, 1, 0),
#' C = c (-1, 1, 0))
#' plane <- get.plane(MR, origin = origin,
#' plane.orientation = orientation, interpolate = TRUE)
#' display.kplane(plane, interpolate = FALSE)
#' @export
#' @importFrom methods is
get.plane <- function(vol, origin = c(0, 0, 0),
plane.orientation = c(1, 0, 0, 0, 1, 0),
alias = "plane.n",
xgrid = NULL, ygrid = NULL, interpolate = TRUE,
method = c("NN","Av")){
if (is.null(vol)) return(NULL)
if (!is(vol, "volume")) stop("vol should be a volume class object.")
if (is.null(vol$vol3D.data)) stop("empty vol$vol3D.data.")
plane.ref <- "plane.ref"
if (length(plane.orientation) != 6 & length(plane.orientation) != 9)
stop("bad plane.orientation length.")
# If no interpolation is used, we take the closest point that exists within the volume
real.origin <- origin
if (!interpolate) {
idx.c <- which(apply(abs(vol$xyz.from.ijk[1:3,1:3]),2,sum) == 0)
idx.r <- which(apply(abs(vol$xyz.from.ijk[1:3,1:3]),1,sum) == 0)
u <- vol$xyz.from.ijk
if (length(idx.c) > 0) {
u[idx.r,idx.c] <- 1
}
real.origin <- (floor((c(origin,1) %*% t(solve(u))) + 0.5) %*% t(vol$xyz.from.ijk ))[1:3]
}
orientation <- plane.orientation
#if (rev.k) orientation <- c(plane.orientation,-vector.product(plane.orientation[1:3],plane.orientation[4:6]))
t.mat <- ref.add(vol$ref.pseudo, origin = real.origin, orientation = orientation,
new.ref.pseudo = plane.ref)
t.mat$ref.info[t.mat$ref.info$ref.pseudo == vol$ref.pseudo, ]$ref <- vol$frame.of.reference
# TM <- t.mat$matrix.list[[paste(plane.ref,vol$ref.pseudo,sep="<-")]]
v <- vol.in.new.ref(vol, plane.ref, t.mat)
new.dxyz <- v$dxyz
#2D
idx.c <- which(apply(abs(v$xyz.from.ijk[1:3,1:3]),2,sum) == 0)
idx.r <- which(apply(abs(v$xyz.from.ijk[1:3,1:3]),1,sum) == 0)
if (length(idx.c) > 0) {
if (abs(v$xyz0[1,idx.r]) > 1e-6) return(NULL)
u <- v$xyz.from.ijk
u[idx.r,idx.c] <- 1
ijk.from.xyz <- solve(u)
ijk.from.xyz[idx.r,idx.c] <- 0
} else {ijk.from.xyz <- solve(v$xyz.from.ijk)}
# ijk.from.xyz <- solve(v$xyz.from.ijk)
ext.pt <- as.matrix(rbind(get.extreme.pt(v),c(1,1)))
dif.ext.pt <- ext.pt[,2] - ext.pt[,1]
mat <- ijk.from.xyz %*% (ext.pt*matrix(c(1,0,0,1,1,0,0,1), ncol = 2))
ds <- max(abs(mat[,2] - mat[,1]))
if (ds > 0) new.dxyz[1] <- dif.ext.pt[1] / max(abs(mat[,2] - mat[,1]))
mat <- ijk.from.xyz %*% (ext.pt*matrix(c(0,1,0,1,0,1,0,1), ncol = 2))
ds <- max(abs(mat[,2] - mat[,1]))
if (ds > 0) new.dxyz[2] <- dif.ext.pt[2]/max(abs(mat[,2] - mat[,1]))
mat <- ijk.from.xyz %*% (ext.pt*matrix(c(0,0,1,1,0,0,1,1), ncol = 2))
ds <- max(abs(mat[,2] - mat[,1]))
if (ds > 0) new.dxyz[3] <- dif.ext.pt[3]/max(abs(mat[,2] - mat[,1]))
ext.pt <- ext.pt[1:2,] / matrix(new.dxyz[c(1,2,1,2)], ncol = 2)
# round.ext.pt <- round(ext.pt + sign(ext.pt) * 0.5*(abs(ext.pt - round(ext.pt)) > 1e-6))
round.ext.pt <- round(ext.pt - sign(ext.pt) * 0.5*(abs(ext.pt - round(ext.pt)) > 1e-6))
if (is.null(xgrid)) {
# creation of the grid, including the origin point
i.idx <- round.ext.pt[1,1]:round.ext.pt[1,2]
new.grid.i <- i.idx * abs(new.dxyz[1])
if (sign(new.dxyz[1]) == -1) new.grid.i <- rev(new.grid.i)
} else{
new.grid.i <- xgrid
if (length(new.grid.i) > 1) new.dxyz[1] <- new.grid.i[2] - new.grid.i[1]
}
if (is.null(ygrid)) {
j.idx <- round.ext.pt[2,1]:round.ext.pt[2,2]
new.grid.j <- j.idx * abs(new.dxyz[2])
if (sign(new.dxyz[2]) == -1) new.grid.j <- rev(new.grid.j)
} else {
new.grid.j <- ygrid
if (length(new.grid.j) > 1) new.dxyz[2] <- new.grid.j[2] - new.grid.j[1]
}
TM <- get.rigid.M(t.mat,plane.ref, vol$ref.pseudo)
if (all(vector.product(orientation[1:3], orientation[4:6]) == -as.numeric(TM[1:3,3])))
new.dxyz[3] <- -new.dxyz[3]
back.vol <- vol.create(pt000 = c(new.grid.i[1],new.grid.j[1], 0),
dxyz = new.dxyz,
n.ijk = c(length(new.grid.i),length(new.grid.j),1),
ref.pseudo = plane.ref, frame.of.reference = t.mat$ref.info[t.mat$ref.info$ref.pseudo == plane.ref, ]$ref,
alias = alias, number = vol$number, modality = vol$modality, description = vol$description)
new.vol <- vol.regrid(v, back.vol, T.MAT = t.mat, interpolate = interpolate,
alias = alias, verbose = FALSE, method = method)
new.vol$object.alias <- vol$object.alias
new.vol$object.info <- vol$object.info
new.vol <- vol.in.new.ref(new.vol, vol$ref.pseudo, T.MAT = t.mat, alias = alias)
new.vol$local.gridx <- new.grid.i
new.vol$local.gridy <- new.grid.j
return(new.vol)
}
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.