【笔记】【C# 二维三维图形绘制工程实例宝典】 第04章 二维矩阵和变换

4.1 矩阵基础和变换

矩阵在变换处理中承担了一个相当重要的角色。一个矩阵就是一个二维数组,最为常用的几何变换都是线性变换,这包括旋转缩放、切变、对称以及正投影。在二维空间中,线性变换可以用2*2的矩阵表示,但是平移却不能应用线性变换的2*2矩阵表示,为了能在矩阵中处理所有的变换操作,将引入其次坐标的概念。

4.2 齐次坐标

在其次坐标中,二维空间内的所有变换,包括缩放、对称、旋转、平移等,都是通过矩阵的运算来进行处理的。所谓其次坐标就用一个N+1维向量来表示N维的向量。它提供了用矩阵运算把二维、三维甚至多维空间中的一个点集从一个坐标系变换到另一个坐标系的有效方法。在齐次坐标中,我们可以将一个二维空间的点A(X,Y)表示为A0(X,Y,W),W表示了一个虚拟的坐标值 。如果W非零,点A0(X,Y,W)可以表示为A1(X/W, Y/W, 1),此时的X/W, Y/W被称为齐次坐标系中的点坐标。当W为零时,该点被称为无穷远点。齐次坐标中二维空间的矩阵由3*3矩阵表示。

4.2.1 齐次坐标中的缩放

| x1 |   | Sx 0  0 | | x |
| y1 | = | 0  Sy 0 | | y | <==> P1 = S(Sx, Sy)P
| 1  |   | 0  0  1 | | 1 |

如果点P通过S(Sx1, Sy1)缩放到点P1,点P1再通过S(Sx2, Sy2)缩放到点P2。持续的缩放其结果就是点之间的连续相乘。

P1 = S(Sx1, Sy1)P   |
                    | ===> P2 = (S(Sx1, Sy1) * S(Sx2, Sy2)) * P
P2 = S(Sx2, Sy2)P1  |

-------------------------------------------------------------------------------------------

| Sx1 0   0 |   | Sx2 0   0 |   | Sx1Sx2 0      0 |
| 0   Sy1 0 | * | 0   Sy2 0 | = | 0      Sy1Sy2 0 |
| 0   0   1 |   | 0   0   1 |   | 0      0      1 |

4.2.2 齐次坐标中的平移

                      | 1  0  0 |
| x1 y1 1 | = |x y| * | 0  1  0 | <===> P1 = T(dx, dy)P
                      | dx dy 1 |

-------------------------------------------------------------------------------------------
            | 1  0  0 |
T(dx, dy) = | 0  1  0 |
            | dx dy 1 |

如果点P通过T(dx1, dy1)平移到点P1,点P1再通过T(dx2,dy2)平移到点P2。连续平移如下实现。

P1 = T(dx1, dy1)P   |
                    | ===> P2 = (T(dx1, dy1) * T(dx2, dy2)) * P
P2 = T(dx2, dy2)P1  |

-------------------------------------------------------------------------------------------

| 1   0   0 |   | 1   0   0 |   | 1         0         0|
| 0   1   0 | * | 0   1   0 | = | 0         1         0|
| dx1 dy1 1 |   | dx2 dy2 1 |   | dx1 + dx2 dy2 + dy2 1|

4.2.3 齐次坐标中的旋转

假设已知点(x, y)与X轴正方向的夹角为ф,r = sqrt(x*x + y*y), 则有如下等式:
x = rcosф
y = rsinф
-------------------------------------------------------------------------------------------
顺时针旋转θ角后得到点(x1, y1)
x1 = rcos(ф + θ) = r(cosфcosθ - sinфsinθ) = xcosθ - ysinθ
y1 = rsin(ф + θ) = r(sinфcosθ + cosфsinθ) = xcosθ + ysinθ

                       |  cosθ sinθ |
| x1 y1 | = | x, y | * |            |
                       | -sinθ cosθ |
-------------------------------------------------------------------------------------------
逆时针旋转θ角后得到点(x2, y2)
x2 = rcos(ф - θ) = r(cosфcosθ + sinфsinθ) = xcosθ + ysinθ
y2 = rsin(ф - θ) = r(sinфcosθ - cosфsinθ) = xcosθ - ysinθ

                       | cosθ -sinθ |
| x1 y1 | = | x, y | * |            |
                       | sinθ  cosθ |

4.2.4 变换组合

在图形应用程序中,对于一个图形对象的变换往往是多种变换的组合。例如,你可能想先对一个图形先进行缩放,然后进行旋转变换,你可以通过结果一系列基本的矩阵变换来达到期望的结果。考虑这样一种情形,在点P1处将长方形顺时针旋转一个角度,因为仅知道在原点处如何旋转长方形,所以你需要将这个原始的问题分解为几个独立不同的问题。

  • 平移长方形使得P1点到达原点处
  • 顺时针旋转长方形到指定角度
  • 平移长方形使得原点返回到P1点
                       |1  0    0| | cosθ sin0 0| |1 0    0|
T(-X,-Y)*R(θ)*T(X,Y) = |0  1    0|*|-sinθ cosθ 0|*|0 1    0|
                       |-x1 -y1 1| | 0    0    1| |x1 y1  1|

                       | cos0              sin0              0|
                     = |-sin0              cos0              0|
                       | x1(1-cos0)+y1sin0 y1(1-cos0)-x1sin0 1|

|X1 Y1 1| = |X Y 1| * T(-X,-Y)*R(θ)*T(X,Y)

4.2.5 GDI+中矩阵的定义

使用新坐标 = 旧坐标 * 齐次变换矩阵的方式进行的变换,齐次坐标系统中变换矩阵总是有最后一列(0, 0, 1)。GDI+中矩阵类的定义是将6个元素分别排列到3行2列位置上的3*2矩阵,计算时在矩阵的最后添加一列(0, 0, 1)。

|1 0|        |1 0 0|
|0 1| <====> |0 1 0|
|0 0|        |0 0 1|

在C#中,可以通过一个点集数组,应用矩阵类的重载构造函数定义一个矩阵对象。以下的代码段描述了如何定义平移、缩放和旋转的矩阵对象。

float dx    = 3f;
float dy    = 2f;
float sx    = 0.5f;
float sy    = 1.5f;
float theta = (float)Math.PI/4;
float sin   = (float)Math.Sin(theta);
float cos   = (float)Math.Cos(theta);

Matrix tm = new Matrix(1,0,0,1,dx,dy);
Matrix sm = new Matrix(sx,0,0,sy,0,0);

// 顺时针旋转45
Matrix rm = new Matrix(cos, sin, -sin, cos, 0, 0);

矩阵类提供了一些非常有用的属性:

  • Elements   - 返回一个包括矩阵元素的数组
  • IsIdentity    - 如果矩阵是其次矩阵,返回true
  • IsInvertible - 如果矩阵可逆,返回true
  • OffsetX      - 返回矩阵的X偏移量
  • OffsetY      - 返回矩阵的Y偏移量

4.2.6 C#中的矩阵操作

矩阵类提供了许多方法函数来实现图形对象的旋转、缩放和平移。它也提供了几个方法来实现矩阵的操作。

  • Reset    - 调用该方法将把矩阵回置为同次矩阵
  • Invert    - 用于逆转矩阵,如果矩阵可逆
  • Multiply - 实现两个矩阵之间的乘法并将结果存入第一个矩阵。

Multiply(const Matrix matrix, MatrixOrder order)中参数matrix指明作为乘数的矩阵,order用于指定乘数矩阵放置的位置。Append指定乘数矩阵在右边;Prepend指定乘数矩阵在左边。

MSDN >> MatrixOrder Enum

  • Append  - 在旧操作后应用新操作
  • Prepend - 在旧操作前应用新操作

4.2.7 C#中基本的矩阵变换

  • Translate - 平移一个矩阵
  • Rotate     - 以原点为中心旋转矩阵
  • RotateAt  - 以指定的中心点旋转矩阵
  • Scale       - 缩放矩阵
  • Shear      - 矩阵切变

4.3 C#中图形对象的变换

以下示例完成对一图片的各种基本变换

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace Example
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void DrawAxes(Graphics g, bool flipY)
        {
            /*
             * 注意:
             * 1. Graphics.Transform 仅存储矩阵变换,并不执行矩阵变换
             * 2. 绘图坐标系,X轴正方向水平向右;Y轴正方向垂直向下
             */
            // 获取初始变换矩阵
            Matrix mm = g.Transform;
            var p = new Pen(Brushes.Red, 1);

            // 初始矩阵
            var m = new Matrix();

            // 移动世界坐标大绘图区域中心位置
            m.Translate(200, 200);
            g.Transform = m;

            g.DrawLine(p, -200, 0,    200, 0);
            g.DrawLine(p, 0,    -200, 0,   200);

            // 获知垂直坐标轴的标尺与标签
            for (int i = -150; i <= 150; i += 50)
            {
                var halfHeight = 0f;
                if(i != 0)
                    halfHeight = g.MeasureString(i.ToString(), this.Font).Height / 2f;
                
                // 根据Y轴的正方向的不同,绘制不同的标签
                g.DrawString(i.ToString(), this.Font, Brushes.Red, 5, flipY ? -i - halfHeight : i - halfHeight);

                // 绘制垂直坐标轴的水平标签
                g.DrawLine(p, -5, i, 5, i);
            }

            // 绘制水平轴的标签
            for (int i = -150; i <= 150; i += 50)
            {
                if (i==0) continue;
                
                g.DrawLine(p, i, -5, i, 5);
                var stringSize = g.MeasureString(i.ToString(), this.Font);
                g.DrawString(i.ToString(), this.Font, Brushes.Red, i-stringSize.Width / 2, 5);
            }
            
            // 绘制坐标轴箭头
            var pathH = new GraphicsPath(new PointF[]{      new PointF(185, -5),      new PointF(200,  0),      new PointF(185,  5)},
                                         new   byte[]{(byte)PathPointType.Start, (byte)PathPointType.Line, (byte)PathPointType.Line});
            g.FillPath(Brushes.Red, pathH);
            
            var flip = cbFlipY.CheckState == CheckState.Checked ? -1 : 1;
            var pathV = new GraphicsPath(new PointF[]{new PointF(-5, 185 * flip), new PointF(0,  200 * flip), new PointF(5,  185 * flip)},
                                         new   byte[]{( byte)PathPointType.Start,   (byte)PathPointType.Line, (byte)PathPointType.Line});
            
            g.FillPath(Brushes.Red, pathV);

            g.Transform = mm;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 创建一个图像,用于作为绘图背景
            Image img = new Bitmap(400, 400);
            pictureBox1.Image = img;
            Graphics g = Graphics.FromImage(pictureBox1.Image);

            // 绘制坐标轴
            DrawAxes(g, (cbFlipY.CheckState == CheckState.Checked));

            // 创建用于移动绘图位置的变换矩阵
            var mm = new Matrix();

            // 是否翻转Y轴
            if (cbFlipY.CheckState == CheckState.Checked)
                mm = new Matrix(1, 0, 0, -1, 0, 0);
            
            // 平移中心
            mm.Translate(200, 200, MatrixOrder.Append);
            g.Transform = mm;
            

            // 创建用于图像变换的矩阵
            var mm1 = new Matrix();


            for (int i = 0; i < listBox1.Items.Count; i++)
            {
                // 如果旋转图像翻转,则显示坐标系由左手坐标系变为右手坐标系
                // 左手坐标系顺时针为正,右手坐标系逆时针为正
                if (listBox1.Items[i].ToString() == "Rotate")
                    mm1.RotateAt((cbFlipY.CheckState == CheckState.Checked ? -1 : 1) * int.Parse(lblRotDeg.Text), new Point(int.Parse(lblRotX.Text), int.Parse(lblRotY.Text)), MatrixOrder.Append);

                if (listBox1.Items[i].ToString() == "Translation")
                    mm1.Translate(int.Parse(lblTransX.Text), int.Parse(lblTransY.Text), MatrixOrder.Append);

                if (listBox1.Items[i].ToString() == "Scale")
                    mm1.Scale(float.Parse(lblStrX.Text), float.Parse(lblStrY.Text), MatrixOrder.Append);
                
                if (listBox1.Items[i].ToString() == "Shear")
                    mm1.Shear(float.Parse(lblShearX.Text), float.Parse(lblShearY.Text), MatrixOrder.Append);
            }

            var imgpic = (Image)pictureBoxBase.Image.Clone();
            var gp = new GraphicsPath();
            
            // DrawImage(Image, PointF[]) 函数要求输入平行四边形的三个顶点,且顺序为左上,右上,左下,第四个点通过计算自动获得
            if (cbFlipY.CheckState == CheckState.Checked)
                gp.AddPolygon(new Point[] { new Point(0, imgpic.Height), new Point(imgpic.Width, imgpic.Height), new Point(0, 0) });
            else
                gp.AddPolygon(new Point[] { new Point(0, 0), new Point(imgpic.Width, 0), new Point(0, imgpic.Height) });

            gp.Transform(mm1);
            PointF[] pts = gp.PathPoints;

            g.DrawImage(imgpic, pts);

            pictureBox1.Refresh();

        }

        private void tRotDeg_ValueChanged(object sender, EventArgs e)
        {
            lblRotDeg.Text = tRotDeg.Value.ToString();
            cbRotate.CheckState = CheckState.Checked;
            if (cbRealtime.CheckState == CheckState.Checked)
            {
                button1_Click(sender, null);
            }
        }

        private void tRotX_ValueChanged(object sender, EventArgs e)
        {
            lblRotX.Text = tRotX.Value.ToString();
            cbRotate.CheckState = CheckState.Checked;
            if (cbRealtime.CheckState == CheckState.Checked)
            {
                button1_Click(sender, null);
            }
        }

        private void tRotY_ValueChanged(object sender, EventArgs e)
        {
            lblRotY.Text = tRotY.Value.ToString();
            cbRotate.CheckState = CheckState.Checked;
            if (cbRealtime.CheckState == CheckState.Checked)
            {
                button1_Click(sender, null);
            }
        }

        private void tTransX_ValueChanged(object sender, EventArgs e)
        {
            lblTransX.Text = tTransX.Value.ToString();
            cbTranslation.CheckState = CheckState.Checked;
            if (cbRealtime.CheckState == CheckState.Checked)
            {
                button1_Click(sender, null);
            }
        }

        private void tTransY_ValueChanged(object sender, EventArgs e)
        {
            lblTransY.Text = tTransY.Value.ToString();
            cbTranslation.CheckState = CheckState.Checked;
            if (cbRealtime.CheckState == CheckState.Checked)
            {
                button1_Click(sender, null);
            }
        }

        private void tStrX_ValueChanged(object sender, EventArgs e)
        {
            lblStrX.Text = String.Format("{0:0.0}", (tStrX.Value / 10.0));
            cbStretch.CheckState = CheckState.Checked;
            if (cbRealtime.CheckState == CheckState.Checked)
            {
                button1_Click(sender, null);
            }
        }

        private void tStrY_ValueChanged(object sender, EventArgs e)
        {
            lblStrY.Text = String.Format("{0:0.0}", (tStrY.Value / 10.0));
            cbStretch.CheckState = CheckState.Checked;
            if (cbRealtime.CheckState == CheckState.Checked)
            {
                button1_Click(sender, null);
            }
        }

        private void tShearX_ValueChanged(object sender, EventArgs e)
        {
            lblShearX.Text = String.Format("{0:0.0}", (tShearX.Value / 10.0));
            cbShear.CheckState = CheckState.Checked;
            if (cbRealtime.CheckState == CheckState.Checked)
            {
                button1_Click(sender, null);
            }
        }

        private void tShearY_ValueChanged(object sender, EventArgs e)
        {
            lblShearY.Text = String.Format("{0:0.0}", (tShearY.Value / 10.0));
            cbShear.CheckState = CheckState.Checked;
            if (cbRealtime.CheckState == CheckState.Checked)
            {
                button1_Click(sender, null);
            }
        }

        private void cbRotate_CheckedChanged(object sender, EventArgs e)
        {
            UpdateListBox((CheckBox)sender, "Rotate");
        }

        private void cbTranslation_CheckedChanged(object sender, EventArgs e)
        {
            UpdateListBox((CheckBox)sender, "Translation");
        }

        private void cbStretch_CheckedChanged(object sender, EventArgs e)
        {
            UpdateListBox((CheckBox)sender, "Scale");
        }

        private void cbShear_CheckedChanged(object sender, EventArgs e)
        {
            UpdateListBox((CheckBox)sender, "Shear");
        }

        private void cbFlipY_CheckedChanged(object sender, EventArgs e)
        {
            button1_Click(sender, null);
        }

        private void buttonUp_Click(object sender, EventArgs e)
        {
            int index = listBox1.SelectedIndex;
            if ((index) <= 0) return;
            string s = (string)listBox1.Items[index];
            listBox1.Items.RemoveAt(index);
            listBox1.Items.Insert(index - 1, s);
            listBox1.SelectedIndex = index - 1;
            if (cbRealtime.CheckState == CheckState.Checked)
            {
                button1_Click(sender, null);
            }
        }

        private void buttonDown_Click(object sender, EventArgs e)
        {
            int index = listBox1.SelectedIndex;
            if (index >= listBox1.Items.Count - 1) return;
            if ((index) <= -1) return;
            string s = (string)listBox1.Items[index];
            listBox1.Items.RemoveAt(index);
            listBox1.Items.Insert(index + 1, s);
            listBox1.SelectedIndex = index + 1;
            if (cbRealtime.CheckState == CheckState.Checked)
            {
                button1_Click(sender, null);
            }
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            Form1_Load(sender, null);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            tRotDeg.Value=0;
			tRotX.Value=0;
			tRotY.Value=0;

			lblRotDeg.Text=tRotDeg.Value.ToString();
			lblRotX.Text=tRotX.Value.ToString();
			lblRotY.Text=tRotY.Value.ToString();

			tTransX.Value =0;
			tTransY.Value=0;

			lblTransX.Text=tTransX.Value.ToString();
			lblTransY.Text=tTransY.Value.ToString();

			tStrX.Value =10;
			tStrY.Value =10;

			lblStrX.Text=String.Format("{0:0.0}",(tStrX.Value /10.0));
			lblStrY.Text=String.Format("{0:0.0}",(tStrY.Value/10.0));

			tShearX.Value =0;
			tShearY.Value=0;

			lblShearX.Text=String.Format("{0:0.0}",(tShearX.Value/10.0));
			lblShearY.Text=String.Format("{0:0.0}",(tShearY.Value/10.0));

			cbFlipY.CheckState=CheckState.Checked;
			cbRotate.CheckState=CheckState.Unchecked;
			cbTranslation.CheckState=CheckState.Unchecked;
			cbStretch.CheckState =CheckState.Unchecked;
			cbShear.CheckState=CheckState.Unchecked;

			button1_Click(this,null);

		}
        private void UpdateListBox(CheckBox cb, String s)
        {
            if (cb.CheckState == CheckState.Checked)
            {
                bool found = false;
                for (int i = 0; i < listBox1.Items.Count; i++)
                    if (listBox1.Items[i].ToString() == s)
                    {
                        found = true;
                        break;
                    }

                if (!found)
                {
                    listBox1.Items.Add(s);
                    listBox1.SelectedIndex = listBox1.Items.Count - 1;
                }

            }
            else
            {
                for (int i = 0; i < listBox1.Items.Count; i++)
                {
                    if (listBox1.Items[i].ToString() == s)
                    {
                        listBox1.Items.RemoveAt(i);

                        if (i > 0) listBox1.SelectedIndex = i - 1;
                        if (i == 0)
                            if (listBox1.Items.Count >= 1)
                                listBox1.SelectedIndex = 0;

                        break;
                    }
                }
            }
        }

     }
}
namespace Example
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            this.label1 = new System.Windows.Forms.Label();
            this.lblShearY = new System.Windows.Forms.Label();
            this.tShearY = new System.Windows.Forms.TrackBar();
            this.label6 = new System.Windows.Forms.Label();
            this.lblShearX = new System.Windows.Forms.Label();
            this.tShearX = new System.Windows.Forms.TrackBar();
            this.cbShear = new System.Windows.Forms.CheckBox();
            this.cbRealtime = new System.Windows.Forms.CheckBox();
            this.btnReset = new System.Windows.Forms.Button();
            this.cbFlipY = new System.Windows.Forms.CheckBox();
            this.pictureBoxBase = new System.Windows.Forms.PictureBox();
            this.label14 = new System.Windows.Forms.Label();
            this.lblStrY = new System.Windows.Forms.Label();
            this.tStrY = new System.Windows.Forms.TrackBar();
            this.cbStretch = new System.Windows.Forms.CheckBox();
            this.label16 = new System.Windows.Forms.Label();
            this.lblStrX = new System.Windows.Forms.Label();
            this.tStrX = new System.Windows.Forms.TrackBar();
            this.label9 = new System.Windows.Forms.Label();
            this.lblRotY = new System.Windows.Forms.Label();
            this.tRotY = new System.Windows.Forms.TrackBar();
            this.label11 = new System.Windows.Forms.Label();
            this.lblRotX = new System.Windows.Forms.Label();
            this.tRotX = new System.Windows.Forms.TrackBar();
            this.label5 = new System.Windows.Forms.Label();
            this.lblTransY = new System.Windows.Forms.Label();
            this.tTransY = new System.Windows.Forms.TrackBar();
            this.cbTranslation = new System.Windows.Forms.CheckBox();
            this.label3 = new System.Windows.Forms.Label();
            this.lblTransX = new System.Windows.Forms.Label();
            this.tTransX = new System.Windows.Forms.TrackBar();
            this.cbRotate = new System.Windows.Forms.CheckBox();
            this.label2 = new System.Windows.Forms.Label();
            this.buttonUp = new System.Windows.Forms.Button();
            this.buttonDown = new System.Windows.Forms.Button();
            this.listBox1 = new System.Windows.Forms.ListBox();
            this.lblRotDeg = new System.Windows.Forms.Label();
            this.tRotDeg = new System.Windows.Forms.TrackBar();
            this.button1 = new System.Windows.Forms.Button();
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            ((System.ComponentModel.ISupportInitialize)(this.tShearY)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.tShearX)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxBase)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.tStrY)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.tStrX)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.tRotY)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.tRotX)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.tTransY)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.tTransX)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.tRotDeg)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.Location = new System.Drawing.Point(460, 339);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(48, 22);
            this.label1.TabIndex = 82;
            this.label1.Text = "Y";
            // 
            // lblShearY
            // 
            this.lblShearY.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.lblShearY.Location = new System.Drawing.Point(612, 339);
            this.lblShearY.Name = "lblShearY";
            this.lblShearY.Size = new System.Drawing.Size(32, 22);
            this.lblShearY.TabIndex = 81;
            // 
            // tShearY
            // 
            this.tShearY.AutoSize = false;
            this.tShearY.LargeChange = 1;
            this.tShearY.Location = new System.Drawing.Point(508, 339);
            this.tShearY.Maximum = 20;
            this.tShearY.Name = "tShearY";
            this.tShearY.Size = new System.Drawing.Size(104, 22);
            this.tShearY.TabIndex = 80;
            this.tShearY.TickFrequency = 10;
            this.tShearY.ValueChanged += new System.EventHandler(this.tShearY_ValueChanged);
            // 
            // label6
            // 
            this.label6.Location = new System.Drawing.Point(460, 309);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(48, 22);
            this.label6.TabIndex = 79;
            this.label6.Text = "X";
            // 
            // lblShearX
            // 
            this.lblShearX.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.lblShearX.Location = new System.Drawing.Point(612, 309);
            this.lblShearX.Name = "lblShearX";
            this.lblShearX.Size = new System.Drawing.Size(32, 22);
            this.lblShearX.TabIndex = 78;
            // 
            // tShearX
            // 
            this.tShearX.AutoSize = false;
            this.tShearX.LargeChange = 1;
            this.tShearX.Location = new System.Drawing.Point(508, 309);
            this.tShearX.Maximum = 20;
            this.tShearX.Name = "tShearX";
            this.tShearX.Size = new System.Drawing.Size(104, 22);
            this.tShearX.TabIndex = 77;
            this.tShearX.TickFrequency = 10;
            this.tShearX.ValueChanged += new System.EventHandler(this.tShearX_ValueChanged);
            // 
            // cbShear
            // 
            this.cbShear.Location = new System.Drawing.Point(444, 280);
            this.cbShear.Name = "cbShear";
            this.cbShear.Size = new System.Drawing.Size(104, 22);
            this.cbShear.TabIndex = 76;
            this.cbShear.Text = "切变";
            this.cbShear.CheckedChanged += new System.EventHandler(this.cbShear_CheckedChanged);
            // 
            // cbRealtime
            // 
            this.cbRealtime.Location = new System.Drawing.Point(156, 415);
            this.cbRealtime.Name = "cbRealtime";
            this.cbRealtime.Size = new System.Drawing.Size(112, 15);
            this.cbRealtime.TabIndex = 75;
            this.cbRealtime.Text = "实时";
            // 
            // btnReset
            // 
            this.btnReset.Location = new System.Drawing.Point(276, 415);
            this.btnReset.Name = "btnReset";
            this.btnReset.Size = new System.Drawing.Size(64, 22);
            this.btnReset.TabIndex = 74;
            this.btnReset.Text = "重置";
            this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
            // 
            // cbFlipY
            // 
            this.cbFlipY.Checked = true;
            this.cbFlipY.CheckState = System.Windows.Forms.CheckState.Checked;
            this.cbFlipY.Location = new System.Drawing.Point(28, 415);
            this.cbFlipY.Name = "cbFlipY";
            this.cbFlipY.Size = new System.Drawing.Size(112, 15);
            this.cbFlipY.TabIndex = 73;
            this.cbFlipY.Text = "翻转Y坐标";
            this.cbFlipY.CheckedChanged += new System.EventHandler(this.cbFlipY_CheckedChanged);
            // 
            // pictureBoxBase
            // 
            this.pictureBoxBase.Image = ((System.Drawing.Image)(resources.GetObject("pictureBoxBase.Image")));
            this.pictureBoxBase.Location = new System.Drawing.Point(68, 440);
            this.pictureBoxBase.Name = "pictureBoxBase";
            this.pictureBoxBase.Size = new System.Drawing.Size(100, 92);
            this.pictureBoxBase.TabIndex = 72;
            this.pictureBoxBase.TabStop = false;
            this.pictureBoxBase.Visible = false;
            // 
            // label14
            // 
            this.label14.Location = new System.Drawing.Point(460, 250);
            this.label14.Name = "label14";
            this.label14.Size = new System.Drawing.Size(48, 22);
            this.label14.TabIndex = 71;
            this.label14.Text = "Y";
            // 
            // lblStrY
            // 
            this.lblStrY.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.lblStrY.Location = new System.Drawing.Point(612, 250);
            this.lblStrY.Name = "lblStrY";
            this.lblStrY.Size = new System.Drawing.Size(32, 22);
            this.lblStrY.TabIndex = 70;
            // 
            // tStrY
            // 
            this.tStrY.AutoSize = false;
            this.tStrY.LargeChange = 1;
            this.tStrY.Location = new System.Drawing.Point(508, 250);
            this.tStrY.Maximum = 20;
            this.tStrY.Minimum = 1;
            this.tStrY.Name = "tStrY";
            this.tStrY.Size = new System.Drawing.Size(104, 22);
            this.tStrY.TabIndex = 69;
            this.tStrY.Value = 10;
            this.tStrY.ValueChanged += new System.EventHandler(this.tStrY_ValueChanged);
            // 
            // cbStretch
            // 
            this.cbStretch.Location = new System.Drawing.Point(444, 198);
            this.cbStretch.Name = "cbStretch";
            this.cbStretch.Size = new System.Drawing.Size(80, 15);
            this.cbStretch.TabIndex = 68;
            this.cbStretch.Text = "缩放";
            this.cbStretch.CheckedChanged += new System.EventHandler(this.cbStretch_CheckedChanged);
            // 
            // label16
            // 
            this.label16.Location = new System.Drawing.Point(460, 221);
            this.label16.Name = "label16";
            this.label16.Size = new System.Drawing.Size(48, 22);
            this.label16.TabIndex = 67;
            this.label16.Text = "X";
            // 
            // lblStrX
            // 
            this.lblStrX.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.lblStrX.Location = new System.Drawing.Point(612, 221);
            this.lblStrX.Name = "lblStrX";
            this.lblStrX.Size = new System.Drawing.Size(32, 22);
            this.lblStrX.TabIndex = 66;
            // 
            // tStrX
            // 
            this.tStrX.AutoSize = false;
            this.tStrX.LargeChange = 1;
            this.tStrX.Location = new System.Drawing.Point(508, 221);
            this.tStrX.Maximum = 20;
            this.tStrX.Minimum = 1;
            this.tStrX.Name = "tStrX";
            this.tStrX.Size = new System.Drawing.Size(104, 22);
            this.tStrX.TabIndex = 65;
            this.tStrX.Value = 10;
            this.tStrX.ValueChanged += new System.EventHandler(this.tStrX_ValueChanged);
            // 
            // label9
            // 
            this.label9.Location = new System.Drawing.Point(460, 88);
            this.label9.Name = "label9";
            this.label9.Size = new System.Drawing.Size(48, 22);
            this.label9.TabIndex = 64;
            this.label9.Text = "Y";
            // 
            // lblRotY
            // 
            this.lblRotY.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.lblRotY.Location = new System.Drawing.Point(612, 88);
            this.lblRotY.Name = "lblRotY";
            this.lblRotY.Size = new System.Drawing.Size(32, 22);
            this.lblRotY.TabIndex = 63;
            // 
            // tRotY
            // 
            this.tRotY.AutoSize = false;
            this.tRotY.LargeChange = 1;
            this.tRotY.Location = new System.Drawing.Point(508, 88);
            this.tRotY.Maximum = 50;
            this.tRotY.Name = "tRotY";
            this.tRotY.Size = new System.Drawing.Size(104, 22);
            this.tRotY.TabIndex = 62;
            this.tRotY.TickFrequency = 10;
            this.tRotY.ValueChanged += new System.EventHandler(this.tRotY_ValueChanged);
            // 
            // label11
            // 
            this.label11.Location = new System.Drawing.Point(460, 58);
            this.label11.Name = "label11";
            this.label11.Size = new System.Drawing.Size(48, 22);
            this.label11.TabIndex = 61;
            this.label11.Text = "X";
            // 
            // lblRotX
            // 
            this.lblRotX.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.lblRotX.Location = new System.Drawing.Point(612, 58);
            this.lblRotX.Name = "lblRotX";
            this.lblRotX.Size = new System.Drawing.Size(32, 22);
            this.lblRotX.TabIndex = 60;
            // 
            // tRotX
            // 
            this.tRotX.AutoSize = false;
            this.tRotX.LargeChange = 1;
            this.tRotX.Location = new System.Drawing.Point(508, 58);
            this.tRotX.Maximum = 50;
            this.tRotX.Name = "tRotX";
            this.tRotX.Size = new System.Drawing.Size(104, 22);
            this.tRotX.TabIndex = 59;
            this.tRotX.TickFrequency = 10;
            this.tRotX.ValueChanged += new System.EventHandler(this.tRotX_ValueChanged);
            // 
            // label5
            // 
            this.label5.Location = new System.Drawing.Point(460, 169);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(48, 22);
            this.label5.TabIndex = 58;
            this.label5.Text = "Y";
            // 
            // lblTransY
            // 
            this.lblTransY.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.lblTransY.Location = new System.Drawing.Point(612, 169);
            this.lblTransY.Name = "lblTransY";
            this.lblTransY.Size = new System.Drawing.Size(32, 22);
            this.lblTransY.TabIndex = 57;
            // 
            // tTransY
            // 
            this.tTransY.AutoSize = false;
            this.tTransY.LargeChange = 1;
            this.tTransY.Location = new System.Drawing.Point(508, 169);
            this.tTransY.Maximum = 150;
            this.tTransY.Name = "tTransY";
            this.tTransY.Size = new System.Drawing.Size(104, 22);
            this.tTransY.TabIndex = 56;
            this.tTransY.TickFrequency = 20;
            this.tTransY.ValueChanged += new System.EventHandler(this.tTransY_ValueChanged);
            // 
            // cbTranslation
            // 
            this.cbTranslation.Location = new System.Drawing.Point(444, 117);
            this.cbTranslation.Name = "cbTranslation";
            this.cbTranslation.Size = new System.Drawing.Size(88, 15);
            this.cbTranslation.TabIndex = 55;
            this.cbTranslation.Text = "平移";
            this.cbTranslation.CheckedChanged += new System.EventHandler(this.cbTranslation_CheckedChanged);
            // 
            // label3
            // 
            this.label3.Location = new System.Drawing.Point(460, 139);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(48, 22);
            this.label3.TabIndex = 54;
            this.label3.Text = "X";
            // 
            // lblTransX
            // 
            this.lblTransX.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.lblTransX.Location = new System.Drawing.Point(612, 139);
            this.lblTransX.Name = "lblTransX";
            this.lblTransX.Size = new System.Drawing.Size(32, 22);
            this.lblTransX.TabIndex = 53;
            // 
            // tTransX
            // 
            this.tTransX.AutoSize = false;
            this.tTransX.LargeChange = 1;
            this.tTransX.Location = new System.Drawing.Point(508, 139);
            this.tTransX.Maximum = 150;
            this.tTransX.Name = "tTransX";
            this.tTransX.Size = new System.Drawing.Size(104, 22);
            this.tTransX.TabIndex = 52;
            this.tTransX.TickFrequency = 20;
            this.tTransX.ValueChanged += new System.EventHandler(this.tTransX_ValueChanged);
            // 
            // cbRotate
            // 
            this.cbRotate.Location = new System.Drawing.Point(436, 6);
            this.cbRotate.Name = "cbRotate";
            this.cbRotate.Size = new System.Drawing.Size(80, 15);
            this.cbRotate.TabIndex = 51;
            this.cbRotate.Text = "旋转";
            this.cbRotate.CheckedChanged += new System.EventHandler(this.cbRotate_CheckedChanged);
            // 
            // label2
            // 
            this.label2.Location = new System.Drawing.Point(460, 29);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(48, 22);
            this.label2.TabIndex = 50;
            this.label2.Text = "角度";
            // 
            // buttonUp
            // 
            this.buttonUp.Location = new System.Drawing.Point(628, 376);
            this.buttonUp.Name = "buttonUp";
            this.buttonUp.Size = new System.Drawing.Size(16, 22);
            this.buttonUp.TabIndex = 49;
            this.buttonUp.Text = "+";
            this.buttonUp.Click += new System.EventHandler(this.buttonUp_Click);
            // 
            // buttonDown
            // 
            this.buttonDown.Location = new System.Drawing.Point(628, 413);
            this.buttonDown.Name = "buttonDown";
            this.buttonDown.Size = new System.Drawing.Size(16, 22);
            this.buttonDown.TabIndex = 48;
            this.buttonDown.Text = "-";
            this.buttonDown.Click += new System.EventHandler(this.buttonDown_Click);
            // 
            // listBox1
            // 
            this.listBox1.ItemHeight = 12;
            this.listBox1.Location = new System.Drawing.Point(444, 376);
            this.listBox1.Name = "listBox1";
            this.listBox1.Size = new System.Drawing.Size(176, 64);
            this.listBox1.TabIndex = 47;
            // 
            // lblRotDeg
            // 
            this.lblRotDeg.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.lblRotDeg.Location = new System.Drawing.Point(612, 29);
            this.lblRotDeg.Name = "lblRotDeg";
            this.lblRotDeg.Size = new System.Drawing.Size(32, 22);
            this.lblRotDeg.TabIndex = 46;
            // 
            // tRotDeg
            // 
            this.tRotDeg.AutoSize = false;
            this.tRotDeg.LargeChange = 1;
            this.tRotDeg.Location = new System.Drawing.Point(508, 29);
            this.tRotDeg.Maximum = 90;
            this.tRotDeg.Name = "tRotDeg";
            this.tRotDeg.Size = new System.Drawing.Size(104, 22);
            this.tRotDeg.TabIndex = 45;
            this.tRotDeg.TickFrequency = 30;
            this.tRotDeg.ValueChanged += new System.EventHandler(this.tRotDeg_ValueChanged);
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(356, 415);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(64, 22);
            this.button1.TabIndex = 44;
            this.button1.Text = "运行";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // pictureBox1
            // 
            this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.pictureBox1.Location = new System.Drawing.Point(20, 6);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(400, 400);
            this.pictureBox1.TabIndex = 43;
            this.pictureBox1.TabStop = false;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(662, 497);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.lblShearY);
            this.Controls.Add(this.tShearY);
            this.Controls.Add(this.label6);
            this.Controls.Add(this.lblShearX);
            this.Controls.Add(this.tShearX);
            this.Controls.Add(this.cbShear);
            this.Controls.Add(this.cbRealtime);
            this.Controls.Add(this.btnReset);
            this.Controls.Add(this.cbFlipY);
            this.Controls.Add(this.pictureBoxBase);
            this.Controls.Add(this.label14);
            this.Controls.Add(this.lblStrY);
            this.Controls.Add(this.tStrY);
            this.Controls.Add(this.cbStretch);
            this.Controls.Add(this.label16);
            this.Controls.Add(this.lblStrX);
            this.Controls.Add(this.tStrX);
            this.Controls.Add(this.label9);
            this.Controls.Add(this.lblRotY);
            this.Controls.Add(this.tRotY);
            this.Controls.Add(this.label11);
            this.Controls.Add(this.lblRotX);
            this.Controls.Add(this.tRotX);
            this.Controls.Add(this.label5);
            this.Controls.Add(this.lblTransY);
            this.Controls.Add(this.tTransY);
            this.Controls.Add(this.cbTranslation);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.lblTransX);
            this.Controls.Add(this.tTransX);
            this.Controls.Add(this.cbRotate);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.buttonUp);
            this.Controls.Add(this.buttonDown);
            this.Controls.Add(this.listBox1);
            this.Controls.Add(this.lblRotDeg);
            this.Controls.Add(this.tRotDeg);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.pictureBox1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.tShearY)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.tShearX)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxBase)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.tStrY)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.tStrX)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.tRotY)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.tRotX)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.tTransY)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.tTransX)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.tRotDeg)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label lblShearY;
        private System.Windows.Forms.TrackBar tShearY;
        private System.Windows.Forms.Label label6;
        private System.Windows.Forms.Label lblShearX;
        private System.Windows.Forms.TrackBar tShearX;
        private System.Windows.Forms.CheckBox cbShear;
        private System.Windows.Forms.CheckBox cbRealtime;
        private System.Windows.Forms.Button btnReset;
        private System.Windows.Forms.CheckBox cbFlipY;
        private System.Windows.Forms.PictureBox pictureBoxBase;
        private System.Windows.Forms.Label label14;
        private System.Windows.Forms.Label lblStrY;
        private System.Windows.Forms.TrackBar tStrY;
        private System.Windows.Forms.CheckBox cbStretch;
        private System.Windows.Forms.Label label16;
        private System.Windows.Forms.Label lblStrX;
        private System.Windows.Forms.TrackBar tStrX;
        private System.Windows.Forms.Label label9;
        private System.Windows.Forms.Label lblRotY;
        private System.Windows.Forms.TrackBar tRotY;
        private System.Windows.Forms.Label label11;
        private System.Windows.Forms.Label lblRotX;
        private System.Windows.Forms.TrackBar tRotX;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.Label lblTransY;
        private System.Windows.Forms.TrackBar tTransY;
        private System.Windows.Forms.CheckBox cbTranslation;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Label lblTransX;
        private System.Windows.Forms.TrackBar tTransX;
        private System.Windows.Forms.CheckBox cbRotate;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Button buttonUp;
        private System.Windows.Forms.Button buttonDown;
        private System.Windows.Forms.ListBox listBox1;
        private System.Windows.Forms.Label lblRotDeg;
        private System.Windows.Forms.TrackBar tRotDeg;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.PictureBox pictureBox1;
    }
}

 

 

 

 

第2基础 34 2.1 笔和画刷 34 2.1.1 pen 类 34 2.1.2 brush 类 35 2.2 基本图状 37 2.2.1 点 37 2.2.2 直线和曲线 37 2.2.3 矩、椭圆和圆弧 40 2.2.4 多边 42 2.3 颜色 44 2.4 双倍缓存 66 第3 坐标系统和颜色变换 69 3.1 坐标系统 69 3.2 颜色变换 77 第二部分 二维的基本算法 第4 二维矩阵变换 82 4.1 矩阵基础和变换 82 4.2 齐次坐标 82 4.2.1 齐次坐标中的缩放 83 4.2.2 齐次坐标中的平移 83 4.2.3 齐次坐标中的旋转 84 4.2.4 变换组合 85 4.2.5 c#矩阵的定义 86 4 .2.6 c#中的矩阵操作 87 4.2.7 c#中基本的矩阵变换 89 4.3 c#中图对象的变换 93 基本变换 93 4.4 c#中的多对象变换 101 4.5 文字变换 105 第5 二维线 109 5.1 序列化和反序列化及二维的基本框架 109 5.1.1 c#序列化和反序列化 110 5.1.2 二维的基本框架 113 5.2 二维 248 5.2.1 简单实例 248 5.2.2 图例 278 5.2.3 符号 289 5.2.4 对数比例 302 5.2.5 图的修饰 308 5.3 阶梯状图 316 5.4 多y轴图 318 第6 特殊二维 327 6.1 创建柱状图 327 6.1.1 水平柱状图 327 6.1.2 垂直柱状图 343 6.1.3 图充填柱状图 344 6.1.4 重叠柱状图 346 6.2 饼状图 348 6.3 误差图 361 6.4 股票图 367 6.4.1 最高最低收盘价股票图 368 6.4.2 最高最低开盘收盘价股票图 369 6.4.3 最高最低价股票图 377 6.4.4 k 线图(阴阳烛图) 380 6.5 面积图 389 6.6 综合图 390 第三部分 三维图的相关知识及三维图的实现 第7 三维矩阵变换 396 7.1 三维数学概念 396 7.1.1 操作三维对象 396 7.1.2 数学结构 397 7.2 三维中的基本矩阵变换 402 7.2.1 c#中三维点和矩阵的操作 403 7.2.2 三维的基本变换 405 7.3 方位角和仰角 434 7.4 三维图中的特殊坐标系统 439 7.4.1 球坐标系统 440 7.4.2 圆柱坐标系统 443 7.5 特殊坐标中的实际应用 447 7.5.1 球坐标示例 447 7.5.2 双缓存 463 第8 三维图 473 8.1 三维图基础 473 8.1.1 point3和matrix3类 473 8.1.2 chartstyle类 476 8.1.3 坐标轴 496 8.1.4 网格线 496 8.1.5 标签 497 8.2 三维折线图 503 8.3 三维图函数包 508 8.3.1 chartstyle2d类 509 8.3.2 point4类 515 8.3.3 dataseries类 516 8.3.4 chartfunctions类 521 8.3.5 drawchart类 526 8.4 曲面图的实现 541 8.4.1 网格图 541 8.4.2 幕布网格图 548 8.4.3 瀑布网格图 551 8.4.4 曲面图 553 8.5 x-y平面色彩图 559 8.6 轮廓图 564 8.6.1 轮廓图的算法 564 8.6.2 轮廓图的实现 564 8.7 组合图 569 8.7.1 三维体系中的x-y色彩图 570 8.7.2 三维体系中的轮廓图 571 8.7.3 网格-轮廓组合图 575 8.7.4 曲面-轮廓组合图 576 8.7.5 填充曲面-轮廓组合图 576 8.8 三维柱状图 577 实现柱状图 577 8.9 切片图 591 切片图的实现 591 第四部分 c#中应用微软office的excel实现各种二维三维图 第9 应用程序中的excel图表 600 9.1 excel和c#间的互操作 600 9.2 c#应用程序中的excel图表示例 602 9.2.1 excel图表对象模型 602 9.2.2 创建独立的excel图表 604 9.2.3 创建嵌入式excel图表 607 9.3 更多的excel图表 608 9.3.1 柱状图 608 9.3.2 饼状图 611 9.3.3 面积图 613 9.3.4 圆环图 615 9.3.5 雷达图 615 9.3.6 股价图 617 9.3.7 曲面图 619 9.3.8 颜色映射 622 9.4 整合excel图表到windows forms应用程序中 627 9.4.1 windows窗体上的独立excel图表 627 9.4.2 windows窗体上的嵌入式excel图表 631 第五部分 实现文件的相关知识 第10 文件的读/写 634 10.1 c#文件读/写常用类 634 10.1.1 system.io.file类和system.io.fileinfo类 634 10.1.2 system.io.directory类和system.directoryinfo类 637 10.2 c#基于流的输入/输出 639 流的继承结构 640 10.3 文件读/写操作涉及的类 643 10.4 一些常见的问题及其解决 方案 643
书名 版权 前言 第一部分 C#的基本数据类型、数组类型和图基础第1 C#语言基础 1.1 数据类型 1.1.1 简单类型 1.1.2 结构类型 1.1.3 枚举类型 1.1.4 数组类型 1.1.5 类类型 1.1.6 类型转换 1.2 类 1.3 接口 1.4 委托与事件 第2基础 2.1 笔和画刷 2.1.1 Pen类 2.1.2 Brush类 2.2 基本图状 2.2.1 点 2.2.2 直线和曲线 2.2.3 矩、椭圆和圆弧 2.2.4 多边 2.3 颜色 2.4 双倍缓存 第3 坐标系统和颜色变换 3.1 坐标系统 3.2 颜色变换 第二部分 二维的基本算法 第4 二维矩阵变换 4.1 矩阵基础和变换 4.2 齐次坐标 4.2.1 齐次坐标中的缩放 4.2.2 齐次坐标中的平移 4.2.3 齐次坐标中的旋转 4.2.4 变换组合 4.2.5 C#中矩阵的定义 4.2.6 C#中的矩阵操作 4.2.7 C#中基本的矩阵变换 4.3 C#中图对象的变换 基本变换 4.4 C#中的多对象变换 4.5 文字变换 第5 二维线 5.1 序列化和反序列化及二维的基本框架 5.1.1 C#序列化和反序列化 5.1.2 二维的基本框架 5.2 二维 5.2.1 简单实例 5.2.2 图例 5.2.3 符号 5.2.4 对数比例 5.2.5 图的修饰 5.3 阶梯状图 5.4 多Y轴图 第6 特殊二维 6.1 创建柱状图 6.1.1 水平柱状图 6.1.2 垂直柱状图 6.1.3 图充填柱状图 6.1.4 重叠柱状图 6.2 饼状图 6.3 误差图 6.4 股票图 6.4.1 最高最低收盘价股票图 6.4.2 最高最低开盘收盘价股票图 6.4.3 最高最低价股票图 6.4.4 K线图(阴阳烛图) 6.5 面积图 6.6 综合图 第三部分 三维图的相关知识及三维图的实现第7 三维矩阵变换 7.1 三维数学概念 7.1.1 操作三维对象 7.1.2 数学结构 7.2 三维中的基本矩阵变换 7.2.1 C#中三维点和矩阵的操作 7.2.2 三维的基本变换 7.3 方位角和仰角 7.4 三维图中的特殊坐标系统 7.4.1 球坐标系统 7.4.2 圆柱坐标系统 7.5 特殊坐标中的实际应用 7.5.1 球坐标示例 7.5.2 双缓存 第8 三维图 8.1 三维图基础 8.1.1 Point3和Matrix3类 8.1.2 ChartStyle类 8.1.3 坐标轴 8.1.4 网格线 8.1.5 标签 8.2 三维折线图 8.3 三维图函数包 8.3.1 ChartStyle2D类 8.3.2 Point4类 8.3.3 DataSeries类 8.3.4 ChartFunctions类 8.3.5 DrawChart类 8.4 曲面图的实现 8.4.1 网格图 8.4.2 幕布网格图 8.4.3 瀑布网格图 8.4.4 曲面图 8.5 X-Y平面色彩图 8.6 轮廓图 8.6.1 轮廓图的算法 8.6.2 轮廓图的实现 8.7 组合图 8.7.1 三维体系中的X-Y色彩图 8.7.2 三维体系中的轮廓图 8.7.3 网格-轮廓组合图 8.7.4 曲面-轮廓组合图 8.7.5 填充曲面-轮廓组合图 8.8 三维柱状图 实现柱状图 8.9 切片图 切片图的实现 第四部分 C#中应用微软Office的Excel实现各种二维三维图第9 应用 程序中的Excel图表 9.1 Excel和C#间的互操作 9.2 C#应用程序中的Excel图表示例 9.2.1 Excel图表对象模型 9.2.2 创建独立的Excel图表 9.2.3 创建嵌入式Excel图表 9.3 更多的Excel图表 9.3.1 柱状图 9.3.2 饼状图 9.3.3 面积图 9.3.4 圆环图 9.3.5 雷达图 9.3.6 股价图 9.3.7 曲面图 9.3.8 颜色映射 9.4 整合Excel图表到Windows Forms应用程序中 9.4.1 Windows窗体上的独立Excel图表 9.4.2 Windows窗体上的嵌入式Excel图表 第五部分 实现文件的相关知识 第10 文件的读/写 10.1 C#文件读/写常用类 10.1.1 System.IO.File类和System.IO.FileI nfo类 10.1.2 System.IO.Directory类和System.Dir ectoryInfo类 10.2 C#基于流的输入/输出 流的继承结构 10.3 文件读/写操作涉及的类 10.4 一些常见的问题及其解决方案 参考文献
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhy29563

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值