2014-02-26 29 views
1

我有一個線段圖案,這是在90度角到另一行:如何通過在spatstat中錨定中點來旋轉psp對象?

require(spatstat)  
range <- c(0,10) 

owin <- owin(xrange = range, yrange = range) 

l1 <- psp(x0 = 8, x1 = 8, y0 = 2, y1 = 8, window = owin, marks = "l1") 
l2 <- psp(x0 = 6, x1 = 6, y0 = 2, y1 = 8, window = owin, marks = "l2") 
l3 <- psp(x0 = 4, x1 = 4, y0 = 2, y1 = 8, window = owin, marks = "l3") 
l4 <- psp(x0 = 2, x1 = 2, y0 = 2, y1 = 8, window = owin, marks = "l4") 

lines <- superimpose(l1, l2, l3, l4) 

main <- psp(x0 = 8, x1 = 0, y0 = 5, y1 = 5, window = owin, marks = "main") 

angles.psp(lines)*(180/pi) 
[1] 90 90 90 90 

這裏是一個視覺表示:

plot(x = range, y = range, type = "n", main = "", asp = 1, axes = F, xlab = "x", ylab = "y") 
plot(lines, col = "darkgrey", add = T) 
plot(main, col = "black", add = T) 
axis(1) 
axis(2, las = 2) 

enter image description here

現在我想旋轉lines以便它們在相同的點但以45度的角度穿過main

lines.rotated <- rotate(lines, -0.7853982) 
angles.psp(lines.rotated)*(180/pi) 
[1] 45 45 45 45 

這工作,但angles.psp功能似乎單獨旋轉,而不是行窗口(owin)因爲我想要的。

plot(x = range, y = range, type = "n", main = "", asp = 1, axes = F, xlab = "x", ylab = "y") 
plot(lines, col = "darkgrey", add = T) 
plot(lines.rotated, col = "blue", add = T) 
plot(main, col = "black", add = T) 
axis(1) 
axis(2, las = 2) 

enter image description here

有一種方法,以相對於lines所有旋轉到main線,使得所述角度爲45度,但交叉點保持不變?

回答

1

迫使它回到PSP只是爲了讓答案自給。下面的代碼應該產生你正在尋找的東西(如果這是一個有用的函數,我們可以要求Adrian(spatstat的維護者)在spatstat中包含它的改進版本)。 首先先決條件:

require(spatstat) 

linerotate.psp <- function(X, L, angle){ 
    ## Window: 
    W <- as.owin(X) 
    ## Empty psp object: 
    Y <- psp(numeric(0),numeric(0),numeric(0),numeric(0),W) 
    for(i in 1:X$n){ 
     ## Line i: 
     Xi <- X[i] 
     ## Crossing of line i and test line L in the window: 
     cross <- crossing.psp(L, Xi) 
     ## Rotate line if the crossing is non-empty: 
     if(npoints(cross)>0){ 
      m <- as.numeric(coords(cross)) 
      ## Move to crossing: 
      Xi <- affine(Xi, vec = -m) 
      ## Rotate: 
      Xi <- rotate(Xi, angle = angle) 
      ## Move back: 
      Xi <- affine(Xi, vec = m) 
      ## Restrict to non-rotated window: 
      Xi <- Xi[W] 
     } 
     ## Collect results: 
     Y <- superimpose(Y, Xi) 
    } 
    return(Y) 
} 

數據:

W <- square(10) 

x0 <- c(8,6,4,2) 
x1 <- x0 
y0 <- rep(2,4) 
y1 <- rep(8,4) 

lines <- psp(x0, y0, x1, y1, window = W) 

main <- psp(x0 = 8, x1 = 0, y0 = 5, y1 = 5, window = W) 

的旋轉數據和角度比較:

rotlines <- linerotate.psp(lines, main, angle = -pi/4) 
angles.psp(lines)*(180/pi) 
[1] 90 90 90 90 
angles.psp(rotlines)*(180/pi) 
[1] 45 45 45 45 

圖形:

plot(lines, col = "darkgrey") 
plot(main, col = "black", add = T) 
plot(rotlines, col = "blue", add = T) 

Rotated lines

圖形與非水平測試線:

main <- psp(x0 = 0, x1 = 10, y0 = 3, y1 = 7, window = W) 
rotlines <- linerotate.psp(lines, main, angle = -pi/4) 

plot(lines, col = "darkgrey") 
plot(main, col = "black", add = T) 
plot(rotlines, col = "blue", add = T) 

rotated lines 2

+0

@EgeRubak謝謝。我認爲這是解決問題比使用外部軟件包更好的解決方案。 @PauloCardoso有一個好點。實現這一點不應該需要對代碼進行非常大的修改,因爲可以將'W'與'main' /附加的可選行而不是'X'聯繫起來。 – Mikko

+0

我完全錯過了這一點。對於那個很抱歉。我將使用修改後的代碼編輯我的答案,以找到與測試線L的所有交點,並在每個交點周圍以指定角度旋轉每條線。 –

+1

我對stackoverflow很陌生,所以我不確定最好的策略是編輯自己的答案還是提供一個新的答案。現在,我看着我編輯的代碼@PauloCardoso的評論不再有意義。做出這樣的改變,原來的評論不再是相關的,被認爲是不好的風格?在另一個說明中,也許原始海報應該編輯問題的標題,因爲我們不再固定中間點,而是與另一條線交叉點。 –

1

我不確定是否有你的想法。

對於一個簡單的方法,可以從maptools elide是一個選項?

是這樣的:

library(maptools) 
# convert lines to SpatialLines 
slines <- as(lines, 'SpatialLines') 

plot(x = range, y = range, type = "n", main = "", asp = 1, axes = F, 
    xlab = "x", ylab = "y") 
plot(lines, col = "darkgrey", add = T) 
plot(main, col = "black", add = T) 
axis(1) 
axis(2, las = 2) 
# Plot slines object on top of your data 
plot(elide(slines, rotate = 45, center = c(5, 5)), add = T) 

# plot it 

rotated slines

但你可能想從旋轉線交叉線與主之間的交叉每一行。真的嗎?

如果是這樣,在每個PSP線上循環。對於PSP L4:

plot(elide(slines[4], rotate = 45, center = c(2, 5)), add = T) 

plot on intersections

您可以用

as.psp.Lines(from, ..., window=NULL, marks=NULL, fatal) 
+0

的旋轉線依然不交叉'main'在比原來的線相同的點。如果你單獨使用'elide'作爲每條線,我想它可以工作。我的應用程序嚴重依賴於'spatstat',所以我想找到一種方法來處理這個包。也許把旋轉的行寫成'psp'對象可能會起作用。 – Mikko

+0

@準確地說。 –