- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
国外有人发现一个鲜为人知的古董级函数作图软件—— GrafEq 。
这个软件只有 2M 大小,它的功能就只有一个:作出形如 x2 + y2 = 1 的二元等式或者不等式的图像。令人惊叹的是,这个软件的图像绘制能力异常强大, Mathematica 等大型专业数学软件完全不是它的对手。
这个软件早就没再更新了。它的“最新版本”是 2.12 ,只支持 Windows 95 到 Windows XP 的系统,或者 PowerPC 7.12 到 MacOS 9.2 的系统,可见其年代久远。神奇的是,这个软件的官方网站依然健在,而且软件竟然也都能下载。如果你有幸还能装上这款软件,你将有机会重温一次 Windows 95 时代的软件安装画面。
一些带有三角函数的方程,某些地方的图像变化非常剧烈,连 Mathematica 也无法准确地描绘出来:
然而, GrafEq 却能很好地描绘出来:
注意,方程的图像显然无法形成实心的方块,这只是因为图像太密集罢了。
既然有机会见到各种方程图像的真容,我们当然要多尝试一些更复杂的方程。下面是另外几个例子:
要比哪个图像最帅,还是要数 GrafEq 官方网站上提供的一个示例:
2012-11-30 Update:
今天,碰巧看到了这个软件的来头。这个软件的算法是 Jeff Tupper 在 2001 年的一篇论文中提出的,感兴趣的读者可以在这里看到: /people/mooncake/papers/SIGGRAPH2001_Tupper.pdf
在这篇论文中, Jeff Tupper 创作了很多漂亮的函数图像,其中一个就是著名的 Tupper 自我指涉公式 。论文中还有几个精彩的图像,分别重新绘制了一遍,贴出来和大家一同分享。
以上原文From : /blog/archives/4447/,
原文内容遵从CC版权协议
Copy Right :
GPU异构计算:复杂函数图像绘制
之前技术大牛Vczh同学开发了一个函数图像绘制程序, 可以画出方程f(x,y)=0的图像。原理是假设f(x, y)是处处可微的,用图像上每一点的坐标带入函数f得到针对x和y的两个方程,再用牛顿迭代法求解,这样所有的点最后就会收敛到一个点集,然后画到图像上。用他的程序可以画出各种各样令人惊叹的方程图形。但是他的程序非常慢,因为对每一个点坐标都用牛顿迭代法求解是一项很费时的任务,即使采用了 Parallel.For,CPU算起来也很吃力。经过研究程序之后觉得可以用擅长并行计算的显卡来加速迭代法求解的过程。用OpenCL来完成这个任务再合适不过了。
整个过程还是相当顺利的,完全在原始程序的基础上改成。仅稍微改变了策略。步骤如下:
解析输入函数f(x,y)之后,分别生成?f/?x和?f/?y两个偏导数,然后将这三个二元函数转化为合法的OpenCL表达式。
用OpenCL实现牛顿迭代法。
将图像上的每一点分派到一个OpenCL线程,然后由无数并行的OpenCL线程计算自己的点。
其中OpenCL代码如下:
fp_t func(fp_t x, fp_t y){return {动态生成};}fp_t df_dx(fp_t x, fp_t y){return {动态生成};}fp_t df_dy(fp_t x, fp_t y){return {动态生成};}fp_t solvex(fp_t start, const fp_t consty){for (int i = 0; i MAX_ITER; ++i){fp_t result = func(start, consty);if (result = EPSILON result = -EPSILON){return start;}fp_t d = df_dx(start, consty);if (d = EPSILON d = -EPSILON){return NAN;}else{start -= result / d;}}return NAN;}kernel void ComputeX(global write_only fp_t* points,int unit,int width,int cx,int cy,float origin_x,float origin_y){int gx = get_global_id(0);int gy = get_global_id(1);uint write_loc = gx + gy * width;fp_t py = origin_y + (fp_t)(gy + 1 - cy)
文档评论(0)