如何根据已知的坡度和坡向值生成二维数组?

发布于 2025-01-19 03:18:28 字数 919 浏览 3 评论 0原文

Given a dummy heightmap (or digital elevation model) stored as a Numpy array like this:

import numpy as np
import matplotlib.pyplot as plt

line = np.flip(np.arange(0, 10))
dem = np.tile(line, (10, 1))

I can calculate its slope and aspect like this:

x, y = np.gradient(dem)
slope = np.degrees(np.arctan(np.sqrt(x**2 + y**2)))
aspect = np.degrees(np.arctan2(x, -y))

And visualise it:

fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
y, x = np.mgrid[:10, :10]
ax.scatter(x, y, dem)
ax.set_title(f"Slope={np.mean(slope)}, Aspect={np.mean(aspect)}")

enter image description here

But how would I go the other way?

我想生成一个固定尺寸的空白2D numpy阵列,然后用遵循已知斜率和方面的值填充(从任意高程开始,例如0)。

Given a dummy heightmap (or digital elevation model) stored as a Numpy array like this:

import numpy as np
import matplotlib.pyplot as plt

line = np.flip(np.arange(0, 10))
dem = np.tile(line, (10, 1))

I can calculate its slope and aspect like this:

x, y = np.gradient(dem)
slope = np.degrees(np.arctan(np.sqrt(x**2 + y**2)))
aspect = np.degrees(np.arctan2(x, -y))

And visualise it:

fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
y, x = np.mgrid[:10, :10]
ax.scatter(x, y, dem)
ax.set_title(f"Slope={np.mean(slope)}, Aspect={np.mean(aspect)}")

enter image description here

But how would I go the other way?

I'd like to generate a blank 2D Numpy array of a fixed size, then fill it with values that follow a known slope and aspect (starting from an arbitrary elevation e.g. 0).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不必你懂 2025-01-26 03:18:28

由于gradient假设步长为1,因此用N点和给定slopeoffset<制作一条线的一般公式/code>

slope * np.arange(N) + offset

所谓的斜率是梯度的大小,以角度的形式给出。您所说的坡向是 x 和 y 方向上部分坡度的比率,也以角度形式给出。您有以下非线性方程组:

np.tan(np.radians(slope))**2 = sx**2 + sy**2
np.tan(np.radians(aspect)) = -sx / sy

幸运的是,您可以使用替换轻松解决此问题:

p = np.tan(np.radians(slope))**2
q = np.tan(np.radians(aspect))
sy = np.sqrt(p / (q**2 + 1))
sx = -q * sy

现在您需要做的就是取斜率 sx的两条线的外部总和sy

dem = offset + sx * np.arange(NX)[::-1, None] + sy * np.arange(NY)

这是一个示例:

输入:

aspect = -30
slope = 45
offset = 1
NX = 12
NY = 15

渐变:

p = np.tan(np.radians(slope))**2
q = np.tan(np.radians(aspect))
sy = np.sqrt(p / (q**2 + 1))   # np.sqrt(3) / 2
sx = -q * sy                   # 0.5

结果:

dem = offset + sx * np.arange(NX)[::-1, None] + sy * np.arange(NY)
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax = fig.add_subplot(111, projection="3d")
ax.scatter(*np.mgrid[:NX, :NY], dem)

在此处输入图像描述

您的约定可能会因某个标志而偏离,您应该能够通过查看轻松修复该约定情节。

Since gradient assumes a step size of 1, the general formula for making a line with N points and a given slope and offset is

slope * np.arange(N) + offset

What you call Slope is the magnitude of the gradient, given as an angle. What you call Aspect is the ratio of partial slopes in the x- and y-directions, also given as an angle. You have the following system of non-linear equations:

np.tan(np.radians(slope))**2 = sx**2 + sy**2
np.tan(np.radians(aspect)) = -sx / sy

Luckily, you can solve this pretty easily using substitution:

p = np.tan(np.radians(slope))**2
q = np.tan(np.radians(aspect))
sy = np.sqrt(p / (q**2 + 1))
sx = -q * sy

Now all you need to do is take the outer sum of two lines with slopes sx and sy:

dem = offset + sx * np.arange(NX)[::-1, None] + sy * np.arange(NY)

Here is an example:

Inputs:

aspect = -30
slope = 45
offset = 1
NX = 12
NY = 15

Gradient:

p = np.tan(np.radians(slope))**2
q = np.tan(np.radians(aspect))
sy = np.sqrt(p / (q**2 + 1))   # np.sqrt(3) / 2
sx = -q * sy                   # 0.5

Result:

dem = offset + sx * np.arange(NX)[::-1, None] + sy * np.arange(NY)
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax = fig.add_subplot(111, projection="3d")
ax.scatter(*np.mgrid[:NX, :NY], dem)

enter image description here

Your conventions may be off by a sign, which you should be able to fix easily by looking at the plot.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文