• 博客等级：
• 博客积分：0
• 博客访问：508,521
• 关注人气：150
• 获赠金笔：0支
• 赠出金笔：0支
• 荣誉徽章：

(2010-01-05 16:17)
 分类： Matlab

# angle2dcm

Create direction cosine matrix from rotation angles

## Syntax

dcm = angle2dcm(rotationAng1, rotationAng2, rotationAng3)
dcm = angle2dcm(rotationAng1, rotationAng2, rotationAng3, rotationSequence)

## Description

dcm = angle2dcm(rotationAng1, rotationAng2, rotationAng3) calculates the direction cosine matrix given three sets of rotation angles. 由三个旋转角计算方向余弦矩阵

dcm = angle2dcm(rotationAng1, rotationAng2, rotationAng3, rotationSequence) calculates the direction cosine matrix using a rotation sequence.由特定的旋转序列计算方向余弦矩阵

## Inputs

rotationAng1

m-by-1 array of first rotation angles, in radians. 第一个旋转角

rotationAng2

m-by-1 array of second rotation angles, in radians.  第二个旋转角

rotationAng3

m-by-1 array of third rotation angles, in radians.第三个旋转角

rotationSequence

String that defines rotation sequence. For example, the default 'ZYX' represents a sequence where rotationAng1 is z-axis rotation, rotationAng2 is y-axis rotation, and rotationAng3 is x-axis rotation.

 'ZYX' 'ZYZ' 'ZXY' 'ZXZ' 'YXZ' 'YXY' 'YZX' 'YZY' 'XYZ' 'XZY' 'XYX' 'XZX' 'ZYX' (default)

## Outputs

 dcm 3-by-3-by-m matrix containing m direction cosine matrices. 3X3的方向余弦矩阵

Examples

A=[2;3;4];

dcm=angle2dcm(20*pi/180,30*pi/180,45*pi/180,'ZXY');

B=dcm*A

>> B =
0.359820367873134
3.848996778596074
3.749100305569416

即B坐标为(0.359820367873134,3.848996778596074,3.749100305569416)

dcm_inv=dcm';

C=dcm_inv*B;

>> C =
2.000000000000000
3.000000000000000
4.000000000000000

(2009-11-12 08:51)

### 杂谈

1 20091112创建文档

2 20091113发送函数介绍，数据的接收，上位机基本功能的完成

1.设置下面的属性

2.代码实现

3.用我封装的一个类来实现

按上述步骤初始化串口之后进行串口的打开和关闭操作

serialPort1.Open();

serialPort1.Close();

private void btn_open_Click(object sender, EventArgs e)
{
if (btn_open.Text == "打开串口")
{
btn_open.Text = "关闭串口";
serialPort1.Open();
}
else
{
btn_open.Text = "打开串口";
serialPort1.Close();
}
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AHRSmanager;

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

}

{

}

private void btn_SerialportSet_Click(object sender, EventArgs e)
{
using (串口设置窗口 frmConfig = new 串口设置窗口())
{
frmConfig.ShowDialog();
}
}

private void btn_open_Click(object sender, EventArgs e)
{
if (btn_open.Text == "打开串口")
{
btn_open.Text = "关闭串口";
serialPort1.Open();
}
else
{
btn_open.Text = "打开串口";
serialPort1.Close();
}
}

private void Form1_Load(object sender, EventArgs e)
{

btn_open.Text = "打开串口";
}

}
}

(一) 十六进制数据发送

1.为程序添加发送按钮，命名为btn_send,为程序添加文本输入框tb_send

2.在btn_send的回调函数中添加以下代码

private void btn_send_Click(object sender, EventArgs e)
{
Byte[] BSendTemp = new Byte[1]; //建立临时字节数组对象
BSendTemp[0] = Byte.Parse(this.tb_send.Text);//由文本框读入想要发送的数据
this.serialPort1.Write(BSendTemp, 0, 1);//发送数据
}

3.测试

(二) 字符串数据发送
1 为程序添加CheckBox cB_Hex，如若选中则发送Hex数据，如若未选则发送String数据。
2 将btn_send的响应函数btn_send_Click修改为：
private void btn_send_Click(object sender, EventArgs e)
{
if (this.cB_Hex.Checked == true)
{
Byte[] BSendTemp = new Byte[1]; //建立临时字节数组对象
BSendTemp[0] = Byte.Parse(this.tb_send.Text);//由文本框读入想要发送的数据
this.serialPort1.Write(BSendTemp, 0, 1);//发送数据
}
else
{
string serialStringTemp = this.tb_send.Text;
this.serialPort1.WriteLine(serialStringTemp);
}
}
3 运行程序，取消Checkbox的选择
4 发送字符串，下面为测试图
5 这里主要利用了WriteLine函数，这个函数在Console中也有定义，用发基本一样。

（A）结构介绍

1 主动定时读取
这种方式的适应能力较弱，当数据来源为定时并且不是很快的情况时可以考虑采用这种方法，这种方法主要适用于数据采集系统而不适用于随机事件发生时的通信或控制系统。

2 事件响应驱动
这种方式是串口通信上位机制作的主要方式，其采用中断思想而成，当串口输入缓冲区中的字节数据大于某个设定的个数时，触发串口输入中断，这时在中断程序中读取串口输入缓冲区中的数据，具有实时性和灵活性，是个常用的较好的方法。本文也是采用这种方法来进行串口输入缓冲区的实时数据读取。
（B）事件响应驱动下的串口输入缓冲区数据读取
.NET中封装了SerialPort 类 表示串行端口资源。

{

}

{
(
new MethodInvoker
(

delegate
{

}

)

);

}

<5> 测试图,打开上位机和调试助手，点击调试助手的发送按钮，上位机就会相应的显示接收到的数据.
<6> 这时候就完成了基本上位机功能的编写

(2009-11-07 08:55)

### zedgraph

http://www.codeproject.com/KB/graphics/zedgraph.aspx

A flexible charting library for .NET   By JChampion

# 正在寻找利用C#画二维线型图像的方法吗？这个就是高度可配置的绘图类库，当然，他也是非常容易用的。

Introduction

ZedGraph是一个类库，为Windows Forms 设计的用户控件,该控件可以通过专业的数据资料创建2D线、Bar和Pie图像。该类库提供高度的灵活性——几乎每一个图像的部分都能由用户修改。于此同时，通过为所有图像的属性提供缺省值使类库的用法保持简单。类库中包括选择合适的刻度因数范围和基于被显示值的的数据范围的步长值的代码。此外，ZedGraph 兼容于.NET 2.0和VS.NET 2005.

ZeGraph 是作为开源开发工程在SourceForge被维护的。该网站包括该项目的wiki、文档、更新历史和所有的发行版本。

Wiki上含有一套简单的图像实例由公开的代码完成（许多的例子包括C#和VB代码）。

Background

我们可以寻找到很多的绘图类库，但是似乎没有一个能够满足我的需要。我发现MSCHART太诡异了，许多其他的选项都不具有可配置性但我需要达到一种精致的外观。当然，许多商业开发包能够做这种花招，但是我需要某种免费的东东。由此，ZedGraph产生了！

这个类库将可以产生各种线型、条形、图形分割统计图表在Form上，考虑到位置矩形和一些数据点（翻译的有点诡异，没太看明白）。ZedGraph处理二维线形或散点图形，所彩的百分数条形图形，误差条形图像，日本烛台图形和图形分割统计图表——他现在还不能处理2.5D或3D表面图形。可以通过坐标轴标签、标题、图例标签、文字标签、箭头、镜像等对象修饰图像。

ZedGraphWiki 和online class documentation 提供了大量的有用的信息，针对其提供更多的信息，ZedGraph 有大量的选项没有在这个入门文档中提供。

Using ZedGraph as a UserControl

1. 在项目主菜单->选择添加引用->添加ZedGraph.dll，然后点击OK，重复这个过程添ZedGraph.Web.dll，这将包括所有的ZedGraph功能在你的工程中。
2. 添加using ZedGraph;语句到你的主Form代码中
3. 在Form设计器中，从工具箱中拖拽ZedGraphControl到From上，按照你的意愿修改其大小和位置。你现在在你的Form中就有了一个ZedGraph控件。如下图
4. 所有的ZedGraph功能都可以通过ZedGraphControl.MasterPane属性来访问，提供ZedGraphControl.GraphPane来引用第一个GraphPane在主MasterPane列表中。（下面会解释这句话的意思）。
6. 在Form设计器中，激活Form后定位到属性中的事件如图，双击Resizes事件，这时Form1_Resize相应的函数模板将出现在在代码文件中
7. 修改Form1_Load（）和Form1_Resize（）方法，按照下面的代码添加CreateGraph() and `SetSize()` 方法。（这里假定你的控件名称为zedGraphControl1）
8. //  form 'Resize'  的事件相应方法

private void Form1_Resize( object sender, EventArgs e )

SetSize();

//这将保留10像素环绕控件的外部边缘，定制这些使之适合你的需要。
private void SetSize()

zedGraphControl1.Location = new Point( 10, 10 );

//保留一个小的页面空白在控件的周围
zedGraphControl1.Size = new Size( ClientRectangle.Width - 20,
ClientRectangle.Height - 20 );

private void Form1_Load( object sender, EventArgs e )

// 装载图像
CreateGraph( zedGraphControl1 );

//设定控件的大小填充form
SetSize();

// 创建图像
private void CreateGraph( ZedGraphControl zgc )

//得到GraphPane的引用
GraphPane myPane = zgc.GraphPane;

// 设置标题
myPane.Title.Text = "My Test Graph\n(For CodeProject Sample)";
myPane.XAxis.Title.Text = "My X Axis";
myPane.YAxis.Title.Text = "My Y Axis";
//生成正弦函数的数据集合
double x, y1, y2;
PointPairList list1 = new PointPairList();
PointPairList list2 = new PointPairList();
for ( int i = 0; i < 36; i++ )
{
x = (double)i + 5;
y1 = 1.5 + Math.Sin( (double)i * 0.2 );
y2 = 3.0 * ( 1.5 + Math.Sin( (double)i * 0.2 ) );
}
//用钻石符合形状生成红色的曲线和图例

list1, Color.Red, SymbolType.Diamond );
//利用圆型的符号生成蓝色的曲线和图例
list2, Color.Blue, SymbolType.Circle );
//告诉ZedGraph 去重新描绘坐标轴当数据变化时
zgc.AxisChange();
}

9. 每次添加或改变数据的时候调用AxisChange()方法。这将告诉ZedGraph去重新计算坐标轴的范围，（注意：这是AxisChange（）的功能——你可以在任何你喜欢的时候调用这个方法，他会基于当前坐标点数据集合来更新坐标范围，如果你不希望坐标轴被重新调节，你也可以避免调用AxisChange()）

8. 执行效果

Enhancing the graph

ZedGraph 允许你通过多种途径更改图形的属性，图像的每个部分都被打包成一个类结构体，这个结构体有可更改的属性去控制图形的输出。下面就是一些在ZedGraph中提供的类（注意这些类是XML文档，详细的细节中每个类请看ZedGraph documentation

 Class Description MasterPane 这是一个管理多个GraphPane对象的类，继承于PaneBase。MasterPane类的应用是可选的，因为GraphPane类能够直接用于单个面板。提供布局、排列和单个GraphPane对象的管理的方法 GraphPane 图像的主要类，继承自PaneBase。包含所有其他的类作为属性。多用于控制图像面板的标题、窗框架和坐标轴框架、背景等属性。 XAxis, `YAxis`, `Y2Axis` Axis类的子类。这些类包括了很多坐标轴显示的形式，包括：刻度、网格、颜色、画笔、字体、标签和类型。 Scale 通过Axis类声明的一个类实例。包括刻度范围、步长、格式和刻度的显示选项。由Linear, `Log`, `Text`, `Date`, `Ordinal`, `Exponent`, `LinearAsOrdinal`, and `DateAsOrdinal` scales的不同而不同。 Legend 此类为描述位置、字体、颜色等性质的类，用于绘制图例 CurveItem 一个对应单条曲线并包含数据的抽象基类。LineItem, `BarItem`, `HiLowBarItem`, `ErrorBarItem`, `PieItem`, `StickItem`, `OHLCBarItem`, and `JapaneseCandleStickItem` 都继承于此类。 CurveList 一个集合类维护了一个CurveItem的对象链表。在链表中的曲线的顺序控制着 Z-顺序为了绘图。在链表中最后的曲线将会出现在其她的曲线之后。 GraphObj 这是一个抽象的基类，他包含了多种的追加图像对象在一个分块中的位置信息。TextObj, `ImageObj`, `LineObj`, `ArrowObj`, `EllipseObj`, `BoxObj`, and `PolyObj` 都继承自`GraphObj`. GraphObjList 一个维护GraphObj链表的集合类。 FontSpec 包括字体信息的功能类，主要是关于图像上字体的颜色、角度、大小、样式、框架和字体的背景填充。每一个包含字体信息的类将会包含一个或几个FontSpec的对象去相应的描述相关联的字体。 Fill 包括背景颜色特性的功能类。每一个含有色彩填充能力的对象都包含一个或多个Fill对象去相应的描述相关联的颜色填充。 Border 包括边框特性的功能类。每一个含有边框描述能力的对象都包含一个或多个Border对象去相应的描述相关联的边框线形和颜色。 Location 一个通用的类，此类处理图像对象在图形中的位置。 PointPair 一个封装了一对double型数据的数据结构，其表征了一个（x，y）的数据点，这是在每个CurveItem中值数组的内部的存储格式。 PointPairList 一个集合类维护了一个PointPair对象的数据链表。

 XDate 此类封装了单独的数据时间值（Double）

// 改变标题的颜色

myPane.Title.FontSpec.FontColor = Color.Green;

//对图像添加灰色网格
myPane.XAxis.MajorGrid.IsVisible = true;
myPane.YAxis.MajorGrid.IsVisible = true;
myPane.XAxis.MajorGrid.Color = Color.LightGray;
myPane.YAxis.MajorGrid.Color = Color.LightGray;

//改变图例的位置

myPane.Legend.Position = ZedGraph.LegendPos.Bottom;

//使两个曲线线性变细
myCurve.Line.Width = 2.0F;
myCurve2.Line.Width = 2.0F;

//在曲线下填充区域
myCurve.Line.Fill = new Fill(Color.White, Color.Red, 45F);
myCurve2.Line.Fill = new Fill(Color.White, Color.Blue, 45F);

//增加符号的大小然后填充其为白色

myCurve.Symbol.Size = 8.0F;
myCurve2.Symbol.Size = 8.0F;
myCurve.Symbol.Fill = new Fill(Color.White);
myCurve2.Symbol.Fill = new Fill(Color.White);

//对坐标轴框架添加背景倾斜填充(其实就是坐标轴的背景图)

myPane.Chart.Fill = new Fill(Color.White,
Color.FromArgb(255, 255, 210), -45F);

// 添加说明文字和箭头
TextObj myText = new TextObj("Interesting\nPoint", 230F, 70F);
myText.FontSpec.FontColor = Color.Red;
myText.Location.AlignH = AlignH.Center;
myText.Location.AlignV = AlignV.Top;
ArrowObj myArrow = new ArrowObj(Color.Red, 12F, 230F, 70F, 280F, 55F);

(2009-06-29 16:37)

### 杂谈

1,由四个字节的十六机制数组转浮点数：

byte[] bytes = new byte[4];

BitConverter.ToSingle(bytes, 0);

2,由浮点数转数组：

byte[] bytes = BitConverter.GetBytes(floatValue);

public static float ToFloat(byte[] data)
{
float a = 0;
byte i;
byte[] x = data;
unsafe
{
void* pf;
fixed (byte* px = x)
{
pf = &a;
for (i = 0; i < data.Length; i++)
{
*((byte*)pf + i) = *(px + i);
}
}
}

return a;
}

public static byte[] ToByte(float data)
{
unsafe
{
byte* pdata = (byte*)&data;
byte[] byteArray = new byte[sizeof(float)];
for (int i = 0; i < sizeof(float); ++i)
byteArray[i] = *pdata++;

return byteArray;
}
}

 错误 1 不安全代码只会在使用 /unsafe 编译的情况下出现 E:\Visual Studio 2008\Projects\TEST\testOfFloatConsolt\testOfFloatConsolt\Program.cs 26 13 testOfFloatConsolt

单片机串口通讯浮点转换函数

WinAVR-20090313测试通过：

void FloatToByte(float floatNum,unsigned char* byteArry)
{
char* pchar=(char*)&floatNum;
for(int i=0;i<sizeof(float);i++)
{
*byteArry=*pchar;
pchar++;
byteArry++;
}
}

下面为符合IEEE754标准的由四个字节型数组转化为相应的浮点数

WinAVR-20090313测试通过：

float ByteToFloat(unsigned char* byteArry)
{
return *((float*)byteArry);
}

调用测试方法：其中USART_Transmit();为向串口发送的函数。

unsigned char floatToByte[4];
FloatToByte(12.15,floatToByte);
float a=ByteToFloat(floatToByte);
FloatToByte(a,floatToByte);
USART_Transmit(floatToByte[0]);
USART_Transmit(floatToByte[1]);
USART_Transmit(floatToByte[2]);
USART_Transmit(floatToByte[3]);

BitConverter.ToSingle(bytes, 0);

(2009-06-17 16:17)
 分类： Matlab

1，rand  生成均匀分布的伪随机数。分布在（0~1）之间

主要语法：rand(m,n)生成m行n列的均匀分布的伪随机数

rand(m,n,'double')生成指定精度的均匀分布的伪随机数，参数还可以是'single'

rand(RandStream,m,n)利用指定的RandStream(我理解为随机种子)生成伪随机数

2，randn 生成标准正态分布的伪随机数（均值为0，方差为1）

主要语法：和上面一样

3, randi 生成均匀分布的伪随机整数

主要语法：randi（iMax）在开区间（0，iMax）生成均匀分布的伪随机整数

randi（iMax，m，n）在开区间（0，iMax）生成mXn型随机矩阵

r = randi([iMin,iMax],m,n)在开区间（iMin，iMax）生成mXn型随机矩阵

概率分布图：

y=rand(1,3000000);
hist(y,2000);

散点图：

y=rand(1,3000000);
plot(y)

概率分布图：

y=randn(1,3000000);
hist(y,2000);

散点图：

y=randn(1,3000000);
plot(y);

rand(1,3)

rand(1,3)

matlab的输出为:

ans =
0.139043482536049   0.734007633362635   0.194791464843949
ans =
0.602204766324215   0.937923745019422   0.149285414707192

Matlab帮助中的下面章节有所叙述：

## Managing the Default Stream

rand, randn, and randi draw random numbers from an underlying random number stream, called the default stream. The @RandStream class allows you to get a handle to the default stream and control random number generation.

rand,randn,和randi 从一个基础的随机数流中得到随机数，叫做默认流。你可以通过 @RandStream 类得到默认流的句柄从而控制随机数的生成。

Get a handle to the default stream as follows:

```defaultStream=RandStream.getDefaultStream

defaultStream =

mt19937ar random stream (current default)
Seed: 0
RandnAlg: Ziggurat
```
```
Return the properties of the stream object with the get method:

```
```get(defaultStream)
Type: 'mt19937ar'
NumStreams: 1
StreamIndex: 1
Substream: 1
Seed: 0
State: [625x1 uint32]
RandnAlg: 'Ziggurat'
Antithetic: 0
FullPrecision: 1
```
```
The State property is the internal state of the generator. You can save the State of defaultStream.
state属性是发生器的内部状态，你可以保存默认流的状态：
```
```myState=defaultStream.State;

```
```
Using myState, you can restore the state of defaultStream and reproduce previous results.

```
```myState=defaultStream.State;
A=rand(1,100);
defaultStream.State=myState;
B=rand(1,100);
isequal(A,B)

ans =

1
```
```你也可以直接使用@RandStream 类的reset静态方法重置种子状态来获取相同的随机生成序列，下面是示例代码:
```

stream = RandStream.getDefaultStream;%获取默认的随机种子（暂时这么叫，帮助有详细解释）
reset(stream);%重置
rand(stream,1,3)
reset(stream);%重置
rand(stream,1,3)

matlab的输出为：

ans =
0.814723686393179   0.905791937075619   0.126986816293506
ans =
0.814723686393179   0.905791937075619   0.126986816293506

(2009-04-11 00:00)

### 杂谈

C# 中List类的Find，Exists,FindAll，FindIndex ，FindLast ,FindLastIndex等方法的应用举例

我一直都认为编写MSDN文档的人语文是好的令人发指啊！

相信很多人都深有体会，这里每个字都认识，放一起完全不知所云，看了好多例子才知道是怎么回事，不知道是我肤浅，还是技术总是要深奥。

总结一下，写了一个通俗点的例子，希望能对看到的人有用。

static void Main(string[] args)//主函数即入口函数，不知道什么意思的面壁吧！
{
List<decimal> list1=new List<decimal>();//此处<>内是泛型的概念，不知道
//的话找本教材看下吧,感觉就像是宏

// 替换
for(int i=0; i<100;i++)                         //生成链表
{
}

if (list1.Exists(MatchPRE))//调用方法，谓词匹配函数的调用,这是调用您自定义的函

//数MatchPRE
Console.WriteLine("ok");//若list1中存在99，则输出ok
else
Console.WriteLine("fail");//若list1中不存在99，则输出fail
}
private static bool MatchPRE(decimal p)//条件匹配函数，list1中每个元素都会传入P中

//匹配后函数返回
{
if (p == 99)//此句为匹配条件，如果匹配，返回，你可以随意更改成你想要的值
return true;
else
{
return false;
}
}

20090928更新

1.你可一采用第一个方法，这个方法为默认方法，对于T为数时将List的成员按照从小到大排列。
2.如果不符合要求则你需要使用第二个方法，实现Comparison<(Of <(T>)>) 泛型委托。即下面的例子
3.也可是利用实现比较器接口的方法实现，即最后两种方法。

List.Sort应用例程：实现比较泛型委托

static void Main(string[] args)
{
Random _random = new Random();//随机对象
List<int> _iList = new List<int>();//列表对象
for (int i = 0; i < 10; i++)
{
}
Console.WriteLine("排序前");
for (int i = 0; i < 10; i++)
{
Console.WriteLine(_iList[i]);//排序前输出
}

_iList.Sort(CompareListBig);//执行排序
Console.WriteLine("排序后");
for (int i = 0; i < 10; i++)
{
Console.WriteLine(_iList[i]);//排序后输出
}
}
private static int CompareListBig(int _a,int _b)//由大到小
{
int _temp = _a - _b;
if (_temp < 0) return 1;
if (_temp > 0) return -1;
return 0;
}
private static int CompareListSmall(int _a, int _b)//由小到大
{
int _temp = _a - _b;
if (_temp> 0) return 1;
if (_temp < 0) return -1;
return 0;
}