画函数图形的C#程序(改进版) (转)

我在10月份发表过一篇随笔“画函数图形的C#程序,兼论一个病态函数”,在那篇随笔中写道:
这个画函数图形的C#程序有一个严重的缺点,就是函数表达式是直接写的源程序中的,不能象SciLab和Matlab那样交互式地输入。 后来,根据“空间/IV”的评论,我写了个动态生成用户输入的函数表达式的类,用以改进这个画函数图形的C#程序。下面是该程序的运行效果:
Plot-v2-01.PNG
Plot-v2-02.PNG
可以看到,不但要画的函数的表达式可以由用户动态地输入,而且函数自变量的范围也可以是常量表达式。 下面就是源程序:
None.gif// plot.cs: 画函数图形, 编译方法: csc /t:winexe plot.cs Expression.cs
None.gif
using System;
None.gif
using System.Drawing;
None.gif
using System.Windows.Forms;
None.gif
using Skyiv.Util;
None.gif
None.gif
namespace Skyiv.Ben.Plot
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif  
sealed class PlotForm : Form
ExpandedSubBlockStart.gifContractedSubBlock.gif  
dot.gif{
InBlock.gif    
const int yBase = 24// 屏幕保留区域的高度
InBlock.gif

InBlock.gif    TextBox tbxX0, tbxX1;  
// 函数自变量的取值范围
InBlock.gif
    TextBox tbxExpression; // 函数的表达式
InBlock.gif
    
InBlock.gif    PlotForm()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      SuspendLayout();
InBlock.gif      
InBlock.gif      Button btnSubmit 
= new Button();
InBlock.gif      btnSubmit.Text 
= "刷新";
InBlock.gif      btnSubmit.Location 
= new Point(00);
InBlock.gif      btnSubmit.Size 
= new Size(4824);
InBlock.gif      btnSubmit.Click 
+= new EventHandler(BtnSubmit_Click);
InBlock.gif
InBlock.gif      tbxX0 
= new TextBox();
InBlock.gif      tbxX0.Text 
= "-Math.PI";
InBlock.gif      tbxX0.Location 
= new Point(553);
InBlock.gif      tbxX0.Size 
= new Size(10020);
InBlock.gif
InBlock.gif      tbxX1 
= new TextBox();
InBlock.gif      tbxX1.Text 
= "Math.PI";
InBlock.gif      tbxX1.Location 
= new Point(1603);
InBlock.gif      tbxX1.Size 
= new Size(10020);
InBlock.gif
InBlock.gif      tbxExpression 
= new TextBox();
InBlock.gif      tbxExpression.Text 
= "Math.Sin(x)";
InBlock.gif      tbxExpression.Location 
= new Point(2653);
InBlock.gif      tbxExpression.Size 
= new Size(33520);
InBlock.gif      tbxExpression.Anchor 
= (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif      Controls.AddRange(
new Control[]dot.gif{btnSubmit, tbxX0, tbxX1, tbxExpression});
InBlock.gif      Text 
= "Plot";
InBlock.gif      BackColor 
= Color.White;
InBlock.gif      ClientSize 
= new Size(600600 + yBase);
InBlock.gif      
// WindowState = FormWindowState.Maximized;
InBlock.gif

InBlock.gif      ResumeLayout(
false);
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
// 点击“刷新”按钮时重绘程序主窗口
InBlock.gif
    void BtnSubmit_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      Invalidate();
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//*
InBlock.gif    // 因为本程序使用 C# 的反射功能动态生成数学表达式并计算其值
InBlock.gif    // 所以重画时有点慢,如果你的计算机的速度不是非常快的,
InBlock.gif    // 就不要在窗口改变大小时强制重绘,而是通过点击发“刷新”按钮重绘。
InBlock.gif    protected override void OnSizeChanged(EventArgs e)
InBlock.gif    {
InBlock.gif      Invalidate();
InBlock.gif      base.OnSizeChanged(e);
InBlock.gif    }
ExpandedSubBlockEnd.gif    
*/

InBlock.gif    
InBlock.gif    
protected override void OnPaint(PaintEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      Graphics gc 
= e.Graphics;
InBlock.gif      
try
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif        
double x0 = new Expression(tbxX0.Text).Compute(0);
InBlock.gif        
double x1 = new Expression(tbxX1.Text).Compute(0);
InBlock.gif        Size size 
= ClientSize;
InBlock.gif        
int i0 = 0;
InBlock.gif        
int i1 = size.Width - 1;
InBlock.gif        
int j0 = yBase;
InBlock.gif        
int j1 = size.Height - 1;
InBlock.gif        Pen pen 
= new Pen(Color.Black, 1);
InBlock.gif        gc.DrawLine(pen, i0, j0, i1, j0); 
// 画图区和保留区的分界线
InBlock.gif
        double rx = (x1 - x0) / (i1 - i0);
InBlock.gif        
double y0, y1;
InBlock.gif        Expression fx 
= new Expression(tbxExpression.Text);
InBlock.gif        GetFunctionValueRange(fx, x0, rx, i0, i1, 
out y0, out y1);
InBlock.gif        
double ry = (y1 - y0) / (j1 - j0);
InBlock.gif        Out(gc, 
0"ClientSize: {0}x{1}", i1 - i0 + 1, j1 - j0 + 1);
InBlock.gif        Out(gc, 
1"f(x): " + tbxExpression.Text);
InBlock.gif        Out(gc, 
2"x:[{0}, {1}] range:{2}", x0, x1, x1 - x0);
InBlock.gif        Out(gc, 
3"y:[{0}, {1}] range:{2}", y0, y1, y1 - y0);
InBlock.gif        Out(gc, 
4"rx:{0}"1 / rx);  // 函数自变量每单位值用多少个象素表示
InBlock.gif
        Out(gc, 5"ry:{0}"1 / ry);  // 函数的值每单位值用多少个象素表示
InBlock.gif
        Out(gc, 6"r :{0}", rx / ry); // 该值如果小于1表示图形纵向被压扁,反之则被拉伸
InBlock.gif
        pen.Color = Color.Green;
InBlock.gif        
int j = j1 + (int)(y0 / ry);
InBlock.gif        
if (j >= j0 && j <= j1) gc.DrawLine(pen, i0, j, i1, j); // x坐标轴
InBlock.gif
        int i = i0 - (int)(x0 / rx);
InBlock.gif        
if (i >= i0 && i <= i1) gc.DrawLine(pen, i, j0, i, j1); // y坐标轴
InBlock.gif
        pen.Color = Color.Red;
InBlock.gif        
for (i = i0; i <= i1; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif          
double x = x0 + (i - i0) * rx;
InBlock.gif          
double y = fx.Compute(x);
InBlock.gif          
if (double.IsInfinity(y) || double.IsNaN(y)) continue;
InBlock.gif          j 
= j1 - (int)((y - y0) / ry);
InBlock.gif          
if (j > j1 || j < j0) continue;
InBlock.gif          gc.DrawLine(pen, i, j, i 
+ 1, j); // 画函数的图形
ExpandedSubBlockEnd.gif
        }

ExpandedSubBlockEnd.gif      }

InBlock.gif      
catch (Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif        Out(gc, 
0, ex.Message);
ExpandedSubBlockEnd.gif      }

InBlock.gif      
base.OnPaint(e);
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
// 函数值的取值范围
InBlock.gif
    void GetFunctionValueRange(Expression fx, double x0, double rx, int i0, int i1, out double y0, out double y1)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      y0 
= double.MaxValue;
InBlock.gif      y1 
= double.MinValue;
InBlock.gif      
for (int i = i0; i <= i1; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif        
double x = x0 + (i - i0) * rx;
InBlock.gif        
double y = fx.Compute(x);
InBlock.gif        
if (double.IsInfinity(y) || double.IsNaN(y)) continue;
InBlock.gif        
if (y0 > y) y0 = y;
InBlock.gif        
if (y1 < y) y1 = y;
ExpandedSubBlockEnd.gif      }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
// 在指定的位置写字符串
InBlock.gif
    void Out(Graphics gc, int line, string fmt, params object [] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      gc.DrawString(
string.Format(fmt, args), new Font("Courier New"10), Brushes.Blue, new PointF(5, yBase + 15 * line));
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
static void Main()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      Application.Run(
new PlotForm());
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockEnd.gif  }

ExpandedBlockEnd.gif}

None.gif

转载于:https://www.cnblogs.com/gjahead/archive/2007/08/18/861164.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Swift-UITextView占位文字及占位文字颜色扩展(可在xib中直接使用)

使用案例 extension UITextView {private struct RuntimeKey {static let hw_placeholderLabelKey UnsafeRawPointer.init(bitPattern: "hw_placeholderLabelKey".hashValue)/// ...其他Key声明}/// 占位文字IBInspectable public var placeholder: String {get {re…

Easy.Ajax 部分源代码, 支持文件上传功能, 兼容所有主流浏览器

下面是Easy.Ajax类的初稿&#xff0c;如须发表&#xff0c;在代码上还要修改以达到最简&#xff0c;但API是不会变了&#xff0c; Easy.Ajax (function (WINDOW) {ajax {proxyPool: {length: function () {var i 0;for (var p in this)i;return i - 1;}},index: 0,clearCach…

Java 8中Lambda表达式的阴暗面

这篇文章可能不会使我成为任何新朋友。 哦&#xff0c;好吧&#xff0c;无论如何我从来没有真正在学校受到欢迎。 但是&#xff0c;让我们说清楚。 就语言而言&#xff0c;Java 8的最大特色无疑是Lambda表达式。 几年来&#xff0c;它一直是功能语言&#xff08;例如Scala和Clo…

复旦大学长跑协会财务制度(初稿)

(一)活动资金来源及主要支出 1、资金主要来源&#xff1a;会费、学校的拨款&#xff0c;私人捐助、企业赞助等。 2、活动性支出&#xff1a;活动宣传、场地租用费、租借多媒体仪器费用及活动经费。事物性支出&#xff1a;协会运作所需物资(如文具等硬件)。 (二)财务报销原则 1、…

JQ实现弹幕效果

JQ实现弹幕效果&#xff0c;快来吐糟你的想法吧 效果图&#xff1a; 代码如下&#xff0c;复制即可使用&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>JQ实现弹幕效果</title><style type"t…

Iterator作用

前言 下面的内容是我从百度知道拷贝出来的&#xff0c;也就不在贴出链接了。我总结下就是迭代器在集合中使用&#xff0c;用户不需要关心具体集合实现的是如何遍历&#xff08;不暴露细节&#xff09;&#xff0c;按照迭代器的方式遍历。 作用 Iterator模式是用于遍历集合类的标…

Django:URL映射

导航 跳转&#xff1a;视图简介 跳转&#xff1a;URL映射 跳转&#xff1a;一、URL中添加参数 跳转&#xff1a;二、指定默认的参数 跳转&#xff1a;三、URL中包含另一个urls模块 跳转&#xff1a;  include函数 跳转&#xff1a;四、path函数 跳转&#xff1a;  自定义ur…

php-v 查看不到版本,解決php -v查看到版本於phpinfo()打印的版本不一致問題

整個事件的起因是這樣的通過git拉取laraevl項目發現缺少.env文件&#xff0c;打算使用composer install生成一個.env文件&#xff0c;然后提示composer最低使用php版本7.1.3而檢測到我的版本為5.4.16。提示如下&#xff1a;然后使用phpinfo打印一下發現版本是7.2.6。打印結果如…

将jOOQ与Spring结合使用:排序和分页

JOOQ是一个库&#xff0c;可以帮助我们控制SQL。 它可以从我们的数据库生成代码&#xff0c;并允许我们使用其流畅的API来构建类型安全的数据库查询。 本教程前面的部分向我们介绍了如何配置应用程序的应用程序上下文&#xff0c;如何从数据库生成代码以及如何将CRUD操作添加到…

获取表的所有列名

selectname fromsyscolumns whereidobject_id(表名)下面这样也可以:selectcolumn_name frominformation_schema.columns wheretable_name news转载于:https://www.cnblogs.com/zhuboxingzbx/archive/2007/09/03/880049.html

天下武功唯快不破------实验吧

题目地址&#xff1a;http://www.shiyanbar.com/ctf/1854 打开链接 全是英文&#xff0c;能力有限&#xff0c;翻译一下&#xff0c;好像没其他东西了&#xff0c;查看一下源码 让用post请求&#xff0c;丢到burp改一下 看到response有一个FLAG: UDBTVF9USElTX1QwX0NINE5HRV9GT…

JS实现文本中查找并替换字符

JS实现文本中查找并替换字符 效果图&#xff1a; 代码如下&#xff0c;复制即可使用&#xff1a; <!DOCTYPE html><html> <head><style type"text/css">*{font-family:"微软雅黑";font-size:16px;margin:0;padding:0;letter-spaci…

数据依赖的公理系统

ArmStrong公理系统 学习数据依赖的公理系统是进行模式分解的算法的理论基础。而Armstrong公理系统是一个具有有效性和完备性的公理系统。 U是属性总体&#xff0c;F是函数依赖&#xff0c;对于R<U,F>推理规则如下&#xff1a; A1 自反律 &#xff1a;若Y⊆X⊆U&#xff0…

在没有IDE的情况下编译和运行Java

最近一个名为“ 不使用IDE编译Java软件包 ”的Java subreddit线程提出了一个问题&#xff1a;“是否有一个命令将软件包内的一组Java文件编译到一个单独的文件夹中&#xff08;以下简称为bin&#xff09;&#xff0c;以及如何我会去运行新的类文件吗&#xff1f;” 该帖子的作者…

java statement 返回类型,6.3 返回类型和返回语句 | Return type Return statement

无返回值函数对于返回类型是void的函数&#xff0c;return后不跟表达式。最后的 return; 可以没有而让程序隐式执行。在void函数中的return语句还有提前使函数退出的作用而不进行接下来的计算&#xff0c;如定义一个swap函数在二者相同时不继续运算直接退出&#xff1a;void sw…

异步调用 (转载)

异步操作通常用于执行完成时间可能较长的任务&#xff0c;如打开大文件、连接远程计算机或查询数据库。异步操作在主应用程序线程以外的线程中执行。应用程序调用方法异步执行某个操作时&#xff0c;应用程序可在异步方法执行其任务时继续执行。.NET框架能够对任何方法进行异步…

《Effective Java》读书笔记 Item 1:考虑静态工厂方法,而不是构造器

众所周知&#xff0c;要想能获取一个类的实例&#xff0c;该类得要提供一个public的构造器。但是《Effective Java》书中说还有一个方法&#xff0c;那就是提供静态工厂方法&#xff08;static factory method&#xff09;&#xff0c;该方法时静态&#xff0c;同时可以根据参数…

[转]MySQL 表锁和行锁机制

本文转自&#xff1a;http://www.cnblogs.com/itdragon/p/8194622.html MySQL 表锁和行锁机制 行锁变表锁&#xff0c;是福还是坑&#xff1f;如果你不清楚MySQL加锁的原理&#xff0c;你会被它整的很惨&#xff01;不知坑在何方&#xff1f;没事&#xff0c;我来给你们标记几个…

使用JS实现文字搬运工

使用JS实现文字搬运工 效果图&#xff1a; 代码如下&#xff0c;复制即可使用&#xff1a; <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetUTF-8"> <title>使用JS实现文字搬运工&…

ActiveMQ –经纪人网络解释–第3部分

现在&#xff0c;我们已经在本博客系列的第1部分和第2 部分中了解了ActiveMQ网络连接器的基础&#xff0c;在第3部分中&#xff0c;我们将研究ActiveMQ如何平衡连接到代理网络的使用者。 介绍 当可以无序处理队列中的消息时通常使用并发使用者&#xff0c;通常可以提高消息吞吐…