如何通过在spatstat中锚定中点来旋转psp对象?

时间:2014-02-26 09:20:49

标签: r spatstat

我有一个线段图案,与另一条线成90度角:

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度,但交叉点保持不变?

2 个答案:

答案 0 :(得分: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

你可以用

强制它回到psp
as.psp.Lines(from, ..., window=NULL, marks=NULL, fatal)

答案 1 :(得分:1)

只是为了让答案自成一体。下面的代码应该产生你想要的东西(如果这是一个有用的函数,我们可以要求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