画二元函数图像_二元函数怎么画图

画二元函数图像_二元函数怎么画图目录概述字符串表达式解析图像绘制函数作为属性赋值参考以及说明概述本篇博客主要是在上一篇《每个人都该懂点函数式编程》的基础上,进一步说明“函数”在函数式编程中的重要作用。强调了函数和普通类型一样,可以赋

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

目录

 

概述

本篇博客主要是在上一篇《每个人都该懂点函数式编程》的基础上,进一步说明“函数”在函数式编程中的重要作用。强调了函数和普通类型一样,可以赋值、存储、传参以及作为另外函数的返回值。

本文附带了一个Demo,该Demo可以将任意字符串函数表达式解析之后生成对应的函数(一元、二元以及三元),如果你输入的是一元或者二元函数表达式,则可以绘制出相应的函数图像。一元函数图像为平面曲线,二元函数图像为立体曲面。看下图:

画二元函数图像_二元函数怎么画图

画二元函数图像_二元函数怎么画图

函数表达式中只识别X、Y、Z三个自变量。

Github源码下载

 

字符串表达式解析

字符串解析是重点。

怎样去识别一串字符串函数表达式呢?如x^2+sin(x)*cos(y)。之后怎样去计算函数值呢?其实原理很简单,由于每个函数表达式中包含的有效符号是有限的,如X、Y、Z、+、-、*、/以及一些函数诸如log、sin、cos等等,只要我们将这些有效符号均识别筛选出来之后,再根据这些符号的优先级别生成一个函数语法树即可。

画二元函数图像_二元函数怎么画图

如上图所示,使用一个“树结构”去存储最终的语法树。最后带入X、Y(二元)求得函数值。

表达式解析这块难点是语法树的构建和最终求值。语法树的构建有点复杂,大家可以参见源码;最终求值的原理是,判断当前符号(节点)是单目运算符号(如cos、sin、负号等)还是双目运算符号(如+ – * /等),如果是单目运算比如cos函数,则先计算子节点(只有一个子节点)的值,然后将得到的值进行cos运算(Math.Cos(子节点的值));相反,如果是双目运算符比如+符号,那么先计算左子节点和右子节点的值,最后将两个值进行+操作(左子节点的值+右子节点的值),依次递归计算得到最终的函数值。

 

图像绘制

图像绘制这块就比较简单了。根据前一步得到的语法树,我们可以创建出对应的一元函数、二元函数以及三元函数(委托的形式)。事先定义的委托结构如下:

    /// <summary>
    /// 一元函数
    /// </summary>
    /// <param name="x"></param>
    /// <returns></returns>
    public delegate double UnaryFunction(double x);
    /// <summary>
    /// 二元函数
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    public delegate double BinaryFunction(double x,double y);
    /// <summary>
    /// 三元函数
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <param name="z"></param>
    /// <returns></returns>
    public delegate double MultiFunction(double x,double y,double z);

很简单就可以看出,一元函数接收一个参数,返回一个值;二元函数接收两个参数,返回一个值;三元函数接收三个参数,返回一个值。生成委托的过程如下:

   (UnaryFunction)((double x) => { return root.GetValue(x, 0, 0); });
   (BinaryFunction)((double x, double y) => { return root.GetValue(x, y, 0); });
   (MultiFunction)((double x, double y, double z) => { return root.GetValue(x, y, z); });

最终给出对应的x、y、z调用委托,即可得到函数值。

一元函数绘制

随便对X取一个区间(如[-10,10]),以0.1为间距,计算每个X对应的Y值(函数值)。最终将这些点连接起来,出来的就是对应的一元函数图像。

二元函数绘制

相似的,随便对X、Y取一个区间(如X取[-10,10],Y取[-10,10]),X、Y均以0.1为间距,计算每个(X、Y)对应的Z值(函数值),最后将这些三维点绘制成曲面。

 

函数作为属性赋值

经过前几步得到了函数(委托对象),我们直接将委托对象作为属性赋给图像绘制控件,绘图控件更新界面。

   //一元
   if (textBox1.Text.ToLower().Contains('x') && !textBox1.Text.ToLower().Contains('y') && !textBox1.Text.ToLower().Contains('z'))
   {
       UnaryFunction func = (new SyntaxManager().ParseUnaryFunction(textBox1.Text));
       unaryFunctionDrawingBoard1.Function = func;
       tabControl1.SelectedIndex = 0;
   }
   //二元
   else if (textBox1.Text.ToLower().Contains('x') && textBox1.Text.ToLower().Contains('y') && !textBox1.Text.ToLower().Contains('z'))
   {
       BinaryFunction func = (new SyntaxManager().ParseBinaryFunction(textBox1.Text));
       binaryFunctionDrawingBoard1.BinaryFunction = func;
       tabControl1.SelectedIndex = 1;
   }
   //三元
   else
   {
        MultiFunction func = (new SyntaxManager().ParseMultiFunction(textBox1.Text));
        MessageBox.Show("三元函数图像无法绘制!");
   }

如上代码,函数作为属性赋值的示例。

 

参考及说明

1.Demo中有关3D图形绘制参考了网上的一个OpenTK的demo:http://download.csdn.net/detail/dragonflies/3418135#comment

2.函数图像在线生成(为了验证demo生成的图像是否正确)

3.注意 函数绘制时没有做任何区间验证,比如logX中的X不能为负,否则无效(绘制时异常)。这些需要自己注意。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/166555.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 几个数字的组合方式种类个数

    几个数字的组合方式种类个数几个数字的组合方式种类个数

    2022年4月24日
    48
  • 一简单的Ajax例子[通俗易懂]

    一简单的Ajax例子[通俗易懂]—ajax.html http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>http://www.w3.org/1999/xhtml”lang=”en”dir=”ltr”>DevelopingWebApplicationwithAjax-Example//此函数将在电击”ViewXMLdata”链接

    2022年7月26日
    4
  • Navicat Premium 15安装需要注意的几个细节

    Navicat Premium 15安装需要注意的几个细节关于软件的下载和激活的流程,网上有太多文章了,这里就不赘述了。主要记录几个细节问题:安装完NavicatPremium15后,激活之前一定不要打开它!打开它不一定有问题,但可以尽量避免后面的各种错误。 下载完成之后,安装解压的过程尽量在断网的情况下进行!不断网不一定有问题,但可以尽量避免后面出现各种问题!激活的过程中,如果没注意这两种,那可能就是经历什么rsapublickeynotfind,或者输入激活密钥有个红叉号等等各种各样的问题,为了避免一些不必要的麻烦,还是按顺序来吧,希望看到

    2022年10月9日
    0
  • IDEA惊天bug:进程已结束,退出代码-1073741819 (0xC0000005)[通俗易懂]

    IDEA惊天bug:进程已结束,退出代码-1073741819 (0xC0000005)[通俗易懂]由于昨天要写的文章没有写完,于是今天早上我四点半就“自然醒”了,心里面有事,睡觉也不安稳。洗漱完毕后,我打开电脑,正襟危坐,摆出一副要干架的态势,不能再拖了。要写的文章中涉及到一串代码,关于Undertow的一个入门示例,贴出来大家看一下。publicclassUndertowTest{publicstaticvoidmain(finalString[]args)…

    2022年10月3日
    0
  • 高曼数位板触控笔无反应问题

    高曼数位板触控笔无反应问题

    2021年5月17日
    365
  • Android LayoutParams详解「建议收藏」

    Android LayoutParams详解「建议收藏」在平时的开发过程中,我们一般是通过XML文件去定义布局,所以对于LayoutParams的使用可能相对较少。但是在需要动态改变View的布局参数(比如宽度、位置)时,就必须要借助这个重要的类了。本文将结合具体场景详细讲解LayoutParams的相关知识。

    2022年9月21日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号