2017-10-08 55 views
0

比方說,我有一個線框,3D對象,如https://free3d.com/3d-model/freerealsichand-85561.html如何使用`rgl`旋轉與加速度計數據的手對象和`animation`

比方說,我希望修正所述對象的手腕被讀出的加速度計手錶(例如,通過航位推算獲取位置)。

如何在rgl中繪製這樣的3-D圖像?

如何根據加速度計數據的變化來旋轉/翻譯所述圖像?

獎勵金:我該如何玩此活動的animation。 (例如,庫animation

該加速度計是3-DOF:x-acc,y-acc,z-acc,沒有任何其他數據。

回答

1

該鏈接包含幾種格式的手,但rgl目前無法讀取它們。它與.OBJ格式最接近,但不能讀取記錄在該文件中的法線或紋理,因此失敗。您可能想要嘗試更新readOBJ以支持更多的OBJ格式;或者,你可以刪除該信息是這樣的:

hand <- readLines("hand.OBJ") 
poly <- grepl("^f ", hand) 
hand[poly] <- gsub("/[^ ]+", "", hand[poly]) 
handmesh <- readOBJ(textConnection(hand)) 

這會給一些警告,因爲它忽略了文件的某些其他部分,但它導致了一個對象,rgl可以處理。您可以繪製這樣說:

shade3d(handmesh, col = "pink") 

要平移和旋轉形狀,請使用userMatrix例如在translate3drotate3d功能

par3d(userMatrix = rotate3d(par3d("userMatrix"), 0.1, 1,0,0)) 

將手圍繞x軸旋轉0.1弧度。 (如果您想要永久更改,也可以旋轉handmesh本身。)

您需要花一些時間弄清楚手腕的座標是什麼,並將您的3D自由度數據轉換爲正確的座標系。

對於動畫您不需要animation;請參閱?rgl::play3d中的示例。例如,要繞x軸旋轉手,您可以使用

open3d() 
shade3d(handmesh, col = "pink") 
play3d(spin3d(axis = c(1, 0, 0))) 
+0

感謝您的信息。我有足夠的工作來解決我的需求。非常有用的例子。 – mshaffer

0

根據提供的answer @ user2554330,我深入瞭解了詳細信息。

RGL :: readOBJ有點不完美,我通知R-鍛造:這件事情RGL:https://r-forge.r-project.org/tracker/index.php?func=detail&aid=6543&group_id=234&atid=949

# rgl::readOBJ 
beginT = Sys.time(); 
hand <- readLines("hand.OBJ") 
poly <- grepl("^f ", hand) 
hand[poly] <- gsub("/[^ ]+", "", hand[poly]) 
handmesh <- readOBJ(textConnection(hand)) 
endT = Sys.time(); print(endT-beginT); 
# Time difference of 1.555696964263916 secs 

我劈具有四個功能:

#' Convert String Matrix to Numeric Matrix 
#' 
#' @param m string matrix 
#' 
#' @return numeric matrix 
#' @export 

numericMatrix = function(m) 
{ 

    m = as.matrix(m); 
    mdim = dim(m); 

    nm <- mapply(m, FUN=as.numeric); 
    matrix(data=nm, nrow=mdim[1], ncol=mdim[2]) 

} 


#' Convert String List of "f" to numeric multi-dimensional array 
#' 
#' @param fobj 
#' 
#' @return fn, multidimension array of rows, cols, and values 
#' @export 
#' 

numericF = function(fobj) 
{ 

    rdim = dim(fobj)[1]; # rows 
    cdim = dim(fobj)[2]; # cols 
    ddim = 3; 

    fn = array(NA,dim=c(rdim,cdim,ddim)); 


    for(rn in 1:rdim) 
    { 
    for(cn in 1:cdim) 
     { 
     rcdat = fobj[rn,cn]; 
     fdat = as.numeric(unlist(strsplit(rcdat,"/",fixed=T))); # basic numeric case 
     fn[rn,cn,] = fdat; 
     } 
    } 



    #fn[1:10,1:4,1:3] 

    fn; 


    } 



#' Internally equivalent to rgl 'readOBJ' 
#' 
#' @param rawobj Raw object read in using parseFileOBJ 
#' 
#' rgl::readOBJ 
#' hand <- readLines("hand.OBJ") 
#' poly <- grepl("^f ", hand) 
#' hand[poly] <- gsub("/[^ ]+", "", hand[poly]) 
#' handmesh <- readOBJ(textConnection(hand)) 
#' 
#' mymesh = buildBasicMeshFromOBJ(parseFileOBJ("hand.OBJ")); 
#' 
#' These appear to be equivalent in the basic form 
#' 
#' @return list object equivalent to readOBJ output 
#' @export 
#' 

buildBasicMeshFromOBJ <- function(rawobj) 
{ 

    mesh = list(); 
     vb = as.matrix(rawobj$v); 
     vb = cbind(vb,1); 
    mesh$vb = t(vb); 
    mesh$it = matrix(0,nrow=3,ncol=0); 
    mesh$primitivetype = "triangle"; 
    mesh$ib = t(as.matrix(rawobj$fn[,,1])); 

    attr(mesh,"class") = c("mesh3d","shape3d"); 

    mesh; 
} 

#' Parse file of type OBJ 
#' 
#' Specification for OBJ format can be found here: 
#' http://www.martinreddy.net/gfx/3d/OBJ.spec 
#' 
#' Requires gdata::trim 
#' 
#' @param filename 
#' 
#' @return list 'rawobj' with all details from the file 
#' @export 
#' 
#' @examples 
#' rawobj = parseFileOBJ("hand.obj"); 
parseFileOBJ <- function(filename) 
{ 



    linestxt <- readLines(filename)     # read all lines 
    linestxt = gsub("\\s+"," ",gdata::trim(linestxt)); # replace multiple spaces with single space 
    linesobj = strsplit(linestxt," ",fixed=T);  # split on spaces 


    rawobj = list(); 
    rawobj$lines = c(); 
    rawobj$comments = c(); 



    for(i in 1:length(linesobj)) 
    { 
    hir = gdata::trim(linesobj[[i]]); 
    key = hir[1]; 
    rdat = hir[-1]; 
    rlen = length(rdat); 
    rstr = paste(rdat,collapse=" "); 
    if (key=="#") { 
     rawobj$lines = c(rawobj$lines,"comments"); 
     rawobj$comments = c(rawobj$comments,rstr); 
     } else { rawobj$lines = c(rawobj$lines,key); 
       if(is.null(rawobj[[key]])) { rawobj[[key]] = rdat; } else 
       { rawobj[[key]] = rbind(rawobj[[key]],rdat);} 
     } 
    } 


    if(!is.null(rawobj[["v"]])) { rawobj[["v"]] = numericMatrix(rawobj[["v"]]); } 
    if(!is.null(rawobj[["vn"]])) { rawobj[["vn"]] = numericMatrix(rawobj[["vn"]]); } 
    if(!is.null(rawobj[["vt"]])) { rawobj[["vt"]] = numericMatrix(rawobj[["vt"]]); } 

    # "f" could be numeric (f 1 2 3 4) or (f -4 -3 -2 -1) or references to v,vn,vt (f 1/1/1 2/2/2 3/3/3 4/4/4) or (f v/vt/vn v/vt/vn v/vt/vn v/vt/vn) or (f 1//1 2//2 3//3 4//4) 
    # rdat = c("1102/9904/4404","2981/9909/4404","3943/9910/4404","2854/9905/4404"); 
    # rdat = c('1//1','2//2','3//3',4//4'); 

    if(!is.null(rawobj[["f"]])) { rawobj[["fn"]] = numericF(rawobj[["f"]]); } 



    rawobj; 

} 

基本用法:

# Takes longer, but processes "all" info in the file 
beginT = Sys.time(); 
rawobj = parseFileOBJ("hand.OBJ"); 
endT = Sys.time(); print(endT-beginT); beginT = endT; 
# Time difference of 6.9523830413818359 secs 
mymesh = buildBasicMeshFromOBJ(rawobj); 
endT = Sys.time(); print(endT-beginT); 
# Time difference of 0.0030009746551513672 secs 

rawobject有全部 th根據此規範在OBJ文件中找到的信息:http://www.martinreddy.net/gfx/3d/OBJ.spec

相關問題