gpt4 book ai didi

r - 估计未定义表面的梯度

转载 作者:行者123 更新时间:2023-12-04 09:43:26 25 4
gpt4 key购买 nike

我想估计未定义表面的梯度(斜率和纵横比)(即函数未知)。为了测试我的方法,这里是测试数据:

require(raster); require(rasterVis)            
set.seed(123)
x <- runif(100, min = 0, max = 1)
y <- runif(100, min = 0, max = 1)
e <- 0.5 * rnorm(100)
test <- expand.grid(sort(x),sort(y))
names(test)<-c('X','Y')
z1 <- (5 * test$X^3 + sin(3*pi*test$Y))
realy <- matrix(z1, 100, 100, byrow = F)
# And a few plots for demonstration #
persp(sort(x), sort(y), realy,
xlab = 'X', ylab = "Y", zlab = 'Z',
main = 'Real function (3d)', theta = 30,
phi = 30, ticktype = "simple", cex=1.4)
contour(sort(x), sort(y), realy,
xlab = 'X', ylab = "Y",
main = 'Real function (contours)', cex=1.4)

我使用 rasterVis::vectorplot 将所有内容转换为栅格和绘图.一切看起来都很好。矢量场表示变化幅度最大的方向,阴影类似于我的等高线图......
test.rast <- raster(t(realy), xmn = 0, xmx = 1, 
ymn = 0, ymx = 1, crs = CRS("+proj"))
vectorplot(test.rast, par.settings=RdBuTheme, narrow = 100, reverse = T)

但是,我需要一个斜率值矩阵。据我了解 vectorplot,它使用 raster::terrain 函数:
terr.mast <- list("slope" = matrix(nrow = 100, 
ncol = 100,
terrain(test.rast,
opt = "slope",
unit = "degrees",
reverse = TRUE,
neighbors = 8)@data@values,
byrow = T),
"aspect" = matrix(nrow = 100,
ncol = 100,
terrain(test.rast,
opt = "aspect",
unit = "degrees",
reverse = TRUE,
neighbors = 8)@data@values,
byrow = T))

然而,坡度看起来真的很高......(90度是垂直的,对吧?!)
terr.mast$slope[2:6,2:6] 
# [,1] [,2] [,3] [,4] [,5]
#[1,] 87.96546 87.96546 87.96546 87.96550 87.96551
#[2,] 84.68628 84.68628 84.68627 84.68702 84.68709
#[3,] 84.41349 84.41350 84.41349 84.41436 84.41444
#[4,] 84.71757 84.71757 84.71756 84.71830 84.71837
#[5,] 79.48740 79.48741 79.48735 79.49315 79.49367

如果我绘制斜率和坡向,他们似乎不同意矢量图形。
plot(terrain(test.rast, opt = c("slope", "aspect"), unit = "degrees", 
reverse = TRUE, neighbors = 8))

我的想法:
  • Vectorplot 必须平滑斜率,但如何平滑?
  • 我相当确定 raster::terrain正在使用流动窗口方法来计算斜率。可能 window 太小了……这个可以扩大吗?
  • 我是否以不恰当的方式处理此事?我还能如何估计未定义曲面的斜率?
  • 最佳答案

    我建了一个 RasterLayer使用来自 raster 的函数处理您的数据:

    library(raster)
    library(rasterVis)

    test.rast <- raster(ncol=100, nrow=100, xmn = 0, xmx = 1, ymn = 0, ymx = 1)
    xy <- xyFromCell(test.rast, 1:ncell(test.rast))
    test.rast[] <- 5*xy[,1] + sin(3*pi*xy[,2])

    让我们用 levelplot 显示这个对象:
    levelplot(test.rast)

    levelplot

    和梯度矢量场 vectorplot :
    vectorplot(test.rast)

    vectorplot

    如果您只需要斜率,您可以通过 terrain 获得它:
    slope <- terrain(test.rast, unit='degrees')

    levelplot(slope, par.settings=BTCTheme())

    slope

    但是,如果我理解正确的话,您确实需要渐变,所以
    你应该计算斜率和方面:
    sa <- terrain(test.rast, opt=c('slope', 'aspect'))

    为了解路 vectorplot正在画箭头,
    在这里,我展示了其(修改后的)代码的一部分,其中水平
    计算箭头的垂直分量:
    dXY <- overlay(sa, fun=function(slope, aspect, ...){
    dx <- slope*sin(aspect) ##sin due to the angular definition of aspect
    dy <- slope*cos(aspect)
    c(dx, dy)
    })

    因为原来的结构 RasterLayer , 这
    水平分量几乎是恒定的,所以让我们画出我们的
    注意垂直分量。下一个代码覆盖
    向量场在这个垂直分量上的箭头。
    levelplot(dXY, layers=2, par.settings=RdBuTheme()) +
    vectorplot(test.rast, region=FALSE)

    dY

    最后,如果您需要坡度和坡向的值,请使用 getValues :
    saVals <- getValues(sa)

    关于r - 估计未定义表面的梯度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16365197/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com