日期:2014-05-16 浏览次数:20914 次
binzhouweichao@163.com
2013-10-19
修改前面的项目。
在之前的项目中,对数据data的处理是通过手动运算的方法,来放大足够的倍数,以取得合适的视图。
本节,对原始数据data不做处理,只是通过调整坐标系scale的方法来放大视图,得到合适的结果。
1. 修改data的声明定义
为了防止数据丢失,对data数据的类型调整为float,即把Point改成PointF。
打开GlobalVars.cs,将原先对data的定义部分注释掉,修改为:
//类似于#define宏定义,设置三个常量 public const int POINTCNT = 50;//点数,POINTCNT <= XMAX - XMIN //public const int XMAX = 200;//X轴最大值,也就是2π对应的值 //public const int XMIN = 0;//X轴最小值 //public const double times = (XMAX - XMIN) / (2 * Math.PI - 0);//放大倍数 public const float XMAX = (float)(2 * Math.PI);//不放大情况下的x的最大值 public const float XMIN = 0F;//不放大情况下x的最小值 public const float xInterval = (XMAX - XMIN) / (POINTCNT - 1);//i增量对应的data.X增量 //类似于全局变量,可以重新赋值 /* //坐标点变量 private static Point[] data = new Point[POINTCNT]; public static Point[] Data { get { return data; } set { data = value; } } * */ //使用调整坐标系Scale的方法调整视图,对原始数据运算不做处理 private static PointF[] data = new PointF[POINTCNT]; public static PointF[] Data { get { return data; } set { data = value; } }
由于是通过坐标系调整的方法,且data坐标类型为float,所以在计算sin函数值时,直接使用原始数据即可。
打开TriPaint.cs,把对data赋值的地方修改成直接运算:
//对数据进行处理 /* for (int i = 0; i < GlobalVars.POINTCNT; i++) { GlobalVars.Data[i].X = (int)(i * GlobalVars.xInterval);//i对应的data.X GlobalVars.Data[i].Y = (int)(GlobalVars.times * Math.Sin(GlobalVars.Data[i].X / GlobalVars.times));//sin函数求值 GlobalVars.Data[i].Y = (int)(GlobalVars.Data[i].Y + GlobalVars.times * 1);//Y轴向正向平移1,即1*times,令最高点(也就是3π/2对应的-1点)的值为0 } * */ //直接运算,倍数及平移稍后处理 for (int i = 0; i < GlobalVars.POINTCNT; i++) { GlobalVars.Data[i].X = i * GlobalVars.xInterval; GlobalVars.Data[i].Y = (float)(Math.Sin(GlobalVars.Data[i].X)); }
默认坐标系为左上角为顶点,右方为x正向,下方为y正向。
在TriPaint创建g处进行坐标系的修改。
首先,如果使用原始数据,图像最低点-1处位于画布外面,所以将坐标系向y正向平移至少1个单位。
因为下面要用到放大,对于方法ScaleTransform(),解释是方法是将该对象的变换矩阵左乘该缩放矩阵。先平移,再放大。
为了是所有视图在图片框中显示,设置平移为:原点平移到左边框的中点。
g.TranslateTransform(0, pictureBox1.Height / 2);//先平移,原点平移到左边框中点
然后,将整个坐标系关于x轴镜像反转:
g.ScaleTransform(1, -1);//关于x轴镜像