Nothing
#' @name bin.cuboid
#' @aliases bin.cylinder
#' @aliases bin.ellipsoid
#' @title Create a volume containing predefined shapes
#' @description These functions create espadon objects of class “volume”, and
#' of modality “binary” or “weight”, by selecting the voxels defining a rectangular
#' cuboid, an elliptical cylinder or an ellipsoid.
#' @param back.vol "volume" class object.
#' @param side Numerical vector of length 3, representing the length, width and height of the cuboid.
# @param pt.min,pt.max Minimum and maximum x, y, z coordinates of the vertices
# of the rectangular cuboid.
#' @param center Numeric vector of length 3, representing the xyz-center of the
#' shape, in the \code{back.vol} frame of reference.
#' @param radius Positive number, or xy-vector or xyz-vector of 2 or 3 positive
#' numbers, representing the radius of the cylinder or the ellipsoid.
#' @param height Positive number representing the height of the cylinder.
#' @param orientation Numerical vector of length 6, specifying the coordinates of
#' the 2 vectors making up the shape base.
#' @param modality modality ("binary" or "weight") of the generated object.
#' @param alias Character string, \code{$alias} of the created object.
#' @param description Character string, describing the created object.
#' @param ... Additional arguments.
#' @return Returns a "volume" class object of "binary" or "weight" modality (see
#' \link[espadon]{espadon.class} for class definitions), with the same grid as
#' \code{back.vol}.
#' \itemize{
#' \item In the “binary” modality, voxels with 50 percent of their volume within
#' the requested shape are set to \code{TRUE}.
#' \item In the “weight” modality, the value of each voxel is its volume fraction
#' included in the requested shape.
#' }
#' @seealso \link[espadon]{add.shape}
#' @examples
#' # Creation of back.vol
#' CT <- vol.create (c(80, 80,40), c(1.2, 1.2, 2),
#' pt000 = c(-50.4,-50.4,-39), modality = "ct",
#' default.value = as.integer(-997), value.sd = 1)
#'
#' # Creation of a cuboid
#' cuboid <- bin.cuboid(CT, side = c(29.7, 20.0, 20.2),
#' center = c(-10.9, -20.4, -10.6))
#'
#' # Creation of a cylinder
#' cylinder <- bin.cylinder(CT, center =c(10.3, 15.6, 0.7),
#' radius = c(10, 20), height = 50,
#' orientation = c(0.5150381, 0.7423287, 0.4285837,
#' -0.8571673, 0.4460361, 0.2575190))
#'
#' # Creation of an ellipsoid
#' ellipsoid <- bin.ellipsoid(CT, center = c(-20.1, 0.1, 5),
#' radius = c(3.3, 6.2, 5.3))
#'
#' # Display
#' k.idx <- unique(which(cuboid$vol3D.data>0, arr.ind = TRUE)[,3]) - 1
#' display.3D.stack(cuboid, k.idx, border = FALSE,
#' col = c("#FFFFFF00", "#EBDFDFFF", "#D8BFBFFF", "#C59F9FFF",
#' "#B27F7FFF", "#9F5F5FFF", "#8C3F3FFF", "#791F1FFF",
#' "#660000FF"))
#'
#' k.idx <- unique(which(cylinder$vol3D.data>0, arr.ind = TRUE)[,3]) - 1
#' display.3D.stack(cylinder, k.idx, border = FALSE,
#' col = c("#FFFFFF00", "#DFEBDFFF", "#BFD8BFFF", "#9FC59FFF",
#' "#7FB27FFF", "#5F9F5FFF", "#3F8C3FFF", "#1F791FFF",
#' "#006600FF"))
#'
#' k.idx <- unique(which(ellipsoid$vol3D.data>0, arr.ind = TRUE)[,3]) - 1
#' display.3D.stack(ellipsoid, k.idx, border = FALSE,
#' col = c("#FFFFFF00", "#DFDFEBFF", "#BFBFD8FF", "#9F9FC5FF",
#' "#7F7FB2FF", "#5F5F9FFF", "#3F3F8CFF", "#1F1F79FF",
#' "#000066FF"))
#' @export
bin.cuboid <- function(back.vol, side=c(10,10,10), center= c(0,0,0), orientation = c(1,0,0,0,1,0),
modality ="weight", alias = "", description = NULL,...){
args_ <- tryCatch(list(...), error = function(e)list())
pt.min <- args_[["pt.min"]]
pt.max <- args_[["pt.max"]]
# up to version 1.8.0
if (!is.null(pt.min) & !is.null(pt.max)){
if (length(pt.min)!=3 | length(pt.max)!=3) stop ("pt.min and pt.max must be numerical vectors of length 3.")
center <- pt.min + pt.max
side <- pt.max - pt.min
} else {
if (length(center)!=3) stop ("Center must be numerical vectors of length 3.")
if (length(side)!=3 & length(side)!=1) stop ("side must be numerical vectors of length 1 or 3.")
side <- rep(side,3)[1:3]
}
if (any(side<1e-6)) stop("The sides of the cuboid must not be less than or equal to zero")
ref.shape <- args_[["ref.shape"]]
t.mat <- args_[["T.MAT"]]
if (!is.null(ref.shape)){
M <- get.rigid.M(t.mat,ref.shape, back.vol$ref.pseudo)
if (is.null(M))
stop("Instead of ref.shape, define the orientation of the cuboid")
t.mat$matrix.list[[paste0(,"<-",ref.shape)]][1:3,4] <- center
t.mat$matrix.list[[paste0(ref.shape,"<-",back.vol$ref.pseudo)]] <- solve(t.mat$matrix.list[[paste0(back.vol$ref.pseudo,"<-",ref.shape)]])
}else{
ref.shape <- paste0(back.vol$ref.pseudo,"r")
t.mat <- ref.add (back.vol$ref.pseudo, orientation = orientation,
origin = center,
new.ref.pseudo = ref.shape,
T.MAT = NULL)
}
args <- list()
args[["back.vol"]] <- back.vol
args[["pt.min"]] <- (-side/2)
args[["pt.max"]] <- (+side/2)
args[["ref.shape"]] <- ref.shape
args[["T.MAT"]] <- t.mat
args[["modality"]] <- modality[1]
args[["alias"]] <- alias
args[["description"]] <- description
args[["shape"]] <- "cuboid"
if (is.null(description)) {
if (length(unique(side))==1) {description <- paste(side[1], "mm square cube")
} else {description <- paste0("rectangular cuboid with (", paste(side, collapse=","), ") mm sides")}
}
do.call(bin.shape, args)
}
#' @rdname bin.cuboid
#' @export
bin.cylinder <- function(back.vol, center, radius, height, orientation = c(1,0,0,0,1,0),
modality ="weight", alias = "", description = NULL,...){
args_ <- tryCatch(list(...), error = function(e)list())
ref.shape <- args_[["ref.shape"]]
t.mat <- args_[["T.MAT"]]
if (!is.null(ref.shape)){
M <- get.rigid.M(t.mat,ref.shape, back.vol$ref.pseudo)
if (is.null(M))
stop("Instead of ref.shape, define the orientation of the cuboid")
t.mat$matrix.list[[paste0(,"<-",ref.shape)]][1:3,4] <- center
t.mat$matrix.list[[paste0(ref.shape,"<-",back.vol$ref.pseudo)]] <- solve(t.mat$matrix.list[[paste0(back.vol$ref.pseudo,"<-",ref.shape)]])
}else{
ref.shape <- paste0(back.vol$ref.pseudo,"r")
t.mat <- ref.add (back.vol$ref.pseudo, orientation = orientation,
origin = center,
new.ref.pseudo = ref.shape,
T.MAT = NULL)
}
if (length(radius)>2) stop ("radius must be a numerical vector of length 1 or 2.")
args <- list()
args[["back.vol"]] <- back.vol
args[["center"]] <- c(0,0,0)
args[["radius"]] <- abs(rep(radius,2)[1:2])
args[["height"]] <- abs(height[1])
args[["ref.shape"]] <- ref.shape
args[["T.MAT"]] <- t.mat
args[["modality"]] <- modality[1]
args[["alias"]] <- alias
args[["description"]] <- description
args[["shape"]] <- "cylinder"
if (is.null(description)) {
if (length(unique(args[["radius"]] ))==1) {description <- paste("cylinder with ", args[["radius"]][1],
"mm radius and ", args[["height"]], "mm height")
} else {description <- paste0("cylinder with radius (", paste(args[["radius"]], collapse=","), ") mm and height ",
args[["height"]], " mm" )}
}
do.call(bin.shape, args)
}
#' @rdname bin.cuboid
#' @export
bin.ellipsoid <- function(back.vol, center, radius, orientation = c(1,0,0,0,1,0),
modality ="weight", alias = "", description = NULL,...){
args_ <- tryCatch(list(...), error = function(e)list())
ref.shape <- args_[["ref.shape"]]
t.mat <- args_[["T.MAT"]]
if (!is.null(ref.shape)){
M <- get.rigid.M(t.mat,ref.shape, back.vol$ref.pseudo)
if (is.null(M))
stop("Instead of ref.shape, define the orientation of the cuboid")
t.mat$matrix.list[[paste0(,"<-",ref.shape)]][1:3,4] <- center
t.mat$matrix.list[[paste0(ref.shape,"<-",back.vol$ref.pseudo)]] <- solve(t.mat$matrix.list[[paste0(back.vol$ref.pseudo,"<-",ref.shape)]])
}else{
ref.shape <- paste0(back.vol$ref.pseudo,"r")
t.mat <- ref.add (back.vol$ref.pseudo, orientation = orientation,
origin = center,
new.ref.pseudo = ref.shape,
T.MAT = NULL)
}
if (length(radius)>3) stop ("radius must be a numerical vector of length less than 3.")
args <- list()
args[["back.vol"]] <- back.vol
args[["center"]] <- c(0,0,0)
args[["radius"]] <- abs(c(radius,rep(radius[length(radius)],2)))[1:3]
args[["ref.shape"]] <- ref.shape
args[["T.MAT"]] <- t.mat
args[["modality"]] <- modality[1]
args[["alias"]] <- alias
if (is.null(description)) {
if (length(unique(args[["radius"]] ))==1) {description <- paste(args[["radius"]][1], "mm radius sphere")
} else {description <- paste0("ellipsoid of radius (", paste(args[["radius"]], collapse=","), ") mm")}
}
args[["description"]] <- description
args[["shape"]] <- "ellipsoid"
args[["error"]] <- args_[["error"]]
do.call(bin.shape, args)
}
bin.shape <- function(back.vol, shape, ref.shape = back.vol$ref.pseudo, T.MAT = NULL,
modality ="weight", alias = "", description = NULL, ...) {
args <- tryCatch(list(...), error = function(e)list())
if (!is (back.vol, "volume"))
stop ("back.vol should be a volume class object.", call.=FALSE)
rigid.M <- get.rigid.M (T.MAT, src.ref = ref.shape, dest.ref = back.vol$ref.pseudo)
if (is.null(rigid.M))
stop("back.vol and the box do not have the same frame of reference: define a valid T.MAT", call.=FALSE)
if (is.null(description)) description <- args[["shape"]]
vol.out <- vol.copy (back.vol, alias = alias, modality=modality, description=description)
vol.out$vol3D.data[] <- 0
vol.out$min.pixel <- 0
vol.out$max.pixel <- 0
#2D
idx.c <- which(apply(abs(back.vol$xyz.from.ijk[1:3,1:3]),2,sum)==0)
idx.r <- which(apply(abs(back.vol$xyz.from.ijk[1:3,1:3]),1,sum)==0)
if (length(idx.c)>0) {
if (abs(back.vol$xyz0[1,idx.r])>1e-6) return(NULL)
u <- back.vol$xyz.from.ijk
u[idx.r,idx.c]<- 1
ijk.from.shape <- solve(u)
ijk.from.shape[idx.r,idx.c] <- 0
} else {#3D
ijk.from.shape <- solve(back.vol$xyz.from.ijk)}
ijk.from.shape <- ijk.from.shape %*% rigid.M
shape.from.ijk <- get.rigid.M (T.MAT, src.ref=back.vol$ref.pseudo, dest.ref = ref.shape) %*% back.vol$xyz.from.ijk
# on crée un volume avec un pas au plus proche de back.vol
p <- abs(shape.from.ijk %*% cbind(c(1,0,0,0),c(0,1,0,0), c(0,0,1,0)))
Vb.dxyz <- apply(p[1:3,],1,max)
Vb.pt000 <- (apply(shape.from.ijk %*% back.vol$cube.idx,1,range))[,1:3]
Vb.n.ijk <- ceiling((Vb.pt000[2,]- Vb.pt000[1,])/Vb.dxyz + 1)
Vb <- vol.create(n.ijk = Vb.n.ijk, dxyz = Vb.dxyz, modality ="weight",pt000 = Vb.pt000[1,],
default.value = 0,ref.pseudo = ref.shape)
if (shape == "cuboid"){
pt.min <- args[["pt.min"]]
pt.max <- args[["pt.max"]]
base_m <- matrix(c(pt.min, pt.min[1],pt.max[2],pt.min[3], pt.max[1:2],
pt.min[3],pt.max[1],pt.min[2:3],pt.min), ncol = 3, byrow = TRUE)
base_M <- base_m
base_M[,3] <- pt.max[3]
# on regarde à quelle indice de Vb correpond les points du struct
Mat <- solve (Vb$xyz.from.ijk)
base_m.ijk <- cbind(base_m,1) %*% t(Mat)
base_M.ijk <- cbind(base_M,1) %*% t(Mat)
range.s <- t(apply(rbind(base_m.ijk[,1:3],base_M.ijk[,1:3]),2,range))
range.s <- cbind(floor(range.s[,1]),ceiling(range.s[,2]))
vol3D.range <- cbind( c(range.s[1,1]-1,max(range.s[2,1]-1,-1),max(range.s[3,1],0)),
apply(cbind(range.s[,2]+1, Vb$n.ijk - 1),1,min))
common.range <- vol3D.range
common.range[,1] <-apply(cbind(range.s[,1], c(0,0,0)),1,max)
common.range[,2] <- apply(cbind(range.s[,2], Vb$n.ijk - 1),1,min)
if (any(common.range[,1]>common.range[,2])) return (vol.out)
vol3D.nijk <-vol3D.range[,2]-vol3D.range[,1] +1
vol3D <- array(0,dim = vol3D.nijk)
base_ijk <- base_m.ijk[, 1:3]
base_ijk[,3] <- vol3D.range[3,1]
u <- base_ijk[2:5,1:3]-base_ijk[1:4,1:3]
dist.u<- sqrt(u[,1]^2 +u[,2]^2 + u[,3]^2)
u[ ,1] <- u[ ,1]/dist.u;
u[ ,2] <- u[ ,2]/dist.u;
pO <- sweep(base_ijk[,1:3] ,2,vol3D.range[,1])
vol3D_ <- array(.ouline2voxC(as.numeric(t(u)),c(vol3D.nijk[1:2],1) , 0, 0, as.numeric(t(pO[1:4, ])),
lambda_max = dist.u, ntab = sum(ceiling(dist.u)+5)),dim=c(vol3D.nijk[1:2],1))
vol3D_[vol3D_>1] <- 1
vol3D_[vol3D_<0] <- 0
rg.k <- vol3D.range[3,1]:vol3D.range[3,2]
k.min <- floor(base_m.ijk[1,3] + 0.5)
k.max <- floor(base_M.ijk[1,3] + 0.5)
vol3D[,,(k.min:k.max)-vol3D.range[3,1] + 1] <- vol3D_[,,rep(1,k.max-k.min + 1)]
if (k.min == k.max){
vol3D[,,k.min-vol3D.range[3,1] + 1] <- vol3D[,,k.min-vol3D.range[3,1] + 1] * (base_M.ijk[1,3]- base_m.ijk[1,3])
}else{
vol3D[,,k.min-vol3D.range[3,1] + 1] <- vol3D[,,k.min-vol3D.range[3,1] + 1] * (k.min + 0.5 - base_m.ijk[1,3])
vol3D[,,k.max-vol3D.range[3,1] + 1] <- vol3D[,,k.max-vol3D.range[3,1] + 1] * (base_M.ijk[1,3] - k.max + 0.5)
}
} else if (shape == "cylinder") {
Rijk <- args[["radius"]]/Vb$dxyz[1:2]
H <- args[["height"]]/Vb$dxyz[3]
Cijk <-get.ijk.from.xyz(args[["center"]],Vb)
x.breaks <- floor(Cijk[1]-Rijk[1]):(ceiling(Cijk[1]+Rijk[1]) +1) - 0.5 #0:Vb$n.ijk[1] - 0.5
y.breaks <- floor(Cijk[2]-Rijk[2]):(ceiling(Cijk[2]+Rijk[2]) +1) - 0.5
costheta <- (x.breaks-Cijk[1])/Rijk[1]
sintheta <- (y.breaks-Cijk[2])/Rijk[2]
fx <- abs(costheta) <=1
fy <- abs(sintheta) <=1
costheta <- costheta[fx]
x.breaks <- x.breaks[fx]
x.theta <- acos(costheta)
x.theta <- (c(2*pi-x.theta,x.theta) + 2*pi) %% (2*pi)
sintheta <- sintheta[fy]
y.breaks <- y.breaks[fy]
y.theta <- asin(sintheta)
y.theta <- (c(pi-y.theta,y.theta) + 2*pi) %% (2*pi)
theta <- sort(unique (c(x.theta, y.theta)),decreasing = TRUE)
theta <- c(theta,theta[1]-2*pi)
vol3D.range <- cbind( c(x.breaks[1]-1.5, max(y.breaks[1]-1.5,-1),floor(Cijk[3]-H/2) -1),
apply(cbind(c(x.breaks[length(x.breaks)]+0.5,
y.breaks[length(y.breaks)]+0.5,
ceiling(Cijk[3]+H/2)+1), Vb$n.ijk - 1),1,min))
common.range <- vol3D.range
common.range[,1] <-apply(cbind(common.range[,1], c(0,0,0)),1,max)
common.range[,2] <- apply(cbind(common.range[,2], Vb$n.ijk - 1),1,min)
le <- length(theta)
if (any(common.range[,1]>common.range[,2]) | le==1) return (vol.out)
vol3D.nijk <-vol3D.range[,2]-vol3D.range[,1] +1
vol3D <- array(0,dim = vol3D.nijk)
O_ijk <-cbind(Rijk[1]*cos(theta) + Cijk[1] - vol3D.range[1,1],
Rijk[2]*sin(theta) + Cijk[2] - vol3D.range[2,1],
0)
mid.theta <- 0.5*(theta[1:(le-1)] + theta[2:le])
pt <- floor(cbind(Rijk[1]*cos(mid.theta) + Cijk[1] - vol3D.range[1,1],
Rijk[2]*sin(mid.theta) + Cijk[2] - vol3D.range[2,1],
0)+0.5) + 1
u <- O_ijk[2:le, ] - O_ijk[1:(le-1), ]
dist.u<- sqrt(u[,1]^2 +u[,2]^2 + u[,3]^2)
u[ ,1] <- u[ ,1]/dist.u;
u[ ,2] <- u[ ,2]/dist.u;
vol3D_ <- array(.ouline2voxC(as.numeric(t( u)),c(vol3D.nijk[1:2],1) , 0, 0, as.numeric(t(O_ijk[1:(le-1), ])),
lambda_max = dist.u, ntab = sum(ceiling(dist.u)+5)),dim=c(vol3D.nijk[1:2],1))
theta_ <- theta
f <- cos(theta)!=0
theta_[f] <- atan(Rijk[2] * tan(theta[f])/ Rijk[1])
S.triangle <- 0.5*abs(Rijk[1] * Rijk[2] * sin(diff(theta)))
zone <- theta /(pi/2)
f <- round(zone) == zone
S.ellipse <- (as.integer(zone) + (as.integer(zone) %% 2)) * Rijk[1]*Rijk[2]*pi * 0.25
S.ellipse[!f] <- S.ellipse[!f] + 0.5*Rijk[1]*Rijk[2]* atan(tan(theta_[!f])*Rijk[1]/Rijk[2])
pt <- cbind(pt,abs(diff(S.ellipse)) - S.triangle)
tab<- as.matrix(do.call (rbind,by(pt, pt[,1]+ 1i*pt[,2],function(tab) cbind(tab[1,1:3],sum(tab[,4])))))
f <- (tab[,3] == 1) & (tab[,2] >0) & (tab[,1] >0) & (tab[,2] <= vol3D.nijk[2]) & (tab[,1] <= vol3D.nijk[1])
vol3D_[tab[f,1:3 ]] <- vol3D_[tab[f,1:3]] + tab[f,4]
vol3D_[vol3D_>1] <- 1
vol3D_[vol3D_<0] <- 0
rg.k <- vol3D.range[3,1]:vol3D.range[3,2]
k.min <- floor(Cijk[3]-H/2 + 0.5)
k.max <- floor(Cijk[3]+H/2 + 0.5)
vol3D[,,(k.min:k.max)-vol3D.range[3,1] + 1] <- vol3D_[,,rep(1,k.max-k.min + 1)]
if (k.min == k.max){
vol3D[,,k.min-vol3D.range[3,1] + 1] <- vol3D[,,k.min-vol3D.range[3,1] + 1] * H
}else{
vol3D[,,k.min-vol3D.range[3,1] + 1] <- vol3D[,,k.min-vol3D.range[3,1] + 1] * (k.min + 0.5 - (Cijk[3]-H/2))
vol3D[,,k.max-vol3D.range[3,1] + 1] <- vol3D[,,k.max-vol3D.range[3,1] + 1] * (Cijk[3]+H/2 - k.max + 0.5)
}
} else if (shape == "ellipsoid"){
#------------------------------
Rijk <- args[["radius"]]/Vb$dxyz
Cijk <-get.ijk.from.xyz(args[["center"]],Vb)
k.min <- floor(Cijk[3] - Rijk[3])
k.max <- ceiling(Cijk[3] + Rijk[3])
samp.nb <- -1
error_abs <- +Inf
error_rel <- +Inf
error_rel0 <- args[["error"]]
if (!is.numeric(error_rel0)) error_rel0 <- 0.01
error_rel0 <- abs(error_rel0[1])
error_abs0 <- error_rel0/10/( pi*Rijk[1]*Rijk[2])
cat(error_rel0,error_abs0)
(abs(error_abs*pi*Rijk[1]*Rijk[2])> error_abs0)
while(((abs(error_rel) > error_rel0) & (abs(error_abs*pi*Rijk[1]*Rijk[2])> error_abs0))& ((k.max - k.min+1) * samp.nb < 500)){
samp.nb <- samp.nb + 2
mid.samp <- floor(0.5*samp.nb)
rg.k <- seq(k.min - mid.samp/samp.nb,k.max + mid.samp/samp.nb,1/samp.nb)
sinphi <- (rg.k - Cijk[3])/Rijk[3]
fz <- abs(sinphi) < 1
error_abs <- sum(1-sinphi[fz]^2)/samp.nb - (4*Rijk[3]/3)
error_rel <- 100 * error_abs /(4*Rijk[3]/3)
}
cat(abs(error_rel))
cat(abs(error_abs*pi*Rijk[1]*Rijk[2]))
cosphi <- suppressWarnings(sqrt(1-sinphi^2))
x.breaks <- floor(Cijk[1] - Rijk[1]):(ceiling(Cijk[1]+Rijk[1]) +1) - 0.5 #0:Vb$n.ijk[1] - 0.5
y.breaks <- floor(Cijk[2] - Rijk[2]):(ceiling(Cijk[2]+Rijk[2]) +1) - 0.5
vol3D.range <- rbind(c(x.breaks[1]+0.5, x.breaks[length(x.breaks)]-0.5),
c(y.breaks[1]+0.5, y.breaks[length(y.breaks)]-0.5),c(k.min,k.max))
common.range <- vol3D.range
common.range[,1] <-apply(cbind(common.range[,1], c(0,0,0)),1,max)
common.range[,2] <- apply(cbind(common.range[,2], Vb$n.ijk - 1),1,min)
if (any(common.range[,1]>common.range[,2])) return (vol.out)
vol3D.nijk <-vol3D.range[,2]-vol3D.range[,1] +1
vol3D.nijk[3] <- vol3D.nijk[3] * samp.nb
vol3D <- array(0,dim = vol3D.nijk)
O_ijk <- dist.u <- u <- list()
for (cp.idx in which(fz)){
costheta <- (x.breaks-Cijk[1])/Rijk[1]/cosphi[cp.idx]
sintheta <- (y.breaks-Cijk[2])/Rijk[2]/cosphi[cp.idx]
x.theta <- acos(costheta[abs(costheta)<=1])
x.theta <- (c(2*pi-x.theta,x.theta) + 2*pi) %% (2*pi)
y.theta <- asin(sintheta[abs(sintheta)<=1])
y.theta <- (c(pi-y.theta,y.theta) + 2*pi) %% (2*pi)
theta <- sort(unique (c(x.theta, y.theta)),decreasing = TRUE)
theta <- c(theta,theta[1]-2*pi)
le <- length(theta)
if (le>1){
O_ijk[[cp.idx]] <-cbind(Rijk[1]*cosphi[cp.idx]*cos(theta) + Cijk[1] - vol3D.range[1,1],
Rijk[2]*cosphi[cp.idx]*sin(theta) + Cijk[2] - vol3D.range[2,1],
cp.idx -1)
mid.theta <- 0.5*(theta[1:(le-1)] + theta[2:le])
pt <- floor(cbind(Rijk[1]*cosphi[cp.idx]*cos(mid.theta) + Cijk[1] - vol3D.range[1,1],
Rijk[2]*cosphi[cp.idx]*sin(mid.theta) + Cijk[2]- vol3D.range[2,1],
cp.idx-1)+0.5) + 1
u[[cp.idx]] <- O_ijk[[cp.idx]][2:le, ] - O_ijk[[cp.idx]][1:(le-1), ]
dist.u[[cp.idx]] <- sqrt(u[[cp.idx]][,1]^2 +u[[cp.idx]][,2]^2 + u[[cp.idx]][,3]^2)
u[[cp.idx]][ ,1] <- u[[cp.idx]][ ,1]/dist.u[[cp.idx]];
u[[cp.idx]][ ,2] <- u[[cp.idx]][ ,2]/dist.u[[cp.idx]];
theta_ <- theta
f <- cos(theta)!=0
theta_[f] <- atan(Rijk[2] * tan(theta[f])/ Rijk[1] )
S.triangle <- 0.5*abs(Rijk[1] * Rijk[2] * sin(diff(theta)))
zone <- theta /(pi/2)
f <- round(zone) == zone
S.ellipse <- (as.integer(zone) + (as.integer(zone) %% 2)) * Rijk[1]*Rijk[2]*pi * 0.25
S.ellipse[!f] <- S.ellipse[!f] + 0.5*Rijk[1]*Rijk[2]* atan(tan(theta_[!f])*Rijk[1]/Rijk[2])
pt <- cbind(pt,(abs(diff(S.ellipse)) - S.triangle) * cosphi[cp.idx]^2)
ptijk <- unique(pt[,1:3])
ptijk <- cbind(ptijk, sapply(1:nrow(ptijk),function(idx)
sum(pt[ptijk[idx,1]==pt[,1] & ptijk[idx,2]==pt[,2],4])))
vol3D [ptijk[,1:3]] <- ptijk[,4]
O_ijk[[cp.idx]] <- O_ijk[[cp.idx]][1:(le-1),]
# vol3D <- vol3D +
# array(.ouline2voxC(as.numeric(t( u[[cp.idx]])),vol3D.nijk , 0:(vol3D.nijk[3]-1),
# 0:(vol3D.nijk[3]-1),as.numeric(t( O_ijk[[cp.idx]] )),
# lambda_max = dist.u[[cp.idx]], ntab = sum(ceiling(dist.u[[cp.idx]])+5)),dim=vol3D.nijk)
# print(sum(vol3D[,,O_ijk[[cp.idx]][1,3] + 1]) - pi*Rijk[1]*Rijk[2]* cosphi[cp.idx]^2)
}
}
dist.u <- unlist(dist.u)
O_ijk <- do.call(rbind,O_ijk)
u <- do.call(rbind,u)
vol3D <- vol3D + array(.ouline2voxC(as.numeric(t( u)),vol3D.nijk , 0:(vol3D.nijk[3]-1),
0:(vol3D.nijk[3]-1),as.numeric(t(O_ijk)),
lambda_max = dist.u, ntab = sum(ceiling(dist.u)+5)),dim=vol3D.nijk)
sm <- 1:(k.max-k.min + 1)*samp.nb- samp.nb + 1
for(idx in (0:(samp.nb-1))[-1]) vol3D[,,sm] <- vol3D[,,sm] + vol3D[,,sm+idx]
vol3D <- vol3D[,,sm]/samp.nb
}
rgi <- (common.range[1,1]:common.range[1,2])
rgj <- (common.range[2,1]:common.range[2,2])
rgk <- (common.range[3,1]:common.range[3,2])
Vb$vol3D.data[ rgi + 1, rgj + 1, rgk + 1] <-
vol3D[ rgi-vol3D.range[1,1]+1, rgj-vol3D.range[2,1]+1, rgk-vol3D.range[3,1]+1]
# Vb$max.pixel <- max(Vb$vol3D.data, na.rm=TRUE)
# Vb$min.pixel <- min(Vb$vol3D.data, na.rm=TRUE)
# display.3D.stack(Vb,Vb$k.idx, border =F)
# rgl::bg3d("black")
if ((all (abs(vol.out$xyz.from.ijk - Vb$xyz.from.ijk) < 1e-6)) & all(rigid.M==diag(4))) {
vol.out$vol3D.data[rgi + 1, rgj + 1, rgk + 1] <- Vb$vol3D.data[rgi + 1, rgj + 1, rgk + 1]
vol.out$vol3D.data[rgi + 1, rgj + 1, rgk + 1][vol.out$vol3D.data[rgi + 1, rgj + 1, rgk + 1] >1] <- 1
vol.out$vol3D.data[rgi + 1, rgj + 1, rgk + 1][vol.out$vol3D.data[rgi + 1, rgj + 1, rgk + 1] <0] <- 0
vol.out$max.pixel <- max(vol.out$vol3D.data[rgi + 1, rgj + 1, rgk + 1], na.rm=TRUE)
vol.out$min.pixel <- min(vol.out$vol3D.data[rgi + 1, rgj + 1, rgk + 1], na.rm=TRUE)
} else {
f <-common.range[,1]>1
common.range[f,1] <- common.range[f,1]-1
f <-common.range[,2]< Vb$n.ijk -1
common.range[f,2] <- common.range[f,2]+1
cube.idx <- Vb$cube.idx
cube.idx [1,] <- common.range[1,c(1,2,2,1,1,2,2,1)]
cube.idx [2,] <- common.range[2,c(1,1,2,2,1,1,2,2)]
cube.idx [3,] <- common.range[3,c(1,1,1,1,2,2,2,2)]
rg.cube <- ijk.from.shape %*% Vb$xyz.from.ijk %*% cube.idx
rgi <- min(floor(rg.cube[1,])):max(ceiling(rg.cube[1,]))
rgj <- min(floor(rg.cube[2,])):max(ceiling(rg.cube[2,]))
rgk <- min(floor(rg.cube[3,])):max(ceiling(rg.cube[3,]))
rgi <- rgi[rgi>=0 & rgi<vol.out$n.ijk[1]]
rgj <- rgj[rgj>=0 & rgj<vol.out$n.ijk[2]]
back.rgk.loc <- match (rgk, vol.out$k.idx)
fna <- is.na(back.rgk.loc)
rgk <- rgk[!fna]
back.rgk.loc <- back.rgk.loc[!fna]
ijk.out <- as.matrix(expand.grid(rgi,rgj,rgk,1))
R.ijk.out <- as.matrix(expand.grid(rgi+1,rgj+1,back.rgk.loc))
Mref <- t(solve(Vb$xyz.from.ijk) %*% shape.from.ijk)
ijk <- (ijk.out %*% Mref)[,1:3,drop =FALSE]
s_ijk <-apply(abs(rbind(c(1,0,0,0),c(0,1,0,0), c(0,0,1,0)) %*% Mref)[,1:3, drop =FALSE],1,max)
vol.out$vol3D.data[R.ijk.out] <- .getvaluefromijkC (vol3D = as.numeric(Vb$vol3D.data),
interpolate = TRUE,
i = as.numeric(ijk[ ,1]),
j = as.numeric(ijk[ ,2]),
k = as.numeric(ijk[ ,3]),
k_idx = Vb$k.idx,
k_loc = Vb$k.idx, n_ijk=Vb$n.ijk,
s_ijk = s_ijk)
vol.out$vol3D.data[R.ijk.out][is.na(vol.out$vol3D.data[R.ijk.out])] <- 0
vol.out$vol3D.data[R.ijk.out][vol.out$vol3D.data[R.ijk.out] >1] <- 1
vol.out$vol3D.data[R.ijk.out][vol.out$vol3D.data[R.ijk.out] <0] <- 0
vol.out$max.pixel <- max(vol.out$vol3D.data[R.ijk.out], na.rm=TRUE)
vol.out$min.pixel <- min(vol.out$vol3D.data[R.ijk.out], na.rm=TRUE)
}
if (modality == "binary"){
vol.out$max.pixel <- !as.logical(round(1-vol.out$max.pixel))
vol.out$min.pixel <- !as.logical(round(1-vol.out$min.pixel))
vol.out$vol3D.data <- array(!as.logical (round(1-vol.out$vol3D.data)),dim =vol.out$n.ijk)
}
return(vol.out)
}
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.