2016-10-22 198 views
1

我想繪製樹的環和計算它們的面積。但是,我已經注意到,實際上並非所有的環都具有圓對稱的半徑。我具有4個半徑數據測量,並且我想繪製以下這樣例如每無線電的每個點環(或任何類似的形狀)(該圖中,用在PowerPoint矢量手動完成):如何繪製一些形狀(橢圓形或橢圓形)並計算其面積?

enter image description here

的問題是,在RI只發現了繪製這些環從symbols()功能circles選項的可能性,我得到這個圖:使用該R腳本 enter image description here

data <- data.frame(
a = c(1,4,5,8, 10), 
b = c(1, 3,7,9, 10), 
c = c(2, 6, 8, 9 ,10), 
d = c(1, 3, 4, 7, 9)) 

data$y <- (data$a - data$b)/2 # y position 
data$x <- (data$d - data$c)/2 # x position 
data$z <- rowMeans(data[,1:4]) # radio length 

symbols(x = data$x, y = data$y, circles=data$z, 
     xlim = c(-10, 10)*1.5, ylim = c(-10, 10)*1.5, inches = F, fg = "orange", lwd = 2) 

我已經檢查了一些帶有橢圓功能的軟件包(elliplot,ellipse,ellipseplot,car等),但我不喜歡它們的功能。我對使用這些軟件包不感興趣,相反,我想寫一個自己的代碼。

我的想法是畫出最符合與四米半徑的我的數據值的環實景圖的形狀,也可以是一個橢圓形,橢圓形等

由於我只使用一個圓一個無線電的數據(在我的例子中,是所有半徑的平均值)。 使用橢圓會更好,因爲我可以使用至少兩個值,即主軸(A + B)和次軸(C + D)。但是繪製一個使用四個半徑(A,B,C,D)或甚至更多半徑的值的形狀會很棒。

Here一個人使用R script畫了一個非常漂亮的superellipse,另外一個吸引一些ellipses likes ringsin R

但是,我不知道如何使用他們的方法來解決我的具體問題。

如果有人有想法如何開始繪製至少在R中的橢圓將是很好的。但如果知道如何使用四個半徑的值繪製一個形狀(橢圓,橢圓等)並最終計算出它們的面積,那就太好了。

非常感謝您的幫助或任何方向。

UPDATE:

感謝@ cuttlefish44你的出色答卷,這是解釋樹木生長到我的學生非常有用的。然而,大多數熱帶樹木具有非常不規則的形狀,現在我想知道如果我能有額外的無線電「E」,在這樣的方案不同的位置半徑軸得出這樣的其它形狀:

irregular stem shape

任何方向對我來說都是非常有用的。

回答

1

如果A & B位於y軸上且C & D位於x軸上,計算橢圓參數並不困難。我用optim()得到params(注意:這種方法有微小的錯誤,比如2.439826e-12)。

數據操縱
# change all data into xy coordinates and make ring-factor 
library(reshape2); library(dplyr) 

data <- data.frame(
    a = c(1, 4, 5, 8, 10), 
    b = c(1, 3, 7, 9, 10) * -1, 
    c = c(2, 6, 8, 9, 10) * -1, 
    d = c(1, 3, 4, 7, 9)) 

data <- t(data) 
colnames(data) <- LETTERS[1:ncol(data)] # ring-factor 
df <- melt(data, value.name = "x")  # change into long-form 

df$y <- df$x        # make xy coordinates 
df[df$Var1=="a"|df$Var1=="b", "x"] <- 0 
df[df$Var1=="c"|df$Var1=="d", "y"] <- 0 
中心座標的計算,牛& OY
center <- df %>% group_by(Var2) %>% summarize(sum(x)/2, sum(y)/2) %>% as.data.frame() 
的橢圓的參數;計算裝置半長軸和-minor軸,RA & RB
opt.f <- function(par, subset, center) {  # target function 
    ox <- center[[1]]       # par[1] and par[2] are ra and rb 
    oy <- center[[2]] 
    x <- subset$x 
    y <- subset$y 
    sum(abs((x - ox)^2/par[1]^2 + (y - oy)^2/par[2]^2 - 1)) # from ellipse equation 
} 

lev <- levels(df$Var2) 

## search parameters 
res <- sapply(1:length(lev), function(a) 
    optim(c(1,1), opt.f, subset = subset(df, Var2 == lev[a]), 
     center = center[a, 2:3], control = list(reltol = 1.0e-12))) 

res # result. you can get detail by res[,1etc]. values are not 0 but much nearly 0 
功能繪製(也許有些包有類似的一個)
radian <- function(degree) degree/180*pi 
plot.ellipse <- function(ox, oy, ra, rb, phi=0, start=0, end=360, length=100, func=lines, ...) { 
    theta <- c(seq(radian(start), radian(end), length=length), radian(end)) 
    if (phi == 0) { 
    func(ra*cos(theta)+ox, rb*sin(theta)+oy, ...) 
    } else { 
    x <- ra*cos(theta) 
    y <- rb*sin(theta) 
    phi <- radian(phi) 
    cosine <- cos(phi) 
    sine <- sin(phi) 
    func(cosine*x-sine*y+ox, sine*x+cosine*y+oy, ...) 
    } 
} 
plot(0, type="n", xlim=c(-10, 10), ylim =c(-10, 10), asp=1, xlab="x", ylab="y", axes = F) 
axis(1, pos=0);axis(2, pos=0, las=2) 
points(df$x, df$y) 
for(a in 1:length(lev)) plot.ellipse(ox = center[a, 2], oy = center[a, 3], 
            ra = res[,a]$par[1], rb = res[,a]$par[2], length=300) 

area <- sapply(res[1,], function(a) pi * a[1] * a[2]) 

enter image description here

+0

感謝您的出色答卷。但是,我有一個新問題來繪製更多不規則的形狀。我已經對我的帖子進行了更新,以解釋我需要的內容。或者你認爲創建一個新問題會更好嗎? –