Common Errors in English Usage

这是一本很值得收藏的书. 点击下面的封皮可跳转到WSU的网页查询.

Read >>


Classification of Stainless Steel Grades (Chinese National Standard)

国家标准不锈钢牌号分组如下:
-

  • 200 系列—铬-镍-锰 奥氏体不锈钢
  • 300 系列—铬-镍 奥氏体不锈钢


Read >>


屏幕坐标系图像变换原理(Image Transform Principle in Screen Coordinates)

<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><strong>第一部分 Matrix的数学原理</strong></span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><strong>Image Transform Principle.</strong></span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">如果你用Matrix进行过图像处理,那么一定知道Matrix这个类。Android中的Matrix是一个3 x 3的矩阵,其内容如下:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_13217092330d9Q.gif" alt="" />&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">Matrix的对图像的处理可分为四类基本变换:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">Translate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 平移变换</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">Rotate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 旋转变换</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">Scale&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 缩放变换</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">Skew&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 错切变换</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;
<p>
    <!--more-->
</p>
<p>
    <br />
</p>

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">从字面上理解,矩阵中的MSCALE用于处理缩放变换,MSKEW用于处理错切变换,MTRANS用于处理平移变换,MPERSP用于处理透视变换。实际中当然不能完全按照字面上的说法去理解Matrix。同时,在Android的文档中,未见到用Matrix进行透视变换的相关说明,所以本文也不讨论这方面的问题。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">针对每种变换,Android提供了pre、set和post三种操作方式。其中</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">set用于设置Matrix中的值。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">pre是先乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。先乘相当于矩阵运算中的右乘。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">post是后乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。后乘相当于矩阵运算中的左乘。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">除平移变换(Translate)外,旋转变换(Rotate)、缩放变换(Scale)和错切变换(Skew)都可以围绕一个中心点来进行,如果不指定,在默认情况下是围绕(0, 0)来进行相应的变换的。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">下面我们来看看四种变换的具体情形。由于所有的图形都是有点组成,因此我们只需要考察一个点相关变换即可。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><strong>一、 平移变换</strong></span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">假定有一个点的坐标是<img src="http://hi.csdn.net/attachment/201111/19/0_132170933730wW.gif" alt="" />&nbsp;,将其移动到<img src="http://hi.csdn.net/attachment/201111/19/0_1321709345NG9E.gif" alt="" />&nbsp;,再假定在<em>x</em>轴和<em>y</em>轴方向移动的大小分别为:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321709352RQ75.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">如下图所示:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321709520MmsS.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">不难知道:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321709527kmK6.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">如果用矩阵来表示的话,就可以写成:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321709536Otg4.gif" alt="" />&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><strong><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><strong>二、 旋转变换</strong></span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><strong>2.1&nbsp;&nbsp;&nbsp; 围绕坐标原点旋转:</strong></span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">假定有一个点<img src="http://hi.csdn.net/attachment/201111/19/0_132170933730wW.gif" alt="" />&nbsp;,相对坐标原点顺时针旋转<img src="http://hi.csdn.net/attachment/201111/19/0_1321709702OsPP.gif" alt="" />后的情形,同时假定<em>P</em>点离坐标原点的距离为<em>r</em>,如下图:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_132170975189NC.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">那么,</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321709797SBJW.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">如果用矩阵,就可以表示为:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321709849ZLVc.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><strong>2.2&nbsp;&nbsp;&nbsp; 围绕某个点旋转</strong></span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">如果是围绕某个点<img src="http://hi.csdn.net/attachment/201111/19/0_13217099588gza.gif" alt="" />顺时针旋转<img src="http://hi.csdn.net/attachment/201111/19/0_1321709702OsPP.gif" alt="" />,那么可以用矩阵表示为:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_13217100380220.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">可以化为:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_13217100952Vqv.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">很显然,</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">1.&nbsp;&nbsp;&nbsp;<br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;&nbsp;<img src="http://hi.csdn.net/attachment/201111/19/0_1321710153kurQ.gif" alt="" />是将坐标原点移动到点<img src="http://hi.csdn.net/attachment/201111/19/0_13217099588gza.gif" alt="" />后,<img src="http://hi.csdn.net/attachment/201111/19/0_132170933730wW.gif" alt="" />&nbsp;的新坐标。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321710301T9nf.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">是将上一步变换后的<img src="http://hi.csdn.net/attachment/201111/19/0_132170933730wW.gif" alt="" />,围绕新的坐标原点顺时针旋转<img src="http://hi.csdn.net/attachment/201111/19/0_1321709702OsPP.gif" alt="" />&nbsp;。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321710398Z3Je.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">经过上一步旋转变换后,再将坐标原点移回到原来的坐标原点。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">所以,围绕某一点进行旋转变换,可以分成3个步骤,即首先将坐标原点移至该点,然后围绕新的坐标原点进行旋转变换,再然后将坐标原点移回到原先的坐标原点。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><strong>三、 缩放变换</strong></span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">理论上而言,一个点是不存在什么缩放变换的,但考虑到所有图像都是由点组成,因此,如果图像在<em>x</em>轴和<em>y</em>轴方向分别放大<em>k1</em>和<em>k2</em>倍的话,那么图像中的所有点的<em>x</em>坐标和<em>y</em>坐标均会分别放大<em>k1</em>和<em>k2</em>倍,即</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321710511G7yd.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">用矩阵表示就是:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321710517pb9W.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">缩放变换比较好理解,就不多说了。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><strong>四、 错切变换</strong></span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">错切变换(skew)在数学上又称为Shear mapping(可译为“剪切变换”)或者Transvection(缩并),它是一种比较特殊的线性变换。错切变换的效果就是让所有点的<em>x</em>坐标(或者<em>y</em>坐标)保持不变,而对应的<em>y</em>坐标(或者<em>x</em>坐标)则按比例发生平移,且平移的大小和该点到<em>x</em>轴(或y轴)的垂直距离成正比。错切变换,属于等面积变换,即一个形状在错切变换的前后,其面积是相等的。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">比如下图,各点的<em>y</em>坐标保持不变,但其<em>x</em>坐标则按比例发生了平移。这种情况将水平错切。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321710615riwr.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">下图各点的<em>x</em>坐标保持不变,但其<em>y</em>坐标则按比例发生了平移。这种情况叫垂直错切。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321710625smm5.gif" alt="" />&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">假定一个点<img src="http://hi.csdn.net/attachment/201111/19/0_132170933730wW.gif" alt="" />经过错切变换后得到<img src="http://hi.csdn.net/attachment/201111/19/0_1321709345NG9E.gif" alt="" />,对于水平错切而言,应该有如下关系:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321710790633H.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">用矩阵表示就是:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321710798y5L6.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">扩展到3 x 3的矩阵就是下面这样的形式:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_13217108084B3T.gif" alt="" />&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">同理,对于垂直错切,可以有:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_13217108954sms.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">在数学上严格的错切变换就是上面这样的。在Android中除了有上面说到的情况外,还可以同时进行水平、垂直错切,那么形式上就是:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_13217109074Nv2.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><strong>五、 对称变换</strong></span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">除了上面讲到的4中基本变换外,事实上,我们还可以利用Matrix,进行对称变换。所谓对称变换,就是经过变化后的图像和原图像是关于某个对称轴是对称的。比如,某点<img src="http://hi.csdn.net/attachment/201111/19/0_132170933730wW.gif" alt="" />&nbsp;经过对称变换后得到<img src="http://hi.csdn.net/attachment/201111/19/0_1321709345NG9E.gif" alt="" />,</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">如果对称轴是x轴,难么,</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711018S31a.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">用矩阵表示就是:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711026LZ03.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">如果对称轴是y轴,那么,</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711090fhGd.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">用矩阵表示就是:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711099Xhak.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">如果对称轴是<em>y = x</em>,如图:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711217oHNz.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">那么,</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711240gEeT.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">很容易可以解得:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711261E6xG.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">用矩阵表示就是:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_132171128473YK.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">同样的道理,如果对称轴是<em>y = -x</em>,那么用矩阵表示就是:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711292jO01.gif" alt="" />&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">特殊地,如果对称轴是<em>y = kx</em>,如下图:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_13217113506Hb8.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">那么,</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711502QQ7A.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">很容易可解得:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711521GZlt.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">用矩阵表示就是:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711541FJA1.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">当<em>k = 0</em>时,即<em>y = 0</em>,也就是对称轴为<em>x</em>轴的情况;当<em>k</em>趋于无穷大时,即<em>x = 0</em>,也就是对称轴为<em>y</em>轴的情况;当<em>k =</em>1时,即<em>y = x</em>,也就是对称轴为<em>y = x</em>的情况;当<em>k = -</em>1时,即<em>y = -x</em>,也就是对称轴为<em>y = -x</em>的情况。不难验证,这和我们前面说到的4中具体情况是相吻合的。</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">&nbsp;</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">如果对称轴是<em>y = kx + b</em>这样的情况,只需要在上面的基础上增加两次平移变换即可,即先将坐标原点移动到(<em>0, b</em>),然后做上面的关于<em>y = kx</em>的对称变换,再然后将坐标原点移回到原来的坐标原点即可。用矩阵表示大致是这样的:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711616I9SJ.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">需要特别注意:在实际编程中,我们知道屏幕的<em>y</em>坐标的正向和数学中<em>y</em>坐标的正向刚好是相反的,所以在数学上<em>y = x</em>和屏幕上的<em>y = -x</em>才是真正的同一个东西,反之亦然。也就是说,如果要使图片在屏幕上看起来像按照数学意义上<em>y = x</em>对称,那么需使用这种转换:</span> 

</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;"><img src="http://hi.csdn.net/attachment/201111/19/0_1321711292jO01.gif" alt="" /><br />

</span>
</p>
<p style="color:#333333;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:13px;">要使图片在屏幕上看起来像按照数学意义上<em>y = -x</em>对称,那么需使用这种转换:<br />

 </span>
</p>
<span style="color:#333333;font-family:Arial;line-height:26px;font-size:13px;background-color:#FFFFFF;">关于对称轴为y = kx y = kx + b的情况,同样需要考虑这方面的问题。</span>



























































































































































Read >>


Using Tracert command

<div class="desc_tit" style="margin:0px;padding:15px 0px 10px;color:#32628B;font-family:Arial, Helvetica, sans-serif, 宋体;font-size:14px;font-weight:bold;">

路由跟踪在线Tracert工具说明

</div>
<p style="color:#666666;text-indent:2em;font-family:Arial, Helvetica, sans-serif, 宋体;font-size:13px;margin-left:26px;">

Tracert(跟踪路由)是路由跟踪实用程序,用于确定 IP 数据报访问目标所采取的路径。Tracert 命令用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其他主机的路由。

</p>
<div class="desc_tit" style="margin:0px;padding:15px 0px 10px;color:#32628B;font-family:Arial, Helvetica, sans-serif, 宋体;font-size:14px;font-weight:bold;">

Tracert 工作原理

</div>
<p style="color:#666666;text-indent:2em;font-family:Arial, Helvetica, sans-serif, 宋体;font-size:13px;margin-left:26px;">

通过向目标发送不同 IP 生存时间 (TTL) 值的“Internet 控制消息协议 (ICMP)”回应数据包,Tracert 诊断程序确定到目标所采取的路由。要求路径上的每个路由器在转发数据包之前至少将数据包上的 TTL 递减 1。数据包上的 TTL 减为 0 时,路由器应该将“ICMP 已超时”的消息发回源系统。
<p>
    <!--more-->
</p>
<p>
    <br />
</p>

</p>
<p>

Tracert 先发送 TTL 为 1 的回应数据包,并在随后的每次发送过程将 TTL 递增 1,直到目标响应或 TTL 达到最大值,从而确定路由。通过检查中间路由器发回的“ICMP 已超时”的消息确定路由。某些路由器不经询问直接丢弃 TTL 过期的数据包,这在 Tracert 实用程序中看不到。

</p>
<p>

<br />

</p>
<p>

<br />

</p>
<div class="desc_tit" style="margin:0px;padding:15px 0px 10px;color:#32628B;font-family:Arial, Helvetica, sans-serif, 宋体;font-size:14px;font-weight:bold;">

Tracert 命令详解及用法

</div>
<p style="color:#666666;text-indent:2em;font-family:Arial, Helvetica, sans-serif, 宋体;font-size:13px;margin-left:26px;">

Tracert 命令支持多种选项,如下所示。

</p>

        tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name
        -d – 指定不将 IP 地址解析到主机名称。
        -h maximum_hops – 指定跃点数以跟踪到称为 target_name 的主机的路由。
        -j host-list – 指定 Tracert 实用程序数据包所采用路径中的路由器接口列表。
        -w timeout – 等待 timeout 为每次回复所指定的毫秒数。
        target_name – 目标主机的名称或 IP 地址。

<p>

<br />

</p>
<p>

<br />

</p>
<h2 style="color:#002200;font-family:&quot;Trebuchet MS&quot;, helvetica, sans-serif;font-size:2em;">

Tracert详解

</h2>
<p style="color:#002200;font-family:georgia;font-size:15px;">

一个探测路由的程序,可以让我们看见<strong>IP数据报到达目的地经过的路由</strong>。

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

<a href="http://www.ha97.com/tag/tracert">Tracert</a>利用ICMP数据报和IP数据报头部中的TTL值。TTL(Time To Live)是一个IP数据报的生存时间,当每个IP数据报经过路由器的时候都回把TTL值减去1或者减去在路由器中停留的时间,但是大多数数据报在路由器中停留的时间都小于1秒种,因此实际上就是在TTL值减去了1。这样,TTL值就相当于一个路由器的计数器。

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

当路由器接收到一个TTL为0或者1的IP数据报的时候,路由器就不再转发这个数据了,而直接丢弃,并且发送一个ICMP“超时”信息给源主机。Tracert程序的关键就是这个回显的ICMP报文的IP报头的信源地址就是这个路由器的IP地址。同时,如果到达了目的主机,我们并不能知道,于是,Tracert还同时发送一个UDP信息给目的主机,并且选择一个很大的值作为UDP的端口,使主机的任何一个应用程序都不使用这个端口。所以,当达到目的主机的时候,UDP模块就产生一个“端口不可到达”的错误,这样就能判断是否是到达目的地了。

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

有说法是利用ping得到的TTL值来判断主机类型,这种办法可以大概地用来判断,有人问为什么一般得到的都不是标准的TTL值。这个就是因为ICMP数据包走的路由器线路的原因,所以,用ping 和 tracert 一起来用更容易判断主机类型(不过并不一定两次走的路线都一样,所以,还是个大概值,不过更接近点,而且主机的默认TTL值是可以改变的)。

</p>
<p>

<br />

</p>

C:>ping 211.99.199.204
Pinging 211.99.199.204 with 32 bytes of data:
Reply from 211.99.199.204: bytes=32 time=20ms TTL=248
Reply from 211.99.199.204: bytes=32 time〈10ms TTL=248
Reply from 211.99.199.204: bytes=32 time=10ms TTL=248
Reply from 211.99.199.204: bytes=32 time=10ms TTL=248
Ping statistics for 211.99.199.204:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 20ms, Average = 10ms

C:>tracert 211.99.199.204
Tracing route to 211.99.199.204 over a maximum of 30 hops
1 10 ms 10 ms 20 ms 211.99.57.121
2 10 ms 10 ms 10 ms 202.96.13.1
3 〈10 ms 10 ms 20 ms 202.96.13.62
4 20 ms 10 ms 10 ms 210.77.139.186
5 〈10 ms 10 ms 20 ms 210.77.139.170
6 〈10 ms 〈10 ms 10 ms 211.99.193.154
7 〈10 ms 10 ms 〈10 ms 211.99.199.204
Trace complete.

<p>

<br />

</p>
<p>

<br />

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

Ping得到的TTL=248,经过了7个路由器,减少了7,所以主机的TTL值是255。这样来判断吧。

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

下面是一些主机的默认TTL值。<br />

LINUX Kernel 2.2.x & 2.4.x ICMP 回显应答的 TTL 字段值为 64

LINUX Kernel 2.6.x ICMP 回显应答的 TTL 字段值为 47
</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

<a href="http://www.ha97.com/tag/freebsd">FreeBSD</a>&nbsp;4.1, 4.0, 3.4;<br />

Sun Solaris 2.5.1, 2.6, 2.7, 2.8;

OpenBSD 2.6, 2.7,

NetBSD

HP UX 10.20

ICMP 回显应答的 TTL 字段值为 255
</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

<a href="http://www.ha97.com/category/microsoft/windows">Windows</a>&nbsp;95/98/98SE/ME 的ICMP回显应答的 TTL 字段值为 32

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

<a href="http://www.ha97.com/tag/windows">Windows</a>&nbsp;NT/2000/XP/2003/vista/2008/7<br />

ICMP 回显应答的 TTL 字段值为 128
</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

ping和tracert命令详解

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

ping只有在安装了TCP/IP协议以后才可以使用:<br />

ping [-t] [-a] [-n count] [-l length] [-f] [-i ttl] [-v tos] [-r count] [-s count] [-j computer-list] | [-k computer-list] [-w timeout] destination-list

Options:

-t Ping the specified host until stopped.To see statistics and continue – type Control-Break;To stop – type Control-C.

不停的ping地方主机,直到你按下Control-C。

此功能没有什么特别的技巧,不过可以配合其他参数使用,将在下面提到。

-a Resolve addresses to hostnames.

解析计算机NetBios名。

示例:
</p>

C:>ping -a 192.168.1.21
Pinging iceblood.yofor.com [192.168.1.21] with 32 bytes of data:
Reply from 192.168.1.21: bytes=32 time<10ms TTL=254
Reply from 192.168.1.21: bytes=32 time<10ms TTL=254
Reply from 192.168.1.21: bytes=32 time<10ms TTL=254
Reply from 192.168.1.21: bytes=32 time<10ms TTL=254
Ping statistics for 192.168.1.21:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms

<p>

<br />

</p>
<p>

<br />

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

从上面就可以知道IP为192.168.1.21的计算机NetBios名为iceblood.yofor.com。<br />

-n count Number of echo requests to send.

发送count指定的Echo数据包数。
</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

在默认情况下,一般都只发送四个数据包,通过这个命令可以自己定义发送的个数,对衡量网络速度很有帮助,比如我想测试发送50个数据包的返回的平均时间为多少,最快时间为多少,最慢时间为多少就可以通过以下获知:

</p>

C:\>ping -n 50 202.103.96.68
Pinging 202.103.96.68 with 32 bytes of data:
Reply from 202.103.96.68: bytes=32 time=50ms TTL=241
Reply from 202.103.96.68: bytes=32 time=50ms TTL=241
Reply from 202.103.96.68: bytes=32 time=50ms TTL=241
Request timed out.
………………
Reply from 202.103.96.68: bytes=32 time=50ms TTL=241
Reply from 202.103.96.68: bytes=32 time=50ms TTL=241
Ping statistics for 202.103.96.68:
Packets: Sent = 50, Received = 48, Lost = 2 (4% loss),Approximate round trip times in milli-seconds:
Minimum = 40ms, Maximum = 51ms, Average = 46ms

<p>

<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">从以上我就可以知道在给202.103.96.68发送50个数据包的过程当中,返回了48个,其中有两个由于未知原因丢失,这48个数据包当中返回速度最快为40ms,最慢为51ms,平均速度为46ms。</span><br />

<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">-l size Send buffer size.</span>

<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">定义echo数据包大小。</span>

<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">在默认的情况下windows的ping发送的数据包大小为32byt,我们也可以自己定义它的大小,但有一个大小的限制,就是最大只能发送65500byt,也许有人会问为什么要限制到65500byt,因为Windows系列的系统都有一个安全漏洞(也许还包括其他系统)就是当向对方一次发送的数据包大于或等于65532时,对方就很有可能挡机,所以微软公司为了解决这一安全漏洞于是限制了ping的数据包大小。虽然微软公司已经做了此限制,但这个参数配合其他参数以后危害依然非常强大,比如我们就可以通过配合-t参数来实现一个带有攻击性的命令:(以下介绍带有危险性,仅用于试验,请勿轻易施于别人机器上,否则后果自负)</span>
</p>
<p>

<br />

</p>

C:>ping -l 65500 -t 192.168.1.21
Pinging 192.168.1.21 with 65500 bytes of data:
Reply from 192.168.1.21: bytes=65500 time<10ms TTL=254
Reply from 192.168.1.21: bytes=65500 time<10ms TTL=254
………………

<p>

<br />

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

这样它就会不停的向192.168.1.21计算机发送大小为65500byt的数据包,如果你只有一台计算机也许没有什么效果,但如果有很多计算机那么就可以使对方完全瘫痪,我曾经就做过这样的试验,当我同时使用10台以上计算机ping一台Win2000Pro系统的计算机时,不到5分钟对方的网络就已经完全瘫痪,网络严重堵塞,HTTP和FTP服务完全停止,由此可见威力非同小可。<br />

-f Set Don<|>t Fragment flag in packet.

在数据包中发送“不要分段”标志。

在一般你所发送的数据包都会通过路由分段再发送给对方,加上此参数以后路由就不会再分段处理。
</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

-i TTL Time To Live.<br />

指定TTL值在对方的系统里停留的时间。

此参数同样是帮助你检查网络运转情况的。
</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

-v TOS Type Of Service.<br />

将“服务类型”字段设置为 tos 指定的值。

-r count Record route for count hops.

在“记录路由”字段中记录传出和返回数据包的路由。

在一般情况下你发送的数据包是通过一个个路由才到达对方的,但到底是经过了哪些路由呢?通过此参数就可以设定你想探测经过的路由的个数,不过限制在了9个,也就是说你只能跟踪到9个路由,如果想探测更多,可以通过其他命令实现,我将在以后的文章中给大家讲解。以下为示例:
</p>
<p>

<br />

</p>

C:>ping -n 1 -r 9 202.96.105.101 (发送一个数据包,最多记录9个路由)
Pinging 202.96.105.101 with 32 bytes of data:
Reply from 202.96.105.101: bytes=32 time=10ms TTL=249
Route: 202.107.208.187 ->
202.107.210.214 ->
61.153.112.70 ->
61.153.112.89 ->
202.96.105.149 ->
202.96.105.97 ->
202.96.105.101 ->
202.96.105.150 ->
61.153.112.90
Ping statistics for 202.96.105.101:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 10ms, Maximum = 10ms, Average = 10ms

<p>

<br />

</p>
<p>

<br />

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

从上面我就可以知道从我的计算机到202.96.105.101一共通过了202.107.208.187 ,202.107.210.214 , 61.153.112.70 , 61.153.112.89 , 202.96.105.149 , 202.96.105.97这几个路由。<br />

-s count Timestamp for count hops.

指定 count 指定的跃点数的时间戳。

此参数和-r差不多,只是这个参数不记录数据包返回所经过的路由,最多也只记录4个。

-j host-list Loose source route along host-list.

利用 computer-list 指定的计算机列表路由数据包。连续计算机可以被中间网关分隔(路由稀疏源)IP 允许的最大数量为 9。

-k host-list Strict source route along host-list.

利用 computer-list 指定的计算机列表路由数据包。连续计算机不能被中间网关分隔(路由严格源)IP 允许的最大数量为 9。

-w timeout Timeout in milliseconds to wait for each reply.

指定超时间隔,单位为毫秒。

此参数没有什么其他技巧。
</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

ping命令的其他技巧:在一般情况下还可以通过ping对方让对方返回给你的TTL值大小,粗略的判断目标主机的系统类型是Windows系列还是<a href="http://www.ha97.com/category/unix">UNIX</a>/Linux系列,一般情况下Windows系列的系统返回的TTL值在100-130之间,而UNIX/Linux系列的系统返回的TTL值在240-255之间,当然TTL的值在对方的主机里是可以修改的,Windows系列的系统可以通过修改注册表以下键值实现:<br />

[HKEY_LOCAL_MACHINE\sys tem\CurrentControlSet\Services\Tcpip\Parameters]

“DefaultTTL”=dword:000000ff

255—FF

128—80

64—-40

32—-20

在路由器上-c可以指定发送的包数.

例如:ping -c 10000 x.x.x.x

就会ping 10000个数据包.并统计丢包率.
</p>
<p>

<br />

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

<strong>Tracert命令详解2</strong> 

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

该诊断实用程序将包含不同生存时间 (TTL) 值的&nbsp;<a href="http://www.ha97.com/tag/internet">Internet</a>&nbsp;控制消息协议 (ICMP) 回显数据包发送到目标,以决定到达目标采用的路由。要在转发数据包上的 TTL 之前至少递减 1,必需路径上的每个路由器,所以 TTL 是有效的跃点计数。数据包上的 TTL 到达 0 时,路由器应该将“ICMP 已超时”的消息发送回源系统。Tracert 先发送 TTL 为 1 的回显数据包,并在随后的每次发送过程将 TTL 递增 1,直到目标响应或 TTL 达到最大值,从而确定路由。路由通过检查中级路由器发送回的“ICMP 已超时”的消息来确定路由。不过,有些路由器悄悄地下传包含过期 TTL 值的数据包,而 tracert 看不到。<br />

tracert [-d] [-h maximum_hops] [-j computer-list] [-w timeout] target_name
</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

使用 tracert 跟踪网络连接<br />

Tracert(跟踪路由)是路由跟踪实用程序,用于确定 IP 数据报访问目标所采取的路径。Tracert 命令用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其它主机的路由。

Tracert 工作原理

通过向目标发送不同 IP 生存时间 (TTL) 值的“Internet 控制消息协议 (ICMP)”回应数据包,Tracert 诊断程序确定到目标所采取的路由。要求路径上的每个路由器在转发数据包之前至少将数据包上的 TTL 递减 1。数据包上的 TTL 减为 0 时,路由器应该将“ICMP 已超时”的消息发回源系统。

Tracert 先发送 TTL 为 1 的回应数据包,并在随后的每次发送过程将 TTL 递增 1,直到目标响应或 TTL 达到最大值,从而确定路由。通过检查中间路由器发回的“ICMP 已超时”的消息确定路由。某些路由器不经询问直接丢弃 TTL 过期的数据包,这在 Tracert 实用程序中看不到。

Tracert 命令按顺序打印出返回“ICMP 已超时”消息的路径中的近端路由器接口列表。如果使用 -d 选项,则 Tracert 实用程序不在每个 IP 地址上查询 DNS。

在下例中,数据包必须通过两个路由器(10.0.0.1 和 192.168.0.1)才能到达主机 172.16.0.99。主机的默认网关是 10.0.0.1,192.168.0.0 网络上的路由器的 IP 地址是 192.168.0.1。
</p>

C:>tracert 172.16.0.99 -d
Tracing route to 172.16.0.99 over a maximum of 30 hops
1 2s 3s 2s 10,0.0,1
2 75 ms 83 ms 88 ms 192.168.0.1
3 73 ms 79 ms 93 ms 172.16.0.99
Trace complete.

<p>

<br />

</p>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">用 tracert 解决问题</span>

<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">可以使用 tracert 命令确定数据包在网络上的停止位置。下例中,默认网关确定 192.168.10.99 主机没有有效路径。这可能是路由器配置的问题,或者是 192.168.10.0 网络不存在(错误的 IP 地址)。</span>
<p>

<br />

</p>
<p>

<br />

</p>

C:>tracert 192.168.10.99
Tracing route to 192.168.10.99 over a maximum of 30 hops
1 10.0.0.1 reports:Destination net unreachable.
Trace complete.

<p style="color:#002200;font-family:georgia;font-size:15px;">

Tracert 实用程序对于解决大网络问题非常有用,此时可以采取几条路径到达同一个点。

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

Tracert 命令行选项

</p>
<p style="color:#002200;font-family:georgia;font-size:15px;">

Tracert 命令支持多种选项,如下表所示。<br />

tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name

-d 指定不将 IP 地址解析到主机名称。

-h maximum_hops 指定跃点数以跟踪到称为 target_name 的主机的路由。

-j host-list 指定 Tracert 实用程序数据包所采用路径中的路由器接口列表。

-w timeout 等待 timeout 为每次回复所指定的毫秒数。

target_name 目标主机的名称或 IP 地址。

使用 tracert 命令跟踪路径

打开 命令提示符,然后键入:

tracert host_name

或者键入 tracert ip_address

其中 host_name 或 ip_address 分别是远程计算机的主机名或 IP 地址。

例如,要跟踪从该计算机到 www.ha97.com 的连接路由,请在命令提示行键入:
</p>

tracert wwwjinchris.com
<p>
</p> <span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">注意</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">要打开“命令提示符”,请单击“开始”,指向“程序”、“附件”,然后单击“命令提示符”。</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">tracert 命令跟踪 TCP/IP 数据包从该计算机到其它远程计算机所采用的路径。tracert 命令使用 ICMP 响应请求并答复消息(和 ping 命令类似),产生关于经过的每个路由器及每个跃点的往返时间 (RTT) 的命令行报告输出。</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">如果 tracert 失败,可以使用命令输出来帮助确定哪个中介路由器转发失败或耗时太多。</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">参数</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">/d</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">指定不将地址解析为计算机名。</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">-h maximum_hops</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">指定搜索目标的最大跃点数。</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">-j computer-list</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">指定沿 computer-list 的稀疏源路由。</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">-w timeout</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">每次应答等待 timeout 指定的微秒数。</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">target_name</span>
<span style="color:#002200;line-height:22.5px;font-family:georgia;font-size:15px;">目标计算机的名称</span> <p>
</p> <p> <span style="font-size:16px;">在我的本地网络上返回结果如下:</span> </p> <p>
</p> <p>
</p>
Microsoft Windows [版本 6.3.9600]
(c) 2013 Microsoft Corporation。保留所有权利。

C:Userschris>tracert www.jinchris.com

通过最多 30 个跃点跟踪
到 jinchris.com [108.175.158.12] 的路由:

  1     1 ms     1 ms     1 ms  192.168.1.1
  2     9 ms    10 ms    13 ms  222.244.208.1
  3   102 ms   102 ms    20 ms  222.247.26.197
  4    68 ms   101 ms   103 ms  61.137.0.229
  5    75 ms   100 ms   102 ms  202.97.40.45
  6            85 ms          202.97.33.238
  7    22 ms    33 ms    24 ms  202.97.60.50
  8   246 ms   305 ms   307 ms  202.97.50.130
  9   232 ms   304 ms   307 ms  202.97.50.74
 10   495 ms   392 ms   394 ms  xe-9-2-3.edge2.SanJose3.Level3.net [4.53.210.113
]
 11   201 ms   190 ms   192 ms  te2-5.bbr01.eq01.sjc01.networklayer.com [4.53.21
0.10]
 12   220 ms   227 ms   223 ms  ae7.bbr02.eq01.sjc02.networklayer.com [173.192.1
8.165]
 13   224 ms   254 ms   222 ms  ae0.bbr02.cs01.lax01.networklayer.com [173.192.1
8.151]
 14   203 ms   197 ms   196 ms  ae7.bbr01.cs01.lax01.networklayer.com [173.192.1
8.166]
 15   229 ms   232 ms   228 ms  ae19.bbr01.eq01.dal03.networklayer.com [173.192.
18.140]
 16   258 ms   305 ms   307 ms  ae5.dar01.sr01.dal05.networklayer.com [173.192.1
8.215]
 17   224 ms   226 ms   226 ms  173.192.118.149
 18   239 ms   236 ms   237 ms  stats.echidna.arvixe.com [108.175.158.12]

跟踪完成。

C:Userschris>

<p>

<br />

</p>
<p>

<br />

</p>


















































































































Read >>


Introduction to EGL API

<p style="font-family:Arial;font-size:14px;text-indent:2em;background-color:#FFFFFF;">

EGL&nbsp;是&nbsp;OpenGL ES&nbsp;和底层&nbsp;Native&nbsp;平台视窗系统之间的接口。本章主要讲述&nbsp;OpenGL ES&nbsp;的&nbsp;EGL API&nbsp;,以及如何用它创建&nbsp;Context&nbsp;和绘制Surface&nbsp;等,并对用于&nbsp;OpenGL&nbsp;的其他视窗&nbsp;API&nbsp;做了比较分析,比如&nbsp;WGL&nbsp;和&nbsp;GLX&nbsp;。本章中将涵盖如下几个方面:

</p>
<p style="font-family:Arial;font-size:14px;text-indent:2em;background-color:#FFFFFF;">

<span style="font-family:Arial;font-size:14px;line-height:21px;background-color:#FFFFFF;">* &nbsp;EGL&nbsp;综述</span> 

</p>
<p style="font-family:Arial;font-size:14px;text-indent:2em;background-color:#FFFFFF;">

* &nbsp;EGL&nbsp;主要构成(&nbsp;Display&nbsp;,&nbsp;Context&nbsp;,&nbsp;Configuration&nbsp;)

</p>
<p style="font-family:Arial;font-size:14px;text-indent:2em;background-color:#FFFFFF;">

* &nbsp;在&nbsp;Brew&nbsp;和&nbsp;Windows CE&nbsp;上使用&nbsp;EGL

</p>
<p style="font-family:Arial;font-size:14px;text-indent:2em;background-color:#FFFFFF;">

* &nbsp;EGL&nbsp;和其他&nbsp;OpenGL&nbsp;视窗系统的比较

</p>
<p style="font-family:Arial;font-size:14px;text-indent:2em;background-color:#FFFFFF;">

<br />

</p>
<p style="font-family:Arial;font-size:14px;text-indent:2em;background-color:#FFFFFF;">

<p>
    <!--more-->
</p>
<p>
    <br />
</p>

</p>
<h2 style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<span style="font-size:18px;"><strong>EGL&nbsp;介绍</strong></span> 

</h2>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

EGL&nbsp;是为&nbsp;OpenGL ES&nbsp;提供平台独立性而设计。在本章中,你将详细地学习每个&nbsp;EGL API&nbsp;,并了解使用&nbsp;EGL&nbsp;时候需要注意的平台特性和限制。&nbsp;OpenGL ES&nbsp;为附加功能和可能的平台特性开发提供了扩展机制,但仍然需要一个可以让&nbsp;OpenGL ES&nbsp;和本地视窗系统交互且平台无关的层。&nbsp;OpenGL ES&nbsp;本质上是一个图形渲染管线的状态机,而&nbsp;EGL&nbsp;则是用于监控这些状态以及维护&nbsp;Frame buffer&nbsp;和其他渲染&nbsp;Surface&nbsp;的外部层。图&nbsp;2-1&nbsp;是一个典型的&nbsp;EGL&nbsp;系统布局图。

</p>
<p style="text-align:center;">

<img src="/wp-content/uploads/2014/09/20140916080300_43585.gif" alt="" /><span style="line-height:1.5;"></span> 

</p>
<p style="text-align:center;">

figure 1 EGL system structure

</p>
<p style="text-align:left;">

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;视窗设计是基于人们熟悉的用于&nbsp;</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">Microsoft Windows</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;(&nbsp;</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">WGL</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;)和&nbsp;</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">UNIX</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;(&nbsp;</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">GLX</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;)上的&nbsp;</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">OpenGL</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;的&nbsp;</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">Native</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;接口,与后者比较接近。</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">OpenGL ES</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;图形管线的状态被存储于&nbsp;</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;管理的一个&nbsp;</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">Context</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;中。&nbsp;</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">Frame Buffers</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;和其他绘制&nbsp;</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">Surfaces</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;通过&nbsp;</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL API</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;创建、管理和销毁。</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">&nbsp;同时也控制和提供了对设备显示和可能的设备渲染配置的访问。</span> 

</p>
<p style="text-align:left;">

<span style="font-family:Arial;line-height:1.5;background-color:#FFFFFF;"><br />

</span>
</p>
<h2 style="text-align:left;">

<span style="font-family:Arial;line-height:1.5;background-color:#FFFFFF;">EGL 数据类型</span> 

</h2>
<p style="text-align:left;">

<span style="font-family:Arial;font-size:14px;line-height:1.5;background-color:#FFFFFF;">EGL&nbsp;包含了自己的一组数据类型,同时也提供了对一组平台相关的本地数据类型的支持。这些&nbsp;Native&nbsp;数据类型定义在&nbsp;EGL&nbsp;系统的头文件中。一旦你了解这些数据类型之间的不同,使用它们将变得很简单。多数情况下,为保证可移植性,开发人员将尽可能使用抽象数据类型而避免直接使用系统数据类型。通过使用定义在&nbsp;EGL&nbsp;中&nbsp;Native&nbsp;类型,可以让你写的&nbsp;EGL&nbsp;代码运行在任意的&nbsp;EGL&nbsp;的实现上。&nbsp;Native EGL&nbsp;类型说明如下:</span> 

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>NativeDisplayType&nbsp;</strong>平台显示数据类型,标识你所开发设备的物理屏幕

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>NativeWindowType&nbsp;</strong>平台窗口数据类型,标识系统窗口

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>NativePixmapType&nbsp;</strong>可以作为&nbsp;Framebuffer&nbsp;的系统图像(内存)数据类型,该类型只用于离屏渲染

</p>
<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">下面的代码是一个</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">NativeWindowType</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">定义的例子。这只是一个例子,不同平台之间的实现千差万别。使用</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">native</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">类型的关键作用在于为开发者抽象化这些细节。</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">QUALCOMM</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">使用</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">IDIB</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">结构定义</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">native</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">类型,如下:</span>
<p>

<br />

</p>
<p style="text-align:left;">

<br />

</p>

struct IDIB {
     AEEVTBL(IBitmap) *pvt; // virtual table pointer
     IQueryInterface * pPaletteMap; // cache for computed palette mapping info
     byte * pBmp; // pointer to top row
     uint32 * pRGB; // palette
     NativeColor ncTransparent; // 32-bit native color value
     uint16 cx; // number of pixels in width
     uint16 cy; // number of pixels in height
     int16 nPitch; // offset from one row to the next
     uint16 cntRGB; // number of palette entries
     uint8 nDepth; // size of pixel in bits
     uint8 nColorScheme; // IDIB_COLORSCHEME_...(ie. 5-6-5)
     uint8 reserved[6];
};

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">接下来的小节中,我们将深入更多</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">数据类型细节。标准</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">数据类型如表</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">2.1</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">所示。</span>
<p>

<br />

</p>
<p style="text-align:left;">

<br />

</p>
<p style="text-align:left;font-family:Arial;font-size:14px;background-color:#FFFFFF;">

表&nbsp;2.1 EGL&nbsp;数据类型

</p>
<div style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<p style="text-align:center;"> 数据类型 </p> <p style="text-align:center;"> 值 </p>
<p style="text-align:center;"> EGLBoolean </p> <p> EGL_TRUE =1, EGL_FALSE=0 </p>
<p> EGLint </p> <p> int 数据类型 </p>
<p> EGLDisplay </p> <p> 系统显示 ID 或句柄 </p>
<p> EGLConfig </p> <p> Surface 的 EGL 配置 </p>
<p> EGLSurface </p> <p> 系统窗口或 frame buffer 句柄 </p>
<p> EGLContext </p> <p> OpenGL ES 图形上下文 </p>
<p> NativeDisplayType </p> <p> Native 系统显示类型 </p>
<p> NativeWindowType </p> <p> Native 系统窗口缓存类型 </p>
<p> NativePixmapType </p> <p> Native 系统 frame buffer </p>

</div>
<div style="text-align:left;">

<span style="line-height:1.5;"> 
<h2 style="font-family:Arial;background-color:#FFFFFF;">
    EGL Displays
</h2>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">
    &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;EGLDisplay&nbsp;是一个关联系统物理屏幕的通用数据类型。对于&nbsp;PC&nbsp;来说,&nbsp;Display&nbsp;就是显示器的句柄。不管是嵌入式系统或&nbsp;PC&nbsp;,都可能有多个物理显示设备。为了使用系统的显示设备,&nbsp;EGL&nbsp;提供了&nbsp;EGLDisplay&nbsp;数据类型,以及一组操作设备显示的&nbsp;API&nbsp;。
</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面的函数原型用于获取&nbsp;Native Display&nbsp;:
</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">
    EGLDisplay eglGetDisplay (NativeDisplayType display);
</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">
    &nbsp; &nbsp; &nbsp; &nbsp; 其中&nbsp;display&nbsp;参数是&nbsp;native&nbsp;系统的窗口显示&nbsp;ID&nbsp;值。如果你只是想得到一个系统默认的&nbsp;Display&nbsp;,你可以使用&nbsp;<strong>EGL_DEFAULT_DISPLAY&nbsp;</strong>参数。如果系统中没有一个可用的&nbsp;native display ID&nbsp;与给定的&nbsp;display&nbsp;参数匹配,函数将返回&nbsp;EGL_NO_DISPLAY&nbsp;,而没有任何&nbsp;Error&nbsp;状态被设置。
</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">
    由于设置无效的&nbsp;display&nbsp;值不会有任何错误状态,在你继续操作前请检测返回值。
</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">
    下面是一个使用&nbsp;EGL API&nbsp;获取系统&nbsp;Display&nbsp;的例子:
</p>

if (m_eglDisplay == EGL_NO_DISPLAY || eglGetError() != EGL_SUCCESS))
throw error_egl_display;
Initialization 初始化</pre>
</span>
</div>
<p>

<br />

</p>
<p style="text-align:left;">

<br />

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

&nbsp; &nbsp; &nbsp; &nbsp; 和很多视窗&nbsp;API&nbsp;类似,&nbsp;EGL&nbsp;在使用前需要初始化,因此每个&nbsp;EGLDisplay&nbsp;在使用前都需要初始化。初始化&nbsp;EGLDisplay&nbsp;的同时,你可以得到系统中&nbsp;EGL&nbsp;的实现版本号。了解当前的版本号在向后兼容性方面是非常有价值的。嵌入式和移动设备通常是持续的投放到市场上,所以你需要考虑到你的代码将被运行在形形色色的实现上。通过动态查询&nbsp;EGL&nbsp;版本号,你可以为新旧版本的&nbsp;EGL&nbsp;附加额外的特性或运行环境。基于平台配置,软件开发可用清楚知道哪些&nbsp;API&nbsp;可用访问,这将会为你的代码提供最大限度的可移植性。

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面是初始化&nbsp;EGL&nbsp;的函数原型:

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

EGLBoolean eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor);

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

其中&nbsp;dpy&nbsp;应该是一个有效的&nbsp;EGLDisplay&nbsp;。函数返回时,&nbsp;major&nbsp;和&nbsp;minor&nbsp;将被赋予当前&nbsp;EGL&nbsp;版本号。比如&nbsp;EGL1.0&nbsp;,&nbsp;major&nbsp;返回&nbsp;1&nbsp;,minor&nbsp;则返回&nbsp;0&nbsp;。给&nbsp;major&nbsp;和&nbsp;minor&nbsp;传&nbsp;NULL&nbsp;是有效的,如果你不关心版本号。

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eglQueryString()&nbsp;函数是另外一个获取版本信息和其他信息的途径。通过&nbsp;eglQueryString()&nbsp;获取版本信息需要解析版本字符串,所以通过传递一个指针给&nbsp;eglInitializ()&nbsp;函数比较容易获得这个信息。注意在调用&nbsp;eglQueryString()&nbsp;必须先使用&nbsp;eglInitialize()&nbsp;初始化&nbsp;EGLDisplay&nbsp;,否则将得到&nbsp;EGL_NOT_INITIALIZED&nbsp;错误信息。

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面是获取&nbsp;EGL&nbsp;版本字符串信息的函数原型:

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

const char * eglQueryString (EGLDisplay dpy, EGLint name);

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

参数&nbsp;name&nbsp;可以是&nbsp;EGL_VENDOR, EGL_VERSION,&nbsp;或者&nbsp;EGL_EXTENSIONS&nbsp;。这个函数最常用来查询有哪些&nbsp;EGL&nbsp;扩展被实现。所有&nbsp;EGL&nbsp;扩展都是可选的,如果你想使用某个扩展特性,请检查该扩展是否被实现了,而不要想当然假定已经实现了。如果没有扩展被实现,将返回一个Null&nbsp;字符串,如果给定的&nbsp;name&nbsp;参数无效,则会得到&nbsp;EGL_BAD_PARAMETER.&nbsp;错误信息。

</p>
<h2 style="font-family:Arial;background-color:#FFFFFF;">

初始化EGL

</h2>
<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">OpenGL ES是一个平台中立的图形库,在它能够工作之前,需要与一个实际的窗口系统关联起来,这与OpenGL是一样的。但不一样的是,这部份工作有标准,这个标 准就是EGL。而OpenGL时代在不同平台上有不同的机制以关联窗口系统,在Windows上是wgl,在X-Window上是xgl,在Apple OS上是agl等。EGL的工作方式和部份术语都接近于xgl。</span>



<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">OpenGL ES的初始化过程如下图所示意:</span>
<p>

<br />

</p>
<p style="text-align:left;">

<br />

</p>
<p style="text-align:center;">

<img src="/wp-content/uploads/2014/09/20140916080844_31236.png" alt="" /> 

</p>
<p style="text-align:center;">

figure 2. OpenGL ES Initialize

</p>
<p style="text-align:left;">

<br />

</p>
<h4>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">1. 获取Display。</span> 

</h4>
<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">Display代表显示器,在有些系统上可以有多个显示器,也就会有多个Display。获得Display要调用EGLboolean eglGetDisplay(NativeDisplay dpy),参数一般为 EGL_DEFAULT_DISPLAY 。该参数实际的意义是平台实现相关的,在X-Window下是XDisplay ID,在MS Windows下是Window DC。</span>
<p>

<br />

</p>
<p style="text-align:left;">

<br />

</p>
<h3>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">2. 初始化egl。</span> 

</h3>
<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">调用 EGLboolean eglInitialize(EGLDisplay dpy, EGLint major, EGLint minor),该函数会进行一些内部初始化工作,并传回EGL版本号(major.minor)。</span>



<h4>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">3. 选择Config。</span> 

</h4>
<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">所为Config实际指的是FrameBuffer的参数,在MS Windows下对应于PixelFormat,在X-Window下对应Visual。一般用EGLboolean eglChooseConfig(EGLDisplay dpy, const EGLint attr_list, EGLConfig config, EGLint config_size, EGLint num_config),其中attr_list是以EGL_NONE结束的参数数组,通常以id,value依次存放,对于个别标识性的属性可以只有 id,没有value。另一个办法是用EGLboolean eglGetConfigs(EGLDisplay dpy, EGLConfig config, EGLint config_size, EGLint *num_config) 来获得所有config。这两个函数都会返回不多于config_size个Config,结果保存在config[]中,系统的总Config个数保存 在num_config中。可以利用eglGetConfig()中间两个参数为0来查询系统支持的Config总个数。</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">Config有众多的Attribute,这些Attribute决定FrameBuffer的格式和能力,通过eglGetConfigAttrib ()来读取,但不能修改。</span>



<h3>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">4. 构造Surface。</span> 

</h3>
<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">Surface实际上就是一个FrameBuffer,通过 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig confg, NativeWindow win, EGLint *cfg_attr) 来创建一个可实际显示的Surface。系统通常还支持另外两种Surface:PixmapSurface和PBufferSurface,这两种都不 是可显示的Surface,PixmapSurface是保存在系统内存中的位图,PBuffer则是保存在显存中的帧。</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">Surface也有一些attribute,基本上都可以故名思意, EGL_HEIGHT EGL_WIDTH EGL_LARGEST_PBUFFER EGL_TEXTURE_FORMAT EGL_TEXTURE_TARGET EGL_MIPMAP_TEXTURE EGL_MIPMAP_LEVEL,通过eglSurfaceAttrib()设置、eglQuerySurface()读取。</span>



<h4>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">5. 创建Context。</span> 

</h4>
<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">OpenGL的pipeline从程序的角度看就是一个状态机,有当前的颜色、纹理坐标、变换矩阵、绚染模式等一大堆状态,这些状态作用于程序提交的顶点 坐标等图元从而形成帧缓冲内的像素。在OpenGL的编程接口中,Context就代表这个状态机,程序的主要工作就是向Context提供图元、设置状 态,偶尔也从Context里获取一些信息。</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">用EGLContext eglCreateContext(EGLDisplay dpy, EGLSurface write, EGLSurface read, EGLContext * share_list)来创建一个Context。</span>
<p>

<br />

</p>
<p style="text-align:left;">

<br />

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<br />

</p>
<h4>

6. 绘制。

</h4>
应用程序通过OpenGL API进行绘制,一帧完成之后,调用eglSwapBuffers(EGLDisplay dpy, EGLContext ctx)来显示。
<p>

<br />

</p>
<h3 style="font-family:Arial;background-color:#FFFFFF;">

EGL Configurations

</h3>
<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGLConfigs</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> 是一个用来描述 </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL surface</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> 配置信息的数据类型。要获取正确的渲染结果, </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">Surface</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> 的格式是非常重要的。根据平台的不同,</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">surface</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> 配置可能会有限制,比如某个设备只支持 </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">16</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> 位色深显示,或是不支持 </span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">stencil buffer</span><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;"> ,还有其他的功能限制或精度的差异。</span>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面是获取系统可用的&nbsp;EGL&nbsp;配置信息的函数原型:

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

EGLBoolean eglGetConfigs (EGLDisplay dpy, EGLConfig *configs,EGLint config_size, EGLint *num_config);

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

参数&nbsp;configs&nbsp;将包含在你的平台上有效的所有&nbsp;EGL framebuffer&nbsp;配置列表。支持的配置总数将通过&nbsp;num_config&nbsp;返回。实际返回的&nbsp;configs&nbsp;的配置个数依赖于程序传入的&nbsp;config_size&nbsp;。如果&nbsp;config_size &lt; num_config&nbsp;,则不是所有的配置信息都将被返回。如果想获取系统支持的所有配置信息,最好的办法就是先给&nbsp;eglGetConfig&nbsp;传一个&nbsp;NULL&nbsp;的&nbsp;configs&nbsp;参数,&nbsp;num_config&nbsp;将得到系统所支持的配置总数,然后用它来给configs&nbsp;分配合适的内存大小,再用得到的&nbsp;configs&nbsp;来调用&nbsp;eglGetConfig&nbsp;。

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面是如果使用&nbsp;eglGetConfig()&nbsp;函数的例子:

</p>

EGLConfig *configs_list;
EGLint num_configs;
// Main Display
m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if( m_eglDisplay == EGL_NO_DISPLAY || eglGetError() != EGL_SUCCESS )
return FALSE;
if( eglInitialize( m_eglDisplay, NULL, NULL ) == EGL_FALSE || eglGetError() != EGL_SUCCESS )
return FALSE;
// find out how many configurations are supported
if ( eglGetConfigs( m_eglDisplay, NULL, 0, &num_configs)== EGL_FALSE || eglGetError() != EGL_SUCCESS )
return FALSE;
configs_list = malloc(num_configs * sizeof(EGLConfig));
if (configs_list == (EGLConfig *)0)
return FALSE;
// Get Configurations
if( eglGetConfigs( m_eglDisplay, configs_list, num_configs, &num_configs)== EGL_FALSE || eglGetError() != EGL_SUCCESS )
return FALSE;

<p>

<br />

</p>
<p style="text-align:left;">

<br />

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

由于当前平台的限制,通常只有很少的配置可用。系统支持的配置通常是利用系统硬件提供最好的性能。当你移植游戏到多个平台,它们的EGL&nbsp;配置可能会有细微的差别,我们希望作为通用的移植问题来直接处理这些问题。

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

&nbsp;

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

选择一个&nbsp;EGL Configuration

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

基于&nbsp;EGL&nbsp;的属性,你可以定义一个希望从系统获得的配置,它将返回一个最接近你的需求的配置。选择一个你特有的配置是有点不合适的,因为只是在你的平台上使用有效。&nbsp;eglChooseConfig()&nbsp;函数将适配一个你所期望的配置,并且尽可能接近一个有效的系统配置。

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面是选择一个&nbsp;EGL&nbsp;配置的函数原型:

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

EGLConfig *configs, EGLint config_size, EGLint * num_config);

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

参数&nbsp;attrib_list&nbsp;指定了选择配置时需要参照的属性。参数&nbsp;configs&nbsp;将返回一个按照&nbsp;attrib_list&nbsp;排序的平台有效的所有&nbsp;EGL framebuffer&nbsp;配置列表。参数&nbsp;config_size&nbsp;指定了可以返回到&nbsp;configs&nbsp;的总配置个数。参数&nbsp;num_config&nbsp;返回了实际匹配的配置总数。

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面是如果使用&nbsp;eglChoosetConfig()&nbsp;函数的例子:

</p>

EGLint attrs[3] = { EGL_DEPTH_SIZE, 16, EGL_NONE };
EGLint num_configs;
EGLConfigs *configs_list;
// Get the display device
if ((eglDisplay = eglGetDisplay(EGL_NO_DISPLAY)) == EGL_NO_DISPLAY)
{
return eglGetError();
}
// Initialize the display
if (eglInitialize(eglDisplay, NULL, NULL) == EGL_FALSE)
{
return eglGetError();
}
// Obtain the total number of configurations that match
if (eglChooseConfig(eglDisplay, attrs, NULL, 0, &num_configs) == EGL_FALSE)
{
return eglGetError();
}
configs_list = malloc(num_configs * sizeof(EGLConfig));
if (configs_list == (EGLConfig *)0)
return eglGetError();
// Obtain the first configuration with a depth buffer of 16 bits
if (!eglChooseConfig(eglDisplay, attrs, &configs_list, num_configs, &num_configs))
{
return eglGetError();
}

<p style="text-align:left;">

<br />

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

如果找到多个合适的配置,有一个简单的排序算法用来匹配最接近你所查询的配置。表&nbsp;2-2&nbsp;显示了基于属性值的用来选择和排序的顺序,也包括了&nbsp;EGL&nbsp;规范中所有&nbsp;EGL&nbsp;配置属性及其默认值。

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

表&nbsp;2.1 EGL&nbsp;配置属性默认值和匹配法则

</p>
<div style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

<p> 属性 </p> <p> 数据类型 </p> <p> 默认值 </p> <p> 排序优先级 </p> <p> 选择顺序 </p>
<p> EGL_BUFFER_SIZE </p> <p> int </p> <p> 0 </p> <p> 3 </p> <p> Smaller value </p>
<p> EGL_RED_SIZE </p> <p> int </p> <p> 0 </p> <p> 2 </p> <p> Larger value </p>
<p> EGL_GREEN_SIZE </p> <p> int </p> <p> 0 </p> <p> 2 </p> <p> Larger value </p>
<p> EGL_BLUE_SIZE </p> <p> int </p> <p> 0 </p> <p> 2 </p> <p> Larger value </p>
<p> EGL_ALPHA_SIZE </p> <p> int </p> <p> 0 </p> <p> 2 </p> <p> Larger value </p>
<p> EGL_CONFIG_CAVET </p> <p> enum </p> <p> EGL_DONT_CARE </p> <p> 1(first) </p> <p> Exact value </p>
<p> EGL_CONFIG_ID </p> <p> int </p> <p> EGL_DONT_CARE </p> <p> 9 </p> <p> Exact value </p>
<p> EGL_DEPTH_SIZE </p> <p> int </p> <p> 0 </p> <p> 6 </p> <p> Smaller value </p>
<p> EGL_LEVEL </p> <p> int </p> <p> 0 </p> <p> - </p> <p> Equal value </p>
<p> EGL_NATIVE_RENDERABLE </p> <p> Boolean </p> <p> EGL_DONT_CARE </p> <p> - </p> <p> Exact value </p>
<p> EGL_NATIVE_VISUAL_TYPE </p> <p> int </p> <p> EGL_DONT_CARE </p> <p> 8 </p> <p> Exact value </p>
<p> EGL_SAMPLE_BUFFERS </p> <p> int </p> <p> 0 </p> <p> 4 </p> <p> Smaller value </p>
<p> EGL_SAMPLES </p> <p> int </p> <p> 0 </p> <p> 5 </p> <p> Smaller value </p>
<p> EGL_STENCIL_SIZE </p> <p> int </p> <p> 0 </p> <p> 7 </p> <p> Smaller value </p>
<p> EGL_SURFACE_TYPE </p> <p> bitmask </p> <p> EGL_WINDOW_BIT </p> <p> - </p> <p> Mask value </p>
<p> EGL_TRANSPARENT_TYPE </p> <p> enum </p> <p> EGL_NONE </p> <p> - </p> <p> Exact value </p>
<p> EGL_TRANSPARENT_RED_VALUE </p> <p> int </p> <p> EGL_DONT_CARE </p> <p> - </p> <p> Exact value </p>
<p> EGL_TRANSPARENT_GREEN_VALUE </p> <p> int </p> <p> EGL_DONT_CARE </p> <p> - </p> <p> Exact value </p>
<p> EGL_TRANSPARENT_BLUE_VALUE </p> <p> int </p> <p> EGL_DONT_CARE </p> <p> - </p> <p> Exact value </p>

</div>
<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">这里不是讲OpenGL的教程,事实上,OpenGL 是与硬件和平台无关的。这里主要讲在Android下,OpenGL 应用的基本架构、OpenGL 与Android 窗口系统通过EGL的绑定</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL是图形资源管理层,工作在图形渲染API(如OpenGL)与运行平台(Android)的窗口系统之间</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">从1.5(API 3)开始Android 支持 OpenGL ES 1.0,到 2.2(API 8)时支持 OpenGL ES 2.0。版本对应关系如下(待完善)</span>



<p>

<br />

</p>
<p>

<br />

</p>
<p>

Android SDK API EGL OpenGL ES OpenGL
1.5 3 1.0 1.0 1.3
1.6 4      
2.1 7      
2.2 8   2.0  

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">Android、EGL、OpenGL 三者关系如下:</span>
</p>
<p>

<br />

</p>
Android Windowing ( SurfaceView) ^ |
 +--------+------------------------+ | EGL | +------------+ | |
 | | Display | | | | +------------+ | |
+-----v-------+ +------------+ | | | Surface | | Config | |
| +-----^-------+ +------------+ | | | +------------+ | |
| | Context | | | | +------------+ | +--------+------------------------+ |
 v OpenGL <span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL 官网有一个1.0版本的 Specification,详细讲述了Surface、Display、Context 概念。简单地说</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">(1)Display 是图形显示设备(显示屏)的抽象表示。大部分EGL函数都要带一个 Display 作为参数</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">(2)Context 是 OpenGL 状态机。Context 与 Surface 可以是一对一、多对一、一对多的关系</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">(3)Surface 是绘图缓冲,可以是 window、pbuffer、pixmap 三种类型之一</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL 工作流程为:</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">(1)初始化</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">(2)配置</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">(3)创建Surface(绑定到平台Windowing系统)</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">(4)绑定Surface与Context</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">(5)Main Loop:渲染(OpenGL),交换离线缓冲(offline buffer)与显示缓冲</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">(6)释放资源</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">在Android SDK中,EGL类在javax.microedition.khronos.egl包中,OpenGL 类在 javax.microedition.khronos.opengles包中</span>

<p>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">下面是一个完整的 EGL/OpenGL 应用,当点击屏幕时,根据点击坐标更新屏幕背景颜色</span> 

</p>
<p>

<br />

</p>

import javax.microedition.khronos.egl.EGL10; 
import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.egl.EGLContext; 
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface; 
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.os.Bundle; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.Window; 
import android.view.WindowManager;
import android.view.SurfaceHolder.Callback; 
import android.view.View.OnTouchListener;
public class OpenGlDemo extends Activity implements Callback, Runnable, OnTouchListener
{ 
    private SurfaceView view;
    private boolean rendering = false;
    private final Object renderLock = new Object();
    private GL10 gl;
    private float red = 0.2f, green = 0.3f, blue = 0.8f;
    @Override
    public void onCreate(Bundle savedInstanceState)
    { 
        requestWindowFeature(Window.FEATURE_NO_TITLE); 
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState); 
        view = new SurfaceView(this); 
        view.getHolder().addCallback(this); 
        view.setOnTouchListener(this); 
        setContentView(view); 
    }
    public void surfaceCreated(SurfaceHolder holder)
    {
        synchronized (renderLock)
        { 
            Log.d("OpenGlDemo >>>", "Start rendering..."); 
            rendering = true;
            new Thread(this).start();
         }
    } 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {   
        
    }
    public void surfaceDestroyed(SurfaceHolder holder) 
    { 
        synchronized (renderLock) 
        { 
            rendering = false;
         } 
    } 
    public void run() 
    { 
        Init EGL10 egl = (EGL10) EGLContext.getEGL(); 
        EGLDisplay disp = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); 
        egl.eglInitialize(disp, new int[2]); 
        Config EGLConfig[] configs = new EGLConfig[1];
        egl.eglChooseConfig(disp, 
             new int[]{ EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE }, configs, 1, new int[1]); 
        EGLConfig config = configs[0]; 
        //Create surface and bind with native windowing 
        EGLSurface surf = egl.eglCreateWindowSurface(disp, config, view .getHolder(), null); 
        //Bind with OpenGL context 
        EGLContext contx = egl.eglCreateContext(disp, config, EGL10.EGL_NO_CONTEXT, null); 
        egl.eglMakeCurrent(disp, surf, surf, contx); 
        gl = (GL10) contx.getGL(); 
        while (true)
        { 
            synchronized (renderLock) 
            {
                if (!rendering) 
                { 
                    break;
                 } 
            }
            render(gl);
            egl.eglSwapBuffers(disp, surf); 
        } 
        Log.d("OpenGlDemo >>>", "Stop rendering");
        // Finalize
        egl.eglMakeCurrent(disp, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); 
        egl.eglDestroyContext(disp, contx); 
        egl.eglDestroySurface(disp, surf);
        gl = null; 
   } 
    private void render(GL10 gl) 
    { 
        gl.glClearColor(red, green, blue, 1.0f); 
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    } 
    public boolean onTouch(View view, MotionEvent e)
    { 
        red = e.getX() / view.getWidth(); 
        green = e.getY() / view.getHeight();
        blue = 1.0f;
        return true;
    }
}

<p>

<br />

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

上面的应用,就是在Android 下的OpenGL 应用的最基本结构,涉及了不少EGL细节的操作

</p>
<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">如果你google 一下“Android OpenGL”,得到结果十之八九是使用了android.opengl.GLSurfaceView。使用GLSurfaceView实现上面的简单应用,代码要简单得多</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">是这样的:GLSurfaceView隐藏了EGL操作及渲染线程的细节,并提供了生命周期回调方法</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">但,基本上,使用 GLSurfaceView 没法控制渲染循环,例如:你没法控制帧速(fps)</span>



<p>

<br />

</p>
<p>

EGL是由Khronos Group提供的一组平台无关的API。它的功能:<br />

1> 和本地窗口系统(native windowing system)通讯;

2> 查询可用的配置;

3> 创建OpenGL ES可用的“绘图表面”(drawing surface);

4> 同步不同类别的API之间的渲染,比如在OpenGL ES和OpenVG之间同步,或者在OpenGL和本地窗口的绘图命令之间;

5> 管理“渲染资源”,比如纹理映射(rendering map)。

● EGLDisplay

EGL可运行于GNU/Linux的X Window System,Microsoft Windows和MacOS X的Quartz。

EGL把这些平台的显示系统抽象为一个独立的类型:EGLDisplay。

使用EGL的第一步就是初始化一个可用的EGLDisplay:
</p>
<p>

<br />

</p>

 EGLint majorVersion;  
    EGLint minorVersion;  
    EGLBoolean success = EGL_FALSE;  
    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);  
    if (display != EGL_NO_DISPLAY)  
    {  
        success = eglInitialize(display, &majorVersion, &minorVersion);  
    }  
    if (success != EGL_TRUE)  
    {  
        EGLint errno = eglGetError();  
        if (errno != EGL_SUCCESS)  
        {  
            _TCHAR errmsg[32];  
            _stprintf(errmsg, _T("[EGL] Initialization failed. Error code: 0x%04x"), errno);  
            // EGL_BAD_DISPLAY      EGLDisplay参数错误  
            // EGL_NOT_INITIALIZED  EGL不能初始化  
        }  
    }  

<p>

<br />

</p>
<p>

<br />

</p>
<p>

<br />

</p>
<p>

<br />

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

这里用到了三个EGL函数:

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

&nbsp;&nbsp;&nbsp; EGLDisplay eglGetDisplay(EGLNativeDisplayType id); &nbsp;<br />

    EGLBoolean eglInitialize(EGLDisplay display, EGLint majorVersion, EGLint minorVersion);  

    EGLint eglGetError();  
</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

● EGLConfig<br />

初始化过后,要选择一个合适的“绘图表面”。
</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

&nbsp;&nbsp;&nbsp; EGLBoolean eglGetConfigs(EGLDisplay display,&nbsp;&nbsp;&nbsp; // 已初始化好&nbsp;

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

&nbsp;&nbsp; EGLConfig* configs,&nbsp;&nbsp;&nbsp; // 如果为NULL,则返回EGL_TRUE和numConfigs,即图形系统所有可用的配置 &nbsp;<br />

   EGLint maxConfigs,     // 上面那个configs数组的容量  

   EGLint* numConfigs);   // 图形系统返回的实际的可用的配置个数,存储在configs数组里  
</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

用例:

</p>
<p>

<span style="line-height:1.5;"> </span> 

</p>

static const EGLint CONFIG_ATTRIBS[] =  
    {  
        EGL_RED_SIZE,       5,  
        EGL_GREEN_SIZE,     6,  
        EGL_BLUE_SIZE,      5,  
        EGL_DEPTH_SIZE,     16,  
        EGL_ALPHA_SIZE,     EGL_DONT_CARE,  
        EGL_STENCIL_SIZE,   EGL_DONT_CARE,  
        EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,  
        EGL_NONE            // 属性表以该常量为结束符  
    };  
    GLint numConfigs;  
    EGLConfig config;  
    if (success != EGL_FALSE)  
        success = eglGetConfigs(display, NULL, 0, &numConfigs);  
    if (success != EGL_FALSE && numConfigs > 0)  
        success = eglChooseConfig(display, CONFIG_ATTRIBS, &config, 1, &numConfigs); 

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">可以查询某个配置的某个属性:</span>
<p>

<br />

</p>
<p>

<span style="line-height:1.5;"> </span> 

</p>

    EGLBoolean eglGetConfigAttrib(EGLDisplay display,    // 已初始化  
                                  EGLConfig config,      // 某个配置  
                                  EGLint attribute,      // 某个属性  
                                  EGLint * value);  

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">让EGL为你选择一个配置:</span>
<p>

<br />

</p>
<p>

<span style="line-height:1.5;"> </span> 

</p>

 EGLBoolean eglChooseConfig(EGLDisplay display,  
                               const EGLint* attribs,    // 你想要的属性事先定义到这个数组里  
                               EGLConfig* configs,       // 图形系统将返回若干满足条件的配置到该数组  
                               EGLint maxConfigs,        // 上面数组的容量  
                               EGLint* numConfigs);      // 图形系统返回的可用的配置个数  



<p>

<br />

</p>
<p>

<span style="line-height:1.5;"><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL如果选择了多个配置给你,则按一定规则放到数组里:</span><br />

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">1> EGL_CONFIG_CAVEAT</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">2> EGL_COLOR_BUFFER_TYPE</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">3> 按color buffer所占位宽</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">4> EGL_BUFFER_SIZE</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">5> EGL_SAMPLE_BUFFERS</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">6> EGL_SAMPLES</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">7> EGL_DEPTH_SIZE</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">8> EGL_STENCIL_SIZE</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">9> EGL_ALPHA_MASK_SIZE</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">10> EGL_NATIVE_VISUAL_TYPE</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">11> EGL_CONFIG_ID</span>



<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">● EGLSurface</span></span>
</p>
<p>

<span style="line-height:1.5;"> </span> 

</p>

 EGLSurface eglCreateWindowSurface(EGLDisplay display,  
                                      EGLConfig config,  
                                      EGLNativeWindowType window, // 在Windows上就是HWND类型  
                                      const EGLint* attribs);     // 此属性表非彼属性表  

<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

这里的属性表并非用于OpenGL ES 2.0,而是其它的API,比如OpenVG。我们只需要记住一个:EGL_RENDER_BUFFER [EGL_BACK_BUFFER, EGL_FRONT_BUFFER]。<br />

OpenGL ES 2.0是必须工作于双缓冲窗口系统的。

该属性表当然也可以为NULL,也可以只有一个EGL_NONE。那表示所有属性使用默认值。

如果函数返回EGL_NO_SURFACE,则失败。错误码:

EGL_BAD_MATCH:          属性设置错误。比如EGL_SURFACE_TYPE没有设置EGL_WINDOW_BIT

EGL_BAD_CONFIG:         因为配置错误,图形系统不支持

EGL_BAD_NATIVE_WINDOW:  窗口句柄错误

EGL_BAD_ALLOC:          无法创建绘图表面。比如先前已经创建一个了。
</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

● pixel buffer<br />

OpenGL ES 2.0可以向pixel buffer渲染,同样使用硬件加速。pbuffer经常用来生成纹理映射。如果想渲染到纹理,常用更高效的framebuffer对象。

在EGL_SURFACE_TYPE里使用使用EGL_PBUFFER_BIT可创建pbuffer:
</p>

 EGLSurface eglCreatePbufferSurface(EGLDisplay display,  
                                       EGLConfig config,  
                                       const EGLint* attribs);  

<p>

<span style="line-height:1.5;"><br />

</span>
</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

使用到的属性:

</p>
<p style="font-family:Arial;font-size:14px;background-color:#FFFFFF;">

EGL_WIDTH, EGL_HEIGHT<br />

EGL_LARGEST_PBUFFER:        如果参数不合适,可使用最大的pbuffer

EGL_TEXTURE_FORMAT:         [EGL_NO_TEXTURE] 如果pbuffer要绑定到纹理映射,要指定纹理的格式

EGL_TEXTURE_TARGET:            [EGL_NO_TEXTURE, EGL_TEXTURE_2D]

EGL_MIPMAP_TEXTRUE:         [EGL_TRUE, EGL_FALSE]
</p>
<p>

<span style="line-height:1.5;"><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">创建失败时返回EGL_NO_SURFACE,错误码:</span><br />

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL_BAD_ALLOC:      缺少资源</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL_BAD_CONFIG:     配置错误</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL_BAD_PARAMETER:  EGL_WIDTH和EGL_HEIGHT为负数</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL_BAD_MATCH:      配置错误;如果用于纹理映射,则高宽参数错误;EGL_TEXTURE_FORMAT和EGL_TEXTURE_TARGET只有一个不是EGL_NO_TEXTURE</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">EGL_BAD_ATTRIBUTE:  指定了EGL_TEXTURE_FORMAT、EGL_TEXTURE_TARGET或者EGL_MIPMAP_TEXTRUE,却不指定使用OpenGLES在配置里</span></span>
</p>
<p>

<span style="line-height:1.5;"><span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">使用pbuffer的例子:</span></span> 

</p>
<p>

<span style="line-height:1.5;"> </span> 

</p>

 EGLint cfgAttribs[] =  
    {  
        EGL_SURFACE_TYPE,    EGL_PBUFFER_BIT,  
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,  
        EGL_RED_SIZE,        5,  
        EGL_GREEN_SIZE,      6,  
        EGL_BLUE_SIZE,       5,  
        EGL_DEPTH_SIZE,      1,  
        EGL_NONE  
    };  
    const EGLint MAX_CONFIG = 10;  // 我们要从10个配置里挑选一个  
    EGLConfig configs[MAX_CONFIG];  
    EGLint numConfigs;  
    if (!eglChooseConfig(display, cfgAttribs, configs, MAX_CONFIG, &numConfigs))  
    {  
        // 报错  
    }  
    else  
    {  
        // 挑选一个配置  
    }  
    EGLint PBufAttribs[] =  
    {  
        EGL_WIDTH,  512,  
        EGL_HEIGHT, 512,  
        EGL_LARGEST_PBUFFER, EGL_TRUE,  
        EGL_NONE  
    };  
    EGLRenderSurface pbuffer = eglCreatePbufferSurface(display, config, PBufAttribs);  
    if (pbuffer == EGL_NO_SURFACE)  
    {  
        // 创建失败,报各种错  
    }  
    EGLint width, height;  
    if (!eglQuerySurface(display, pbuffer, EGL_HEIGHT, &height)  
        || !eglQuerySurface(display, pbuffer, EGL_WIDTH, &width)  
    {  
        // 查询不到信息,报错  
    }  

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">pbuffer和普通的窗口渲染最大的不同是不能swap,要么拷贝其值,要么修改其绑定成为纹理。</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">● EGLContext</span>
<p>

<br />

</p>
<p>

<span style="line-height:1.5;"> </span> 

</p>

EGLContext eglCreateContext(EGLDisplay display,  
                                EGLConfig config,  
                                EGLContext context,    // EGL_NO_CONTEXT表示不向其它的context共享资源  
                                const EGLint * attribs)// 我们暂时只用EGL_CONTEXT_CLIENT_VERSION  
    const EGLint attribs[] =  
    {  
        EGL_CONTEXT_CLIENT_VERSION, 2,  
        EGL_NONE  
    };  
    EGLContext context = eglCreateContext(display, cfg, EGL_NO_CONTEXT, attribs);  
    if (context == EGL_NO_CONTEXT)  
    {  
        if (EGL_BAD_CONFIG == eglGetError())  
        {  
            ...  
        }  
    }  
    if (!eglMakeCurrent(display, window, window, context)) // 两个window表示读写都在一个窗口  
    {  
        // 报错  
    }  

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">● 渲染同步</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">只使用OpenGL ES 2.0,那么,glFinish即可保证所有的渲染工作进行下去。</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">但使用OpenVG或本地图形API渲染字体,要比使用OpenGL ES 2.0要容易。所以,你可能要在同一个窗口使用多个库来渲染。</span>



<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">可以用EGL的同步函数:EGLBoolean eglWaitClient() 延迟客户端的执行,等待服务器端完成OpenGL ES 2.0或者OpenVG的渲染。</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">如果失败,返回错误码:EGL_BAD_CURRENT_SURFACE。</span>



<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">如果要等待本地图形API的渲染完成,使用:EGLBoolean eglWaitNative(EGLint engine)。</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">engine参数必须是EGL_CORE_NATIVE_ENGINE。其它值都是通过EGL扩展来指定。</span>

<span style="font-family:Arial;font-size:14px;line-height:26px;background-color:#FFFFFF;">如果失败,返回错误码:EGL_BAD_PARAMETER。</span>

<p>

<br />

</p>
<p>

<span style="line-height:1.5;"><br />

</span>
</p>
<p>

<br />

</p>
<p>

<span style="line-height:1.5;"><br />

</span>
</p>
<p>

<br />

</p>


























































































































































































































Read >>


单端模拟输入 与 差分模拟输入的区别

<p>

<span style="font-size:18px;">单端输入,输入信号均以共同的地线为基准.这种输入方法主要应用于输入信号电压较高(高于1 V),信号源到模拟输入硬件的导线较短(低于15 ft),且所有的输入信号共用一个基准地线.如果信号达不到这些标准,此时应该用差分输入.对于差分输入,每一个输入信号都有自有的基准地线;由于共模噪声可以被导线所消除,从而减小了噪声误差.单端输入时, 是判断信号与 GND 的电压差. &nbsp;</span> 

</p>
<p>

<span style="font-size:18px;"><br />

</span>
</p>
<p>

<span style="font-size:18px;">差分输入时, 是判断两个信号线的电压差. &nbsp;</span> 

</p>
<p>

<span style="font-size:18px;">
<p>
    <!--more-->
</p>
<p>
    <br />
</p>



</span>
</p>
<p>

<span style="font-size:18px;">信号受干扰时, 差分的两线会同时受影响, 但电压差变化不大. (抗干扰性较佳) &nbsp;而单端输入的一线变化时, GND 不变, 所以电压差变化较大. (抗干扰性较差) &nbsp;差分信号和普通的单端信号走线相比,最明显的优势体现在以下三个方面: &nbsp;</span> 

</p>
<p>

<span style="font-size:18px;"><br />

</span>
</p>
<span style="font-size:18px;">a.抗干扰能力强,因为两根差分走线之间的耦合很好,当外界存在噪声干扰时,几乎是同时被耦合到两条线上,而接收端关心的只是两信号的差值,所以外界的共模噪声可以被完全抵消。  </span>

<span style="font-size:18px;">b.能有效抑制EMI,同样的道理,由于两根信号的极性相反,他们对外辐射的电磁场可以相互抵消,耦合的越紧密,泄放到外界的电磁能量越少。  </span>

<p>

<span style="font-size:18px;">c.时序定位精确,由于差分信号的开关变化是位于两个信号的交点,而不像普通单端信号依靠高低两个阈值电压判断,因而受工艺,温度的影响小,能降低时序上的误差,同时也更适合于低幅度信号的电路。目前流行的LVDS(low voltage differential signaling)就是指这种小振幅差分信号技术。 &nbsp;&nbsp;</span> 

</p>
<p>

<span style="font-size:18px;"><br />

</span>
</p>
<span style="font-size:18px;">当AD的输入信号只有一路时,为了更好地抑制共模噪声,我们可以采用差分输入方式。</span>
















Read >>


phpRPC Efficient Ajax remote procedure call

<p>

<img width="360" height="360" alt="" src="http://www.phprpc.org/images/architecture.gif" /> 

</p>
<p>

<br />

PHPRPC 是一个轻型的、安全的、跨网际的、跨语言的、跨平台的、跨环境的、跨域的、支持复杂对象传输的、支持引用参数传递的、支持内容输出重定向的、支持分级错误处理的、支持会话的、面向服务的高性能远程过程调用协议。
</p>
<p>

<br />

</p>
<p>

<br />

目前该协议的最新版本为 3.0。该版本目前已有以下几种语言的实现: 
</p>
<p>

<p>
    <!--more-->
</p>
<p>
    <br />
</p>



<span style="font-size:14px;">ASP:</span>提供 JScript 和 VBScript 两种语言的支持。
</p>
<p>

<strong><span style="font-size:16px;">ActionScript</span></strong>:提供 ActionScript 2.0 和 ActionScript 3.0 两个版本的支持。&nbsp;

</p>
<p>

<strong><span style="font-size:16px;">Delphi/C++Builder/Kylix</span></strong>:提供 Delphi/C++Builder 6.0-2009 和 Kylix 客户端的支持,不但可以支持 Win32 原生程序开发,而且还支持 Linux 程序开发。&nbsp;

</p>
<p>

<strong><span style="font-size:16px;">Java:支</span></strong>持 JDK 1.2 以上的所有版本,它还支持 Google Android 开发包。另外,它还有单独的 J2ME 版本,支持 CLDC-1.1 和 MIDP-1.0。

</p>
<p>

<strong><span style="font-size:16px;">JavaScript:</span></strong>提供两个版本的实现,一个使用纯 Javascript 实现,另一个需要调用一个 swf 文件,两个版本都支持跨域的远程过程调用,但是使用 swf 的版本不限制参数长度,并且有更好的安全控制机制。这两个版本已经通过完整测试的浏览器包括 IE 5+,Netscape 7+,Firefox,Mozilla,Opera,Safari,Epiphany,Camino 与 Konqueror。并且纯 JavaScript 版本还通过了 Pocket IE、Opera Mini、Opera Mobile、iPhone、Android 等手持设备浏览器的测试。

</p>
<p>

<strong><span style="font-size:16px;">.NET:</span></strong>支持 .NET 框架下所有的语言(如 C#、VB.NET、VC.NET、Delphi.NET 等),并且支持目前所有版本的 .NET Framework 和 .NET Compact Framework,当然它也支持 Mono。最新版本增加了对 SilverLight 2.0 的支持。&nbsp;

</p>
<p>

<strong><span style="font-size:16px;">PHP:</span></strong>支持 PHP4 与 PHP5,同样支持正处于开发阶段的 PHP6。&nbsp;

</p>
<p>

<strong><span style="font-size:16px;">Python:</span></strong>支持 Python 2.4、2.5、2.6,而且支持在 Google App Engine 上应用。&nbsp;

</p>
<p>

<strong><span style="font-size:16px;">Ruby:</span></strong>该版本支持 Ruby 1.8.5 及其更高版本。服务器除了支持以 cgi、fcgi、scgi、lsapi 方式运行外,还支持以独立服务器 ( mongrel、thin、ebb 或 webrick ) 方式运行。

</p>
<p>

<strong><span style="font-size:16px;">Perl:</span></strong>目前该版本尚不成熟,有待完善。

Lazarus(Free Pascal):移植自 Delphi 版本, 需要 Indy for Lazarus 支持。
其中 ASP、.NET、Java、Ruby、Python 和 PHP 版本除了提供客户端实现外,还提供了服务器端实现。
</p>
<p>

<br />

</p>
<p>

<br />

</p>
<h2>

为什么要有 PHPRPC?&nbsp;

</h2>
<p>

<br />

</p>
<p>

<br />

</p>

如果不是因为头脑发热心血来潮,那么一定是为了解决某些问题才有了 PHPRPC。 好吧,我承认是因为我受够了那些大企业所鼓吹的强大无比的 SOAP(WebService)之后才开始考虑写 PHPRPC 的。如果你也是一个需要类似于 SOAP 所鼓吹的能力,而实际上又被 SOAP 折磨的痛苦不堪却又无所适从的人的话,或许 PHPRPC 就是你的最佳选择。

<p>

<br />

</p>
<p>

<span style="font-size:16px;">简单地讲, phpPRC只做一件事情, 那就是让数据传输变得更加简单/安全/高效.</span> 

</p>
<p>

<span><span style="line-height:24px;">phpPRC与通用的Webservice SOAP构建标准是不相符合的.</span></span> 

</p>
<p>

<span><span style="line-height:24px;"><br />

</span></span>
</p>
<h2>

<span><span style="line-height:24px;">怎么用?</span></span> 

</h2>
<p>

<span><span style="line-height:24px;"><span style="color:#333333;line-height:26px;font-family:Arial;font-size:14px;background-color:#FFFFFF;">首先下载相应的语言包文件:http://phprpc.org/zh_CN/docs/ 我这里为了测试方便,下载的php版本,把压缩包解压到网站根目录。在根目录下创建两个测试文件server.php与client.php</span></span></span> 

</p>
<p>

<span><span style="line-height:24px;"> </span></span> 

</p>

<?php
include ("php/phprpc_server.php");
function HelloWorld() {
    return 'Hello World!';
}
$server = new PHPRPC_Server();
$server->add('HelloWorld');
$server->start();
?>
<?php
include ("php/phprpc_client.php");
$client = new PHPRPC_Client('http://127.0.0.1/server.php');
echo $client->HelloWorld();
?>

<h2>

<span><span style="line-height:24px;">怎么用? 之2</span></span> 

</h2>
<p>

<span><span style="line-height:24px;">服务端程序一般用的技术, 如ASP, ASP.NET, .NET, PHP, Java等, 可以用相应的支持程序包发布Server端的RPC服务.<br />

</span></span>
</p>
<p>

<span><span style="line-height:24px;">客户端, 可用javascript, ActionScript(Flex应用), ASP, PHP等.</span></span> 

</p>
<p>

<span><span style="line-height:24px;"><br />

</span></span>
</p>
<p>

<span><span style="line-height:24px;">总之, 很方便. 解决了我的ASP.NET程序迁移的问题, 再也不用操心windows主机了, 可以拥抱服务众多的Linux主机.</span></span> 

</p>
<p>

<br />

</p>
<p>

<br />

</p>
<p>

项目主页:&nbsp;<a href="http://www.phprpc.org/" target="_blank">http://www.phprpc.org/</a> 

</p>









































Read >>


电流输出与电压输出型传感器的区别

<span style="line-height:28px;font-family:Simsun;font-size:14px;background-color:#F8FCFD;"> </span><u>传感器</u><span style="line-height:28px;font-family:Simsun;font-size:14px;background-color:#F8FCFD;">输出有很多形式,但是大多是电流输出和电压输出,有些客户在选择传感器的时候不知道应该选择电路输出还是电压输出,下面我们就来说说这两种输出的区别,下面我们以</span><u>压力传感器</u><span style="line-height:28px;font-family:Simsun;font-size:14px;background-color:#F8FCFD;">为例进行说明。</span>
<p>

<!--more-->

</p>
<p>

<br />

</p>


<span style="line-height:28px;font-family:Simsun;font-size:14px;background-color:#F8FCFD;">    压力传感器是应用最多的一款传感器之一,电流输出和电压输出的压力传感器都非常常见,这两种输出主要有下面几个区别,首先,早期的变送器大多为电压输出型,即将测量信号转换为0-5V电压输出,这是运放直接输出,信号功率<0.05W,通过模拟/数字转换电路转换数字信号供</span><u>单片机</u><span style="line-height:28px;font-family:Simsun;font-size:14px;background-color:#F8FCFD;">读取、控制。其次,在信号需要远距离传输或使用环境中电网干扰较大的场合,电压输出型传感器的使用受到了极大限制,暴露了抗干扰能力较差,线路损耗破坏了精度等等等缺点,而两线制电流输出型变送器以其具有极高的抗干扰能力得到了广泛应用。最后,电压输出型变送器抗干扰能力极差,线路损耗的破坏,谈不上精度有多高,有时输出的直流电压上还叠加有交流成分,使单片机产生误判断,控制出现错误,严重时还会损坏设备,输出0-5V绝对不能远传,远传后线路压降大,精确度大打折扣。</span>

<span style="line-height:28px;font-family:Simsun;font-size:14px;background-color:#F8FCFD;">    电流输出、电压输出的传感器都是非常常见的,但是就目前发展趋势来看,电压输出正在逐渐淘汰,现在数字输出的传感器也正在被客户接收,数字输出的传感器信号容易处理,便于集成,未来更多的传感器将会选择数字输出的。</span>






Read >>


旧题重弹:判断点位于多边形内部算法

<p style="color:#4B4B4B;font-family:verdana, Arial, helvetica, sans-seriff;">

<strong>1. 叉乘判别法(只适用于凸多边形)<br />



想象一个凸多边形,其每一个边都将整个2D屏幕划分成为左右两边,连接每一边的第一个端点和要测试的点得到一个矢量v,将两个2维矢量扩展成3维的,然后将该边与v叉乘,判断结果3维矢量中Z分量的符号是否发生变化,进而推导出点是否处于凸多边形内外。这里要注意的是,多边形顶点究竟是左手序还是右手序,这对具体判断方式有影响。



2. 面积判别法(只适用于凸多边形)



第四点分别与三角形的两个点组成的面积分别设为S1,S2,S3,只要S1+S2+S3>原来的三角形面积就不在三角形范围中.可以使用海伦公式 。

<p>
    <!--more-->
</p>
<p>
    <br />
</p>



3. 角度和判别法(适用于任意多边形)

<span style="color:#4B4B4B;font-family:verdana, Arial, helvetica, sans-seriff;font-size:14px;line-height:20px;background-color:#FFFFFF;">该点与没对相邻顶点的夹角之和为360,则在内,否则在外</span>
</p>
<p style="color:#4B4B4B;font-family:verdana, Arial, helvetica, sans-seriff;">

<br />

4. 水平/垂直交叉点数判别法(适用于任意多边形)


</p>
<p style="color:#4B4B4B;font-family:verdana, Arial, helvetica, sans-seriff;">

<span style="color:#333333;font-family:Simsun;font-size:medium;line-height:1.5;">以点P为端点,向左方作射线L,由于多边形是有界的,所以射线L的左端一定在多边形外,考虑沿着L从无穷远处开始自左向右移动,遇到和多边形的第一个交点的时候,进入到了多边形的内部,遇到第二个交点的时候,离开了多边形,……所以很容易看出当L和多边形的交点数目C是奇数的时候,P在多边形内,是偶数的话P在多边形外。</span> 

</p>
<p align="left" style="color:#FFFFFF;font-family:Simsun;font-size:medium;">

<span><span> </span></span><span><span> </span><span style="color:#333333;">但是有些特殊情况要加以考虑。如图下图(a)(b)(c)(d)所示。在图(a)中,L和多边形的顶点相交,这时候交点只能计算一个;在图(b)中,L和多边形顶点的交点不应被计算;在图(c)和(d) 中,L和多边形的一条边重合,这条边应该被忽略不计。如果L和多边形的一条边重合,这条边应该被忽略不计。</span></span> 

</p>
<p align="left" style="color:#FFFFFF;font-family:Simsun;font-size:medium;">

<span><span style="color:#333333;">&nbsp;&nbsp;&nbsp;&nbsp;</span><img src="http://dev.gameres.com/Program/Abstract/Geometry_3.gif" width="300" height="600" /></span> 

</p>
<p align="left" style="color:#FFFFFF;font-family:Simsun;font-size:medium;">

<span><span> </span></span><span><span> </span><span style="color:#333333;">为了统一起见,我们在计算射线L和多边形的交点的时候,1。对于多边形的水平边不作考虑;2。对于多边形的顶点和L相交的情况,如果该顶点是其所属的边上纵坐标较大的顶点,则计数,否则忽略;3。对于P在多边形边上的情形,直接可判断P属于多边行。由此得出算法的伪代码如下:</span><br />

</span><span><span style="color:#333333;">    count ← 0;</span>

<span style="color:#333333;">     以P为端点,作从右向左的射线L; </span>

<span style="color:#333333;">     for 多边形的每条边s</span>

<span style="color:#333333;">      do if P在边s上 </span>

<span style="color:#333333;">           then return true;</span>

<span style="color:#333333;">         if s不是水平的</span>

<span style="color:#333333;">           then if s的一个端点在L上</span>

<span style="color:#333333;">                  if 该端点是s两端点中纵坐标较大的端点</span>

<span style="color:#333333;">                    then count ← count+1</span>

<span style="color:#333333;">                else if s和L相交</span>

<span style="color:#333333;">                  then count ← count+1;</span>

<span style="color:#333333;">     if count mod 2 = 1 </span>

<span style="color:#333333;">       then return true;</span>

<span style="color:#333333;">     else return false;</span></span><span>



<span> </span><span style="color:#333333;">其中做射线L的方法是:设P'的纵坐标和P相同,横坐标为正无穷大(很大的一个正数),则P和P'就确定了射线L。</span></span>
</p>
<p align="left" style="color:#FFFFFF;font-family:Simsun;font-size:medium;">

<span><span> </span></span><span><span> </span><span style="color:#333333;">判断点是否在多边形中的这个算法的时间复杂度为O(n)。</span></span> 

</p>
<p>

<br />

</p>
<p style="color:#4B4B4B;font-family:verdana, Arial, helvetica, sans-seriff;">

<br />

</p>



































Read >>


C#中使用指针总结

<p style="color:#333333;font-family:verdana, Arial, Helvetica, sans-serif;font-size:14px;background-color:#FFFFFF;">

C#为了类型安全,默认并不支持指针。但是也并不是说C#不支持指针,我们可以使用unsafe关键词,开启不安全代码(unsafe code)开发模式。在不安全模式下,我们可以直接操作内存,这样就可以使用指针了。在不安全模式下,CLR并不检测unsafe代码的安全,而是直接执行代码。unsafe代码的安全需要开发人员自行检测。

Read >>