I am trying to create a 3D surface on a fixed grid of say 1m or 0.5m spacing, where the surface is a channel defined by a cross section of a number of points. Ideally it should be any number of points. For example a cross section such as:
PTS = [[0.0,10.0],[3.0,9.0],[30.0,8.5],[33.0,8.0],[35.0,7.8],[37.0,8.0],[40.0,8.5],[67.0,9.0],[70.0,10.0]] Where the channel here is 70 m wide and has a double trapezoidal section.
I have tried, to code this but failed to date:
I want to read the points, and then interpolate based on the spacing to provide a calculated elevation (Z value). This should populate the domain of X & Y, thereby providing XYZ values of the 3D terrain
This example is supposed to create a 1500m long channel that is 70 m wide
CODE:
Setup computational domain
length = 50.0 # change back to 3500
width = 30.0 #changed this
dx = dy = 1.0 # Resolution: of grid on both axes
h=2.21 # Constant depth
slope_X=1/100
def topography(x,y):
z = -x*slope_X
PTS = [[0.0,10.0],[3.0,9.0],[30.0,8.5],[33.0,8.0],[35.0,7.8],[37.0,8.0],[40.0,8.5],[67.0,9.0],[70.0,10.0]]
N = len(x)
for i in range(N):
# Construct Cross section from LIST of PTS
for j in range(len(PTS)):
if j == 0:
pass
else:
m = (PTS[j][1]-PTS[j-1][1])/(PTS[j][0]-PTS[j-1][0])
b = PTS[j-1][1]-(PTS[j][1]-PTS[j-1][1])/(PTS[j][0]-PTS[j-1][0])*PTS[j-1][0]
z[i]= m *y[i]+b
if x[i]==10:
print 'Z =', z[i]
return z
As the code traverses over X, the basic Z provides a sloping bed, and then the cross section defined, creates the Z's over a range of Y's
Ideally this could also be applied along a polyline, rather than apply it only in the x -direction. That way the channel could be produced along a curve, or a S- bend for example
I hope some one has some clever ideas on how to resolve this... Thank you
It was mentioned that scipy might be able to help here.... I will try to make sense of this, to create a function to interpolate between the points:
from scipy.interpolate import interp1d
x = np.linspace(0, 10, 10)
y = np.exp(-x/3.0)
f = interp1d(x, y)
f2 = interp1d(x, y, kind=’cubic’)
xnew = np.linspace(0, 10, 40)
import matplotlib.pyplot as plt
plt.plot(x,y,’o’,xnew,f(xnew),’-’, xnew, f2(xnew),’--’)
plt.legend([’data’, ’linear’, ’cubic’], loc=’best’)
plt.show()