如何绘制多变量函数的平滑contour/level曲线
How to draw smooth contour/level curves of multivariable functions
程序员和数学爱好者们大家好。
最近一直在探索CAS图形计算器的功能;特别是,他们如何能够绘制水平曲线以及多变量函数的等高线。
在我提出问题之前,请注意几点:
- 我使用 Python 的 Pygame 库纯粹是为了 window 和图形。当然还有更好的选择,但我真的很想让我的代码尽可能地原始,以便尽可能多地学习。
- 是的,是的。我知道 matplotlib!天哪,我看到了 100 条关于使用其他支持库的不同建议。虽然它们绝对是令人惊叹和强大的工具,但我真的在努力从这里的基础上积累我的知识,以便有一天我什至能够发展和支持像它们这样的库。
我的最终目标是让情节看起来像这样流畅:
Mathematica Contour Plot Circle E.g.
我目前做的是:
- 在 500x500 点等于 0 的网格上评估函数,具有一定的误差容限(我的是 0.01)。这让我粗略估计了 f(x,y)=0 处的水平曲线。
- 然后我使用一个狡猾的距离函数来找到每个点的最近邻点,并在两者之间画一条抗锯齿线。
可以在此处查看这两个步骤的结果:
First Evaluating Valid Grid Points
Then Drawing Lines to Closest Points
由于明显的原因,我在图表中有间隙,下一个最接近的点总是使图表不连续。唉!我想到了另一个 janky 解决方法。在找到最近点的基础上,它实际上寻找尚未访问过的下一个最近点怎么样?这个想法很接近,但似乎还没有真正接近有效。这是我实施后的结果:
Slightly Smarter Point Connecting
我的问题是,这种事情通常如何在图形计算器中实现?我一直在做这一切吗?任何想法或建议将不胜感激:)
(我没有包含任何代码,主要是因为它不是很清楚,也不是特别相关的问题)。
此外,如果有人有一些核心数学答案可以建议,请不要害怕提出建议,我在编码和数学(尤其是数值和计算方法)方面有良好的背景,所以我希望我能能够应付他们。
所以你正在为你的平面上的每个 x 和 y 点计算方程。然后你检查结果是否 < 0.01,如果是,你就是在画点。
检查是否应绘制点的更好方法是检查以下情况之一是否为真:
(a) 如果点为零
(b) 如果该点为正且至少有一个负邻居
(c) 如果该点为负且至少有一个正邻居
这有 3 个问题:
- 它不支持任何类型的抗锯齿,因此结果看起来不会像您想要的那样平滑
- 你不能制作更粗的线条(超过 1 个像素)
- 如果0点线只是接触(两边都是正数,一边不是正数,一边是负数)
第二个解决方案可能会解决这些问题,但它是我制作的,没有经过测试,所以它可能有效也可能无效:
您将值分配给 角,然后计算从角开始的每个点到零线的距离。这是查找距离的算法:
def distance(tl, tr, bl, br): # the 4 corners
avg = abs((tl + tr + bl + br) / 4) # getting the absolute average
m = min(map(abs, (tl + tr + bl + br))) # absolute minimum of points
if min == 0: # special case
return float('inf')
return avg / m # distance to 0 point assuming the trend will continue
此 returns 到 0 线的估计距离,您现在可以绘制像素,例如如果你想要一条 5 像素的线,那么如果结果 <4 你绘制像素全彩,elif 像素 <5 你绘制不透明度为距离的像素 - 4(*255
如果你正在使用pygames alpha 选项)
此解决方案假设函数是线性的。
试试吧,最坏的情况下它不起作用...
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.30.1319&rep=rep1&type=pdf
这份 21 页的文档包含了我准确流畅地绘制隐式曲线所需的一切。它甚至涵盖了优化方法并支持隐式函数的分叉点。强烈推荐给任何有类似我上面问题的人。
感谢所有提出建议和澄清问题的人,他们都帮助我找到了这个资源。
程序员和数学爱好者们大家好。
最近一直在探索CAS图形计算器的功能;特别是,他们如何能够绘制水平曲线以及多变量函数的等高线。
在我提出问题之前,请注意几点:
- 我使用 Python 的 Pygame 库纯粹是为了 window 和图形。当然还有更好的选择,但我真的很想让我的代码尽可能地原始,以便尽可能多地学习。
- 是的,是的。我知道 matplotlib!天哪,我看到了 100 条关于使用其他支持库的不同建议。虽然它们绝对是令人惊叹和强大的工具,但我真的在努力从这里的基础上积累我的知识,以便有一天我什至能够发展和支持像它们这样的库。
我的最终目标是让情节看起来像这样流畅: Mathematica Contour Plot Circle E.g.
我目前做的是:
- 在 500x500 点等于 0 的网格上评估函数,具有一定的误差容限(我的是 0.01)。这让我粗略估计了 f(x,y)=0 处的水平曲线。
- 然后我使用一个狡猾的距离函数来找到每个点的最近邻点,并在两者之间画一条抗锯齿线。
可以在此处查看这两个步骤的结果:
First Evaluating Valid Grid Points
Then Drawing Lines to Closest Points
由于明显的原因,我在图表中有间隙,下一个最接近的点总是使图表不连续。唉!我想到了另一个 janky 解决方法。在找到最近点的基础上,它实际上寻找尚未访问过的下一个最近点怎么样?这个想法很接近,但似乎还没有真正接近有效。这是我实施后的结果:
Slightly Smarter Point Connecting
我的问题是,这种事情通常如何在图形计算器中实现?我一直在做这一切吗?任何想法或建议将不胜感激:)
(我没有包含任何代码,主要是因为它不是很清楚,也不是特别相关的问题)。
此外,如果有人有一些核心数学答案可以建议,请不要害怕提出建议,我在编码和数学(尤其是数值和计算方法)方面有良好的背景,所以我希望我能能够应付他们。
所以你正在为你的平面上的每个 x 和 y 点计算方程。然后你检查结果是否 < 0.01,如果是,你就是在画点。
检查是否应绘制点的更好方法是检查以下情况之一是否为真:
(a) 如果点为零
(b) 如果该点为正且至少有一个负邻居
(c) 如果该点为负且至少有一个正邻居
这有 3 个问题:
- 它不支持任何类型的抗锯齿,因此结果看起来不会像您想要的那样平滑
- 你不能制作更粗的线条(超过 1 个像素)
- 如果0点线只是接触(两边都是正数,一边不是正数,一边是负数)
第二个解决方案可能会解决这些问题,但它是我制作的,没有经过测试,所以它可能有效也可能无效:
您将值分配给 角,然后计算从角开始的每个点到零线的距离。这是查找距离的算法:
def distance(tl, tr, bl, br): # the 4 corners
avg = abs((tl + tr + bl + br) / 4) # getting the absolute average
m = min(map(abs, (tl + tr + bl + br))) # absolute minimum of points
if min == 0: # special case
return float('inf')
return avg / m # distance to 0 point assuming the trend will continue
此 returns 到 0 线的估计距离,您现在可以绘制像素,例如如果你想要一条 5 像素的线,那么如果结果 <4 你绘制像素全彩,elif 像素 <5 你绘制不透明度为距离的像素 - 4(*255
如果你正在使用pygames alpha 选项)
此解决方案假设函数是线性的。
试试吧,最坏的情况下它不起作用...
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.30.1319&rep=rep1&type=pdf
这份 21 页的文档包含了我准确流畅地绘制隐式曲线所需的一切。它甚至涵盖了优化方法并支持隐式函数的分叉点。强烈推荐给任何有类似我上面问题的人。
感谢所有提出建议和澄清问题的人,他们都帮助我找到了这个资源。