2017-10-09 2 views
2

J'essaie de comprendre comment calculer la surface d'une section de rivière remplie d'eau pour différents niveaux d'eau.Calculer l'aire de la section transversale en fonction de la hauteur

Pour la section, j'ai la profondeur à tous les 25 cm sur la rivière large de 5 m et la zone peut être calculée sur la base d'une question précédente bien répondu Calculate area of cross section for varying height

x_profile <- seq(0, 500, 25) 
y_profile <- c(50, 73, 64, 59, 60, 64, 82, 78, 79, 76, 72, 
      68, 63, 65, 62, 61, 56, 50, 44, 39, 25) 

library(sf) 

#Create matrix with coordinates 
m <- matrix(c(0, x_profile, 500, 0, 0, -y_profile, 0, 0), 
     byrow = FALSE, ncol = 2) 

#Create a polygon 
poly <- st_polygon(list(m)) 

# Calcualte the area 
st_area(poly) 

Mais cette section est seulement partiellement rempli d'eau, et c'est la section transversale remplie d'eau que j'essaie maintenant de calculer.

L'eau commence à remplir la section de la partie la plus profonde et la profondeur varient alors, par exemple comme ceci:

water_level<-c(40, 38, 25, 33, 40, 42, 50, 39) 

Est-ce que quelqu'un a des idées sur la façon dont cela pourrait être fait en r? Merci d'avance.

+0

avez-vous le même nombre de valeurs 'water_level' en tant que' y_profile'? Je pense que vous avez juste besoin de trouver la différence entre 'y_profile' et' water_level', mais ça va être difficile à faire si vous n'avez pas le même nombre de valeurs. – shea

+0

Donc pour 'water_level' est 40 alors c'est un niveau d'eau Y valeur de l'axe' max (y_profile) - 40' = 42? – Spacedman

+1

Une façon de procéder consiste à construire un rectangle au niveau de l'eau qui entoure le profil et se croiser avec le profil en utilisant 'st_intersection'. – Spacedman

Répondre

5

Cette fonction calcule l'intersection du profil avec une ligne à la profondeur spécifiée à partir du bas du profil. Il est légèrement redondant en ce qu'elle a également besoin des x et des valeurs de profil y qui pourrait en théorie être extraits de profile:

filler <- function(depth, profile, xprof, yprof, xdelta=100, ydelta=100){ 
    d = -(max(yprof))+depth 
    xr = range(xprof) 
    yr = range(-yprof) 
    xdelta = 100 
    xc = xr[c(1,2,2,1,1)] + c(-xdelta, xdelta, xdelta, -xdelta, -xdelta) 
    yc = c(d, d, min(yr)-ydelta, min(yr)-ydelta, d) 
    water = st_polygon(list(cbind(xc,yc))) 
    st_intersection(profile, water) 
} 

donc en cours d'utilisation:

> plot(poly) 
> plot(filler(40, poly, x_profile, y_profile), add=TRUE, col="green") 
> plot(filler(30, poly, x_profile, y_profile), add=TRUE, col="red") 
> plot(filler(15, poly, x_profile, y_profile), add=TRUE, col="blue") 

depths

Notez le premier la région verte est légèrement couverte par les régions moins profondes. Notez également comment les régions bleues se trouvent dans deux sections. Vous pouvez obtenir la section avec st_area et en profondeur la zone zéro est zéro:

> st_area(filler(20, poly, x_profile, y_profile)) 
[1] 2450.761 
> st_area(filler(2, poly, x_profile, y_profile)) 
[1] 15.27778 
> st_area(filler(0, poly, x_profile, y_profile)) 
[1] 0 

Je ne sais pas ce qui se passe si vous allez au-dessus du haut de votre profil ...

+0

Merci beaucoup pour votre réponse! Cela a fonctionné parfaitement! – Nicolle