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;
}
}