<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_青春都一饷，忍把浮名，换了代码轻狂。</title><subtitle type="text">关注DirectX</subtitle><id>http://feed.cnblogs.com/blog/u/56021/rss</id><updated>2012-05-26T13:39:49Z</updated><author><name>zdd</name><uri>http://www.cnblogs.com/graphics/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/graphics/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/56021/rss"/><entry><id>http://www.cnblogs.com/graphics/archive/2012/05/07/2039569.html</id><title type="text">DirectX怪象之二， 程序很吃CPU</title><summary type="text">学习DirectX编程的兄弟们可能经常遇到的一个情况是，程序经常莫名奇妙的占用大量的CPU资源，其实吃CPU的问题并不是DirectX程序所特有的，几乎任何程序都可能，只不过DirectX程序更加容易产生而已，总结了一下，主要有以下几个方面没有及时释放资源这种情况的现象多发生在程序运行的时候，也就是窗口处于active状态时，大家都知道，DX是基于COM的，这也就意味着，你需要手动释放COM对象，如果没有及时释放的话，CPU就会吃紧，尤其是当在Render函数中创建对象的时候更是如此。至于哪些需要释放，哪些不需要释放，需要视具体情况而定，这里有一个简单的方法，如果创建该对象的函数形如Creat</summary><published>2012-05-07T01:10:00Z</published><updated>2012-05-07T01:10:00Z</updated><author><name>zdd</name><uri>http://www.cnblogs.com/graphics/</uri></author><link rel="alternate" href="http://www.cnblogs.com/graphics/archive/2012/05/07/2039569.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/graphics/archive/2012/05/07/2039569.html"/><content type="html">&lt;p&gt;学习DirectX编程的兄弟们可能经常遇到的一个情况是，程序经常莫名奇妙的占用大量的CPU资源，其实吃CPU的问题并不是DirectX程序所特有的，几乎任何程序都可能，只不过DirectX程序更加容易产生而已，总结了一下，主要有以下几个方面&lt;/p&gt;&lt;p&gt;&lt;strong&gt;没有及时释放资源&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这种情况的现象多发生在程序运行的时候，也就是窗口处于active状态时，大家都知道，DX是基于COM的，这也就意味着，你需要手动释放COM对象，如果没有及时释放的话，CPU就会吃紧，尤其是当在Render函数中创建对象的时候更是如此。至于哪些需要释放，哪些不需要释放，需要视具体情况而定，这里有一个简单的方法，如果创建该对象的函数形如CreateXXX，那么基本都需要释放，这种对象一般都有一个Release方法，直接调用这个方法即可。给大家分享一个宏定义，来自于DX SDK，这个宏可以很方便的释放COM对象&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;#define&lt;/span&gt;&lt;span style="color: #000000;"&gt; SAFE_RELEASE(P) if(P){ P-&amp;gt;Release(); P = NULL;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;我们在编程时应该遵循一些好的编程习惯，这样就会避免错误发生，比如&lt;/p&gt;&lt;p&gt;1 对于那些只需要一次创建的对象，通通放到Render函数之外，所以我们通常设置一个函数名叫InitD3D，可以把一次性初始化的代码都放到这里。切记不可把非渲染操作放到Render函数里面，因为Render函数就是用来做渲染的，而且调用频率极高，几乎是时时刻刻都在调用，如果把其他操作资源的过程也放到这里，势必会影响效率。&lt;/p&gt;&lt;p&gt;2 在开发的时候尽量使用Debug版本的库，这样可以及时发现资源泄露。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;没有处理窗口inactive的情况&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这种情况多发生在窗口处于inactive状态时，比如被遮挡或者最小化到任务栏。先看一段Windows下的渲染框架，下面的代码逻辑很简单，有消息则处理消息，无消息则渲染，如果你使用了这段代码，那么你可以试着将窗口最小化，你将会看到CPU使用率上升一大截，为什么呢？这是由于PeekMessage的机制造成的，说到PeekMessage就不得不说GetMessage，这二者都是用于从消息队列中取得消息，不同的是，PeekMessage如果没取到消息，会立即返回0，而GetMessage如果没取到消息，则会一直等待有消息可取。也就是说PeekMessage是异步的，而GetMessage是同步的。下面的代码就是利用没有消息处理的时间进行渲染，而当窗口最小化时，PeekMessage一直取不到消息，所以程序一直在渲染，这样就占用了大量的CPU时间。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #000000;"&gt;MSG msg ;&lt;br/&gt;ZeroMemory( &lt;/span&gt;&amp;amp;msg, &lt;span style="color: #0000ff;"&gt;sizeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(msg) );&lt;br/&gt;PeekMessage( &lt;/span&gt;&amp;amp;msg, NULL, &lt;span style="color: #800080;"&gt;0U&lt;/span&gt;, &lt;span style="color: #800080;"&gt;0U&lt;/span&gt;&lt;span style="color: #000000;"&gt;, PM_NOREMOVE );&lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Get latest time&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; DWORD lastTime =&lt;span style="color: #000000;"&gt; timeGetTime();&lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt; (msg.message !=&lt;span style="color: #000000;"&gt; WM_QUIT)&lt;br/&gt;{&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;( PeekMessage(&amp;amp;msg, NULL, &lt;span style="color: #800080;"&gt;0U&lt;/span&gt;, &lt;span style="color: #800080;"&gt;0U&lt;/span&gt;, PM_REMOVE) !=&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br/&gt;    {&lt;br/&gt;        TranslateMessage (&lt;/span&gt;&amp;amp;&lt;span style="color: #000000;"&gt;msg) ;&lt;br/&gt;        DispatchMessage (&lt;/span&gt;&amp;amp;&lt;span style="color: #000000;"&gt;msg) ;&lt;br/&gt;    }&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Render the scene if there is no message to handle&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #000000;"&gt;    {&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Get current time&lt;/span&gt;&lt;br/&gt;        DWORD currTime =&lt;span style="color: #000000;"&gt; timeGetTime();&lt;br/&gt;&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Calculate time elapsed&lt;/span&gt;&lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;float&lt;/span&gt; timeDelta = (currTime - lastTime) *&lt;span style="color: #800080;"&gt;0.001f&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Render&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #000000;"&gt;        Render(timeDelta) ;&lt;br/&gt;&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Update lastTime&lt;/span&gt;&lt;br/&gt;        lastTime =&lt;span style="color: #000000;"&gt; currTime;&lt;br/&gt;    }&lt;br/&gt;}&lt;/span&gt;&lt;/div&gt;&lt;p&gt;有了上面的分析，我们可以分两种情况来处理，一是程序处于active状态时，我们按照上面的方法渲染。二是程序处于inactive状态时，我们可以使用GetMessage来等待一个消息，因为此时程序不需要渲染（已经最小化了，还渲染啥呀？）。对应的代码如下&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #000000;"&gt;BOOL bGotMsg;&lt;br/&gt;MSG msg;&lt;br/&gt;PeekMessage( &lt;/span&gt;&amp;amp;msg, NULL, &lt;span style="color: #800080;"&gt;0U&lt;/span&gt;, &lt;span style="color: #800080;"&gt;0U&lt;/span&gt;&lt;span style="color: #000000;"&gt;, PM_NOREMOVE );&lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;( WM_QUIT !=&lt;span style="color: #000000;"&gt; msg.message )&lt;br/&gt;{&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Use PeekMessage() if the app is active, so we can use idle time to&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; render the scene. Else, use GetMessage() to avoid eating CPU time.&lt;/span&gt;&lt;br/&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;( m_bActive )&lt;br/&gt;        bGotMsg &lt;/span&gt;= PeekMessage( &amp;amp;msg, NULL, &lt;span style="color: #800080;"&gt;0U&lt;/span&gt;, &lt;span style="color: #800080;"&gt;0U&lt;/span&gt;&lt;span style="color: #000000;"&gt;, PM_REMOVE );&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br/&gt;        bGotMsg &lt;/span&gt;= GetMessage( &amp;amp;msg, NULL, &lt;span style="color: #800080;"&gt;0U&lt;/span&gt;, &lt;span style="color: #800080;"&gt;0U&lt;/span&gt;&lt;span style="color: #000000;"&gt; );&lt;br/&gt;&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;( bGotMsg )&lt;br/&gt;    {&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Translate and dispatch the message&lt;/span&gt;&lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;( &lt;span style="color: #800080;"&gt;0&lt;/span&gt;== TranslateAccelerator( m_hWnd, hAccel, &amp;amp;&lt;span style="color: #000000;"&gt;msg ) )&lt;br/&gt;        {&lt;br/&gt;            TranslateMessage( &lt;/span&gt;&amp;amp;&lt;span style="color: #000000;"&gt;msg );&lt;br/&gt;            DispatchMessage( &lt;/span&gt;&amp;amp;&lt;span style="color: #000000;"&gt;msg );&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br/&gt;    {&lt;br/&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Render a frame during idle time (no messages are waiting)&lt;/span&gt;&lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;( m_bActive )&lt;br/&gt;        {&lt;br/&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;( FAILED( Render3DEnvironment() ) )&lt;br/&gt;                SendMessage( m_hWnd, WM_CLOSE, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; );&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;/span&gt;&lt;/div&gt;&lt;p&gt;下面的问题就是如何处理&lt;span style="color: #000000;"&gt;m_bActive这个变量了，可以响应WM_SIZE消息，SIZE_MAXHIDE表示有其他窗口最大化了，这样就意味着本窗口被完全遮挡了，SIZE_MINIMIZED表示窗口最小化了。这两种情况我们将窗口视为inactive状态。&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; WM_SIZE:&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Check to see if we are losing our window...&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;( SIZE_MAXHIDE&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;wParam &lt;/span&gt;&lt;span style="color: #000000;"&gt;||&lt;/span&gt;&lt;span style="color: #000000;"&gt; SIZE_MINIMIZED&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;wParam )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        m_bActive &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; FALSE;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        m_bActive &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; TRUE;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;没有做场景管理&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;由于我对场景管理不是很熟练，所以只能简单说说，&lt;span style="color: #000000;"&gt;场景管理应该属于中高层次的技术，在刚学DirectX的时候，根本不会考虑这些，但是随着知识的深入，程序代码的增大，逻辑越来越复杂，模型越来越多，难免会涉及到场景管理，什么是场景管理呢，如果从渲染的角度来讲，就是区分哪些应该渲染，哪些不用渲染，就是说要提高渲染的速度，场景管理中最基本的就是Frustum剪裁，四叉树，BSP场景管理，八叉树等。&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;Frustum，中文翻译成视锥，视锥剪裁是最基本的场景管理，也就是只渲染在视野内的模型，其他的一律剪裁掉。&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;四叉树多用于地形渲染&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;BSP多用于室内场景管理，著名的Quake系列使用的就是BSP树&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;八叉树比较通用&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;如果你的场景中有大量的模型，而又没有做场景管理，也就意味着，一次性将所有的模型都渲染一遍，不管模型是否在视野里，这势必很浪费CPU资源。&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;当然，肯定还有许多其他的原因，欢迎大家补充！&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/64257/2012050710000638.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/graphics/aggbug/2039569.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/graphics/archive/2012/05/07/2039569.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/graphics/archive/2012/05/02/2052571.html</id><title type="text">DirectX怪像之一，我的模型不见了</title><summary type="text">引言对于刚刚编写DirectX程序的朋友来说，经常遇到的一个问题就是，风风火火写了一大堆代码，编译-运行！哇塞，窗口里黑乎乎一片，啥也没有，或者是之前运行好好的程序，不只修改了哪里，导致以前渲染的画面现在都没有了。我在学习的过程中也经常遇到这种问题，索性总结下来，与大家分享。希望能给刚入门的兄弟们一个提醒。场景为何消失？根据我自己的经验，如果渲染场景中某些东西不见了，一般有以下几个主要的原因光照设置不正确很简单，在一个伸手不见五指的黑夜里，你能指望看见什么呢？光照是D3D中必不可少的东西，用来计算顶点的最终颜色。但是并不是所有的顶点格式都需要光照，有些定点格式，如果设置了光照反而会导致模型无法</summary><published>2012-05-02T00:49:00Z</published><updated>2012-05-02T00:49:00Z</updated><author><name>zdd</name><uri>http://www.cnblogs.com/graphics/</uri></author><link rel="alternate" href="http://www.cnblogs.com/graphics/archive/2012/05/02/2052571.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/graphics/archive/2012/05/02/2052571.html"/><content type="html">&lt;p&gt;&lt;strong&gt;引言&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;对于刚刚编写DirectX程序的朋友来说，经常遇到的一个问题就是，风风火火写了一大堆代码，编译-运行！哇塞，窗口里黑乎乎一片，啥也没有，或者是之前运行好好的程序，不只修改了哪里，导致以前渲染的画面现在都没有了。我在学习的过程中也经常遇到这种问题，索性总结下来，与大家分享。希望能给刚入门的兄弟们一个提醒。&lt;/p&gt;&lt;p&gt;场景为何消失？&lt;/p&gt;&lt;p&gt;根据我自己的经验，如果渲染场景中某些东西不见了，一般有以下几个主要的原因&lt;/p&gt;&lt;p&gt;&lt;strong&gt;光照设置不正确&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;很简单，在一个伸手不见五指的黑夜里，你能指望看见什么呢？光照是D3D中必不可少的东西，用来计算顶点的最终颜色。但是并不是所有的顶点格式都需要光照，有些定点格式，如果设置了光照反而会导致模型无法显示，比如LT（Lit and Transformed）格式。我们来看看D3D中的光照原理。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;如果将光照设置为enable（通过D3DRS_LIGHTING=TRUE设置），那么系统会对所有法向量不为0的顶点进行光照计算，即使输入的顶点中包含颜色信息，也将被丢弃。&lt;/li&gt;&lt;li&gt;如果将光照设置为disable，那么对于LT格式，将使用顶点自带的颜色信息，而对于其他类型的顶点，将没有光照计算，也就无法显示。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;所以如果顶点是LT格式的，而且设置了光照为enable，那么模型也是无法显示的，因为LT格式的顶点不包含法向量，没有法向量是无法完成光照计算的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;视图矩阵设置不正确&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这个也很简单，在一个阳光明媚的日子，一位绝色美女站在你旁边，可是你却背对着她！如何欣赏到她的美呢？有了光照，有了场景，可是如果场景不在你的视野内，你依然什么都看不见，比如模型绘制在X轴正半轴上，而视线却指向X轴负半轴。所以，正确的设置视图矩阵也是看见场景的重要因素。DirectX使用左手系，Z轴指向屏幕内部的方向为正，一般来说模型都绘制在坐标系的原点，而观察点也设置为原点，眼睛的位置只要设置成Z轴负半轴上的某个位置就可以了。下面就是一个典型的设置代码&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;D3DXVECTOR3 lookCenter(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;) ;&lt;br /&gt;D3DXVECTOR3 upVec(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;) ;&lt;br /&gt;D3DXVECTOR3 eyePt(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;20.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;) ;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;剔除方式不正确&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;D3D默认的剔除方式是逆时针，也就是CULL_CCW，如果你的顶点是按照逆时针顺序定义的，而且使用了默认的剔除方式，那么肯定什么都看不见。所以一定要&lt;span style="color: #ff0000;"&gt;确保顶点定义的顺序和剔除顺序是相反的&lt;/span&gt;，也就是说，如果程序中定义了顺时针剔除，那么你的顶点就应该保持逆时针顺序。在D3D中可以指定如下三种剪裁方式：&lt;/p&gt;&lt;p&gt;D3DCULL_CW顺时针&lt;/p&gt;&lt;p&gt;D3DCULL_CCW　 逆时针&lt;/p&gt;&lt;p&gt;D3DCULL_NONE&amp;nbsp;&amp;nbsp; 不剪裁&lt;/p&gt;&lt;p&gt;&lt;strong&gt;如何诊断剪裁问题？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;如果你怀疑程序可能是由于剪裁导致了错误，那么可以将剪裁方式指定为D3DCULL_NONE，并按照下面步骤诊断。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;问题不存在了，这说明是剔除方式不对，可以分别试试D3DCULL_CW和D3DCULL_CCW这两种方式。&lt;/li&gt;&lt;li&gt;问题依旧，这说明不是剔除的问题，因为D3DCULL_NONE不进行任何剔除操作，所有的面都该显示。应该是其他原因引起的。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;转换矩阵设置不正确&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;比如不小心将模型平移到了视野之外。&lt;/p&gt;&lt;p&gt;每个模型要单独设置world matrix&lt;/p&gt;&lt;p&gt;&lt;strong&gt;没有绘制内容&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这个原因听起来很滑稽，不过不可否认的是，我曾多次犯了这个错误，程序中没有绘制任何东西！其实这个问题的原因往往是修改代码造成的，一开始程序的行为是正确的，但是后来为了修改某些功能为Render函数就行修改，可能会无意间注释掉某些内容，如果将绘制的代码注释掉，那肯定就什么也看不见了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;当然，看不见模型的原因远不止这些，本文只是抛砖引玉，欢迎大家补充指正！&lt;/p&gt;&lt;img src="http://www.cnblogs.com/graphics/aggbug/2052571.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/graphics/archive/2012/05/02/2052571.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/graphics/archive/2012/04/03/2117798.html</id><title type="text">DirectX截图黑屏的解决办法</title><summary type="text">好久没有更新博客了，今天开始继续耕耘。生活要继续工作要继续梦想也一定要继续！之前写过一篇关于DirectX截屏的文章，其中有网友留言提到了截图黑屏的问题，于是这些日子研究了一下，与大家一同分享。为什么会黑屏？一句话概括，黑屏是由于DDraw加速引起的！先说一下DirectX的显示原理，通常我们看到的屏幕上的数据，都是通过Primary Surface送至显示器的，常用的截屏函数也基本上是通过截取Primary Surface中的数据来实现的。现在多数的视频播放软件都是用DDraw写的（现在DDraw已经融合到DirectX的Graphics本分，DDraw这个词也已经成为历史了。），而且使用了</summary><published>2012-04-03T00:38:00Z</published><updated>2012-04-03T00:38:00Z</updated><author><name>zdd</name><uri>http://www.cnblogs.com/graphics/</uri></author><link rel="alternate" href="http://www.cnblogs.com/graphics/archive/2012/04/03/2117798.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/graphics/archive/2012/04/03/2117798.html"/><content type="html">&lt;p&gt;好久没有更新博客了，今天开始继续耕耘。&lt;/p&gt;&lt;p&gt;生活要继续&lt;/p&gt;&lt;p&gt;工作要继续&lt;/p&gt;&lt;p&gt;梦想也一定要继续！&lt;/p&gt;&lt;p&gt;之前写过一篇关于&lt;a href="http://www.cnblogs.com/graphics/archive/2009/11/25/1610914.html"&gt;DirectX截屏&lt;/a&gt;的文章，其中有网友留言提到了截图黑屏的问题，于是这些日子研究了一下，与大家一同分享。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;为什么会黑屏？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;一句话概括，黑屏是由于DDraw加速引起的！&lt;/p&gt;&lt;p&gt;先说一下DirectX的显示原理，通常我们看到的屏幕上的数据，都是通过Primary Surface送至显示器的，常用的截屏函数也基本上是通过截取Primary Surface中的数据来实现的。现在多数的视频播放软件都是用DDraw写的（现在DDraw已经融合到DirectX的Graphics本分，DDraw这个词也已经成为历史了。），而且使用了一种叫做Overlay的表面，我们常用的截屏函数都是截取普通的primary surface中的数据，无法截取Overlay surface中的数据，而微软又没有提供公共的API来获取Overlay surface中的数据，所以，黑屏就不足为奇了。下面就是使用了Overlay技术的Windows Media Player截图时的黑屏现象。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/64257/2012040221560168.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;Overlay是纯硬件支持的，DDraw并不会用软件实现这种功能。这种Surface的特殊之处在于，它相当于蒙在屏幕上的一块塑料板，也就是说，这个如果使用了这种Surface，那么它就位于所有surface的最前端。显示设备在向屏幕显示数据的时候，会先判断该位置是否有Overlay，如果有，就显示Overlay中像素，如果没有，就使用Primary Surface中的像素。所以，当你打开一个播放器来播放视频，截图的时候就会发现播放器窗口是黑的。原因就是这块区域正好对应着Overlay。当然是截取不到的。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/64257/2012040121575487.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;关于Overlay surfaces的详细介绍，可以看&lt;a href="http://msdn.microsoft.com/en-us/library/aa916217.aspx"&gt;这里&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;如何避免截图时黑屏&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;大多数软件除了DDraw的渲染模式之外，还提供了一种Software renderer模式，也就是软件模式，这种模式在DDraw加速不可用的时候才会使用，所以一个避免截图黑屏的办法就是关闭DDraw加速，强迫软件使用Software renderer模式，这样，Overlay surface就不存在了，也就不会黑屏了。具体办法如下&lt;/p&gt;&lt;p&gt;方法一： 使用软件本身的设置来禁用Overlay技术，该方法只会影响该软件本身，以常见的Windows Media Player为例，设置如下（将 使用覆盖这个选项勾掉，这样软件就不会使用Overlay Surface了）&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/64257/2012032721140241.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;方法二： 使用DirectX控制面板来关闭DDraw加速，上面的方法相当于关闭分支开关，而这个方法则相当于把总闸给关闭了，系统中所有其他软件也不能使用DDraw加速了。如果安装了DirectX SDK，那么直接在运行栏里面输入dxdiag即可打开DirectX控制面板，设置如下。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/64257/2012032721244143.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;方法三：其实还有一种办法，就是用程序占用Overlay surface，这种办法太麻烦，一般人不会用，因为一般的独立显卡都支持Overlay Surface，而且支持的个数是有限的，所以，如果我们提前用程序占用了所有的Overlay Surface，那么其他程序就无法再使用了，也就不会导致截图黑屏了。在使用这种方法前，应该首先查看自己的显卡是否支持Overlay技术，以及支持多少个。如果安装了DirectX SDK，可以依次展开：开始-程序-Microsoft DirectX SDK-DirectX Utilities-DirectX Caps Viewer，由下图可知，我的显卡支持一个Overlay Surface，我还没玩过高级显卡，没见过支持多个Overlay的显卡，哪位兄弟有好的显卡，也发个图让小弟看看。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/64257/2012032721513316.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;但是这种方法有一个弊端，就是如果软件不支持Software Renderer模式，那么如果你先用程序占用了Overlay，再启动播放软件的时候，就会导致错误。&lt;/p&gt;&lt;p&gt;以上几种办法究其本质，实际上就是一种，都是禁止使用Overlay Surface。而且这些方法都有一个弊端，就是要求先入为主，也就是在软件启动前（或者确切的说，是视频播放前）做好设置，然后再启动软件。如果视频已经播放（Overlay已经被占用），那么这些方法将会统统失效。&lt;/p&gt;&lt;p&gt;除此之外，还可以使用现成的截图软件，很多软件都可以处理黑屏的情况，比如HyperSnap 6就很不错。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;如何截取Overlay中的数据？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;说来这不是一个简单的问题，我在网上搜索了很久，也没找到合适的办法，据说使用Hook技术可能会办到，但是我对hook不太熟悉，所以也没尝试，希望哪位朋友有兴趣可以试试，关于这个话题，google讨论组上有个帖子，介绍的比较详细，感兴趣的可以看看&lt;a href="http://groups.google.com/group/microsoft.public.win32.programmer.directx.video/browse_thread/thread/21e81ba7044feb7e"&gt;这里&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;挑战一下！&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;我这里有一个关于Overlay Surface的Demo（&lt;a href="http://files.cnblogs.com/graphics/Mosquito.zip"&gt;下载&lt;/a&gt;）。这个Demo来自DirectX 7的SDK，是一只飞动的小蚊子。由于版本较老，现在网上已经不太常见了。根据上面的研究可以断定，能截取到这只小蚊子绝非易事，感兴趣的朋友不妨试试！&lt;/p&gt;&lt;img src="http://www.cnblogs.com/graphics/aggbug/2117798.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/graphics/archive/2012/04/03/2117798.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/graphics/archive/2011/09/15/2176635.html</id><title type="text">也谈走台阶问题</title><summary type="text">问题刚才在首页看到一篇博客，说的是腾讯的一道面试题：一个楼梯有50个台阶，每一步可以走一个台阶，也可以走两个台阶，请问走完这个楼梯共有多少种方法？博主把这题分析的很麻烦。引来很多人围观。我以前也碰到过这个问题。写出来和大家分享一下。举个例子，假设有3个台阶，则有三种走法：分别是，1-1-1, 1-2, 2-1。分析很简单的一道题，学过组合数学的人很快就能想到，这是一个递推关系。假设走完k个台阶有f(k)种走法。k = 1时，f(k) = 1k = 2时，f(k) = 2k = n时，第一步走一个台阶，剩n-1个台阶，有f(n - 1)种走法。第一步走两个台阶，剩n-2个台阶，有f(n - 2)</summary><published>2011-09-15T06:23:00Z</published><updated>2011-09-15T06:23:00Z</updated><author><name>zdd</name><uri>http://www.cnblogs.com/graphics/</uri></author><link rel="alternate" href="http://www.cnblogs.com/graphics/archive/2011/09/15/2176635.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/graphics/archive/2011/09/15/2176635.html"/><content type="html">&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;刚才在首页看到一篇&lt;a href="http://www.cnblogs.com/flowerszhong/archive/2011/09/14/2176374.html"&gt;博客&lt;/a&gt;，说的是腾讯的一道面试题：一个楼梯有50个台阶，每一步可以走一个台阶，也可以走两个台阶，请问走完这个楼梯共有多少种方法？博主把这题分析的很麻烦。引来很多人围观。我以前也碰到过这个问题。写出来和大家分享一下。&lt;/p&gt;&lt;p&gt;举个例子，假设有3个台阶，则有三种走法：分别是，1-1-1, 1-2, 2-1。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;分析&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;很简单的一道题，学过组合数学的人很快就能想到，这是一个递推关系。假设走完k个台阶有f(k)种走法。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;k = 1时，f(k) = 1&lt;/li&gt;&lt;li&gt;k = 2时，f(k) = 2&lt;/li&gt;&lt;li&gt;k = n时，第一步走一个台阶，剩n-1个台阶，有f(n - 1)种走法。第一步走两个台阶，剩n-2个台阶，有f(n - 2)种走法。所以共有f(n - 1) + f(n - 2)种走法。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;于是有如下公式&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011091513375412.png" alt="" height="111" width="276" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;代码&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; count(unsigned &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; n)&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(n &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; ;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(n &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt; ;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; count(n &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; count(n &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;) ;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;具体是怎么走的呢？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;上面只给出了有多少种走法，那么具体每一种走法是怎么走的呢？比如n=4时，五种走法分别如下：&lt;/p&gt;&lt;p&gt;1,1,1,1&lt;/p&gt;&lt;p&gt;1,1,2&lt;/p&gt;&lt;p&gt;1,2,1&lt;/p&gt;&lt;p&gt;2,1,1&lt;/p&gt;&lt;p&gt;2,2&lt;/p&gt;&lt;p&gt;我们用一个整型数组来存放每一步的内容，1表示这步走了一个台阶，2表示这步走了两个台阶。回溯法搞定。代码如下。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; count(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; n, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; t)&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(n &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; ;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (n &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;        Output(step, t) ;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;i)&lt;br /&gt;        {&lt;br /&gt;            step[t] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; i ;&lt;br /&gt;            count(n &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; i, t &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;) ;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;类似的问题&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;与此题类似的问题有很多，比如铺地砖问题，自然数拆分等。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;铺地砖问题&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;有一个长度为n,宽度为2的地面，有若干块长为2,宽为1的地砖，请问用此地砖铺完这个地面共有多少种方法？&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011091513585158.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011091513594658.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;分析一下，假设铺完长度为n的地面有f(n)种方法，如果第一块地砖竖起来铺，还剩下长度为n-1的地面，有f(n-1)种方法。如下图。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011091514130894.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;如果第一块地转横着铺，那么还剩下长度为n-2的地面，有f(n-2)种铺法。如下图。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011091514131737.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;所以这道题与上面的题解法完全一样。不同的题目，相同的模型而已。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;自然数拆分&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;给定一个自然数n，将其拆分为若干个自然数字之和，请问有多少种方法？举个例子，n=4时，可以拆分为1-1-1-1，1-1-2，1-3，2-2。&lt;/p&gt;&lt;p&gt;这题和上面的题很像，不过上面的问题是排列问题，而这题是组合问题，比如n=4时，1-1-2，1-2-1，2-1-1这三种只能算一个拆分。在上面的基础上，去掉重复的组合即可。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/graphics/aggbug/2176635.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/graphics/archive/2011/09/15/2176635.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/graphics/archive/2011/07/14/2105195.html</id><title type="text">数组面试题-子数组之和</title><summary type="text">昨天在一位老兄的凡客面试题中看到的，拿来写一下。题目描述给定一个含有n个元素的整形数组a，再给定一个和sum，求出数组中满足给定和的所有元素组合，举个例子，设有数组a[6] = { 1, 2, 3, 4, 5, 6 }，sum = 10，则满足和为10的所有组合是{1, 2, 3, 4}{1, 3, 6}{1, 4, 5}{2, 3, 5}{4, 6}注意，这是个n选m的问题，并不是两两组合问题。解法一：穷举法最直观的想法就是穷举，把数组中元素的所有组合情况都找出来，然后看看哪些组合满足给定的和即可，这种方法的计算量非常大，是指数级的，假设数组有n个元素，那么所有组合的情况一共有2 ^ n种（</summary><published>2011-07-14T09:24:00Z</published><updated>2011-07-14T09:24:00Z</updated><author><name>zdd</name><uri>http://www.cnblogs.com/graphics/</uri></author><link rel="alternate" href="http://www.cnblogs.com/graphics/archive/2011/07/14/2105195.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/graphics/archive/2011/07/14/2105195.html"/><content type="html">&lt;p&gt;昨天在一位老兄的凡客面试题中看到的，拿来写一下。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;题目描述&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;给定一个含有n个元素的整形数组a，再给定一个和sum，求出数组中满足给定和的所有元素组合，举个例子，设有数组a[6] = { 1, 2, 3, 4, 5, 6 }，sum = 10，则满足和为10的所有组合是&lt;/p&gt;&lt;p&gt;{1, 2, 3, 4}&lt;br /&gt;{1, 3, 6}&lt;br /&gt;{1, 4, 5}&lt;br /&gt;{2, 3, 5}&lt;br /&gt;{4, 6}&lt;/p&gt;&lt;p&gt;注意，这是个n选m的问题，并不是两两组合问题。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;解法一：穷举法&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;最直观的想法就是穷举，把数组中元素的所有组合情况都找出来，然后看看哪些组合满足给定的和即可，这种方法的计算量非常大，是指数级的，假设数组有n个元素，那么所有组合的情况一共有2 ^ n种（包括空集），如果n很大的话，这个方法将会非常慢。那么如何找出所有这些组合呢？其实对于任意一个组合来讲，数组a中任意一个元素要么在这个组合中，要么不在这个组合中，我们用1表示在，用0表示不在，那么每一种组合实际上对应着一个01序列，而这个序列对应着一个十进制数，一共有多少种这样的序列呢？前面说了，是2 ^ n种，分别对应1 - 2 ^ n中的每一个十进制数，所以我们只需遍历这些数字，确定哪些位是1，将数组a中对应的数字放入组合中，再检查一下这个组合的和是否为sum即可。举个例子，在题目描述中我们说到a[6] = { 1, 2, 3, 4, 5, 6 }，sum = 10，那么&lt;/p&gt;&lt;p&gt;{1, 2, 3, 4} 相当于 111100 （1, 2, 3, 4在组合中，而5, 6不在）&lt;/p&gt;&lt;p&gt;{1, 3, 6} 相当于101001&lt;/p&gt;&lt;p&gt;...&lt;/p&gt;&lt;p&gt;数组a有6个元素，所以我们要搜索64个数，只有上面的三种组合满足条件，其他的全部淘汰。&lt;/p&gt;&lt;p&gt;代码-输出函数&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;输出一种组合，该组合取决于参数i&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;将参数i写成二进制的形式，对于i中取值为1的位，取数组a中对应的元素放到组合中&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;n是数组a中元素个数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #008000;"&gt;// 在取a中元素的时候，方向是从后向前的，因为我们测试i中哪些位是1的时候是从右向左进行的。&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;Output(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;a,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;n,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;i)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;k&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;n&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt;(i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cout&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;a[k]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;--&lt;/span&gt;&lt;span style="color: #000000;"&gt;k&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cout&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;endl&amp;nbsp;;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;代码-主函数&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;FixedSum(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;a,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;n,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;sum)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;total&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;n)&amp;nbsp;;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;组合总数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;total;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;i)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;t&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;i&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;s&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;k&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;n&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt;(t&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(t&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;a[k]&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;--&lt;/span&gt;&lt;span style="color: #000000;"&gt;k&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;t&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(s&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;sum)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Output(a,&amp;nbsp;n,&amp;nbsp;i)&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;解法二：回溯法&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;很多数排列组合问题都可以用回溯法来解决，回溯相比上面方法的优点就是减少可行解搜索的范围，因为回溯一旦发现当前解不满足条件就会停止搜索，回溯并进入下一个分支进行搜索，比上面的方法快很多，这里使用的是回溯法中的子集树模型。对于数组中任意一个元素，先将其放入结果集中，如果当前和不超出给定和，那就继续考察下一个元素，如果超出给定和，则舍弃当前元素。如此往复，直到找到所有可行解。&lt;/p&gt;&lt;p&gt;首先定义一个标志位数组flag[]，flag[i]如果为true，则表示a[i]在当前解中，如果flag[i]为false则表示不在。这个数组元素个数与数组a的元素个数相同。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;flag[&lt;/span&gt;&lt;span style="color: #800080;"&gt;100&lt;/span&gt;&lt;span style="color: #000000;"&gt;]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;代码-输出函数&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;输出一种组合，该组合有n个元素&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;Output(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;a,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;n)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;n;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;i)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(flag[i])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cout&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;a[i]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cout&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;endl&amp;nbsp;;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;代码-主函数&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;a:&amp;nbsp;待搜索的数组&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;n:&amp;nbsp;数组元素个数&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;t:&amp;nbsp;已经存储的元素个数&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;sum:&amp;nbsp;给定的和&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;FixedSum(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;a,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;n,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;t,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;sum)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(sum&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Output(a,&amp;nbsp;t)&amp;nbsp;;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(t &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;n&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;flag[t]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(sum&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;a[t]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FixedSum(a,&amp;nbsp;n,&amp;nbsp;t&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;sum&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;a[t])&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;flag[t]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(sum&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FixedSum(a,&amp;nbsp;n,&amp;nbsp;t&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;sum)&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Happy Coding!!!&lt;/p&gt;&lt;p&gt;== THE END ==&lt;/p&gt;&lt;img src="http://www.cnblogs.com/graphics/aggbug/2105195.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/graphics/archive/2011/07/14/2105195.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/graphics/archive/2011/07/11/2103117.html</id><title type="text">也谈杨辉三角形</title><summary type="text">很久没更新博客了，来篇水的。今天看见有位兄弟写了杨辉三角形，记得以前自己也研究过，索性也发一篇，欢迎讨论。来历杨辉三角形也叫贾宪三角形，西方叫帕斯卡三角形，其实就是各阶二项式系数排列起来构成的三角形，如下。每行的数字实际上是(a + b) ^ n展开后的结果。 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1历史上发现这个三角形的人很多，这里介绍几个主要的，北宋人贾宪约1050年首先使用“贾宪三角”进行高次开方运算。杨辉，字谦光，南宋时期杭州人。在他1261年所著的《详解九章算法》一书中，辑录了如上所示的三角形数表，称之为“开方作法本源”图。欧洲直到1623年以后，法国数学家帕斯卡在</summary><published>2011-07-11T09:48:00Z</published><updated>2011-07-11T09:48:00Z</updated><author><name>zdd</name><uri>http://www.cnblogs.com/graphics/</uri></author><link rel="alternate" href="http://www.cnblogs.com/graphics/archive/2011/07/11/2103117.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/graphics/archive/2011/07/11/2103117.html"/><content type="html">&lt;p&gt;很久没更新博客了，来篇水的。今天看见有位兄弟写了杨辉三角形，记得以前自己也研究过，索性也发一篇，欢迎讨论。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;来历&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;杨辉三角形也叫贾宪三角形，西方叫帕斯卡三角形，其实就是各阶二项式系数排列起来构成的三角形，如下。每行的数字实际上是(a + b) ^ n展开后的结果。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 1 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 2 1 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 3 3 1 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 4 6 4 1&lt;/p&gt;&lt;p&gt;历史上发现这个三角形的人很多，这里介绍几个主要的，北宋人贾宪约1050年首先使用&amp;ldquo;贾宪三角&amp;rdquo;进行高次开方运算。杨辉，字谦光，南宋时期杭州人。在他1261年所著的《详解九章算法》一书中，辑录了如上所示的三角形数表，称之为&amp;ldquo;开方作法本源&amp;rdquo;图。欧洲直到1623年以后，法国数学家帕斯卡在13岁时发现了&amp;ldquo;帕斯卡三角&amp;rdquo;。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;编程输出杨辉三角形&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;方法一&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;使用二维数组计算并存储各行数字然后输出，如果不考虑每行左侧空格的话，上面的三角形可以写成如下形式&lt;/p&gt;&lt;p&gt;1&lt;/p&gt;&lt;p&gt;1 1&lt;/p&gt;&lt;p&gt;1 2 1&lt;/p&gt;&lt;p&gt;1 3 3 1&lt;/p&gt;&lt;p&gt;1 4 6 4 1&lt;/p&gt;&lt;p&gt;根据观察我们发现，第一列和对角线上的数字都是1，其他数字则是其左上方数字和正上方数字之和，如下图，其中数字1被标记成红色，因为1是我们预先设置好的，图中的白色数字为合成数字，合成数字是由1或者其他已经存在的数字相加而成的。比如数字2是由其上方的1和左上方的1相加而成，第一个3是由其上方的2和左上方的1相加而成。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011071117003615.png" /&gt;&lt;/p&gt;&lt;p&gt;设p是存储数字的二维数组，设i和j分别表示p的行号和列号，则有&lt;/p&gt;&lt;ul&gt;&lt;li&gt;如果j == 0 或 j == i，则p[i][j] = 1 ;&lt;/li&gt;&lt;li&gt;否则，p[i][j] = p[i - 1][j] + p[i - 1][j - 1] ;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;有了上面的分析，写代码就不再是难事了。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 打印杨辉三角形，参数n是层数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; YanghuiTriangle(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; n)&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;定义二维数组并初始化&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;**&lt;/span&gt;&lt;span style="color: #000000;"&gt;p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;[n] ;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; n; &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;i)&lt;br /&gt;    {&lt;br /&gt;        p[i] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;[n] ;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; j &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; j &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; n; &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;j)&lt;br /&gt;            p[i][j] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 填充并输出&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; n; &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;i)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; j &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; j &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; i; &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;j)&lt;br /&gt;        {&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 第一列和对角线列的元素置1&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(j &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;||&lt;/span&gt;&lt;span style="color: #000000;"&gt; j &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; i)&lt;br /&gt;                p[i][j] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; ;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 其他元素是其上方元素和左上方元素之和&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;                p[i][j] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; p[i &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;][j] &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; p[i &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;][j &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;] ;&lt;br /&gt;            cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; p[i][j] &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; ;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; endl ;&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;输出如下&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011071117380184.png" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;方法二&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;方法一的优点是直观，代码好写，但是缺点是如果层数n很大的话，那么将需要很大的存储空间(n * n)，而这么大的空间中有一半被浪费掉了。下面这个方法使用一维数组实现，空间上只要n即可。思路是逐行计算并输出，举个例子，假设我们要输出5行（n = 5），我们先计算并输出第一行，然后计算并输出第二行，...，最后是第五行，因为每行的数字个数不超过行数n，所以一个含有n个元素的一维数组就可以胜任了，只不过这个一维数组中的数字是不断变化的（除了第一个元素），我们用新增的元素覆盖掉了原来的元素。下图展示了这个一维数组的变化过程。其中红色字数字表示每次迭代新增的数字。可见这种方法中第一列数字1始终保持不变。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011071117195165.png" /&gt;&lt;/p&gt;&lt;p&gt;1 首先定义一个含有n个元素的一维数组，且第一个元素初始化为1，其他元素初始化为0&lt;/p&gt;&lt;p&gt;2 对于每一行的计算，除了第一元素之外，其他所有元素都由其本身的值加上其前一个值构成，注意，计算的方向是从后向前，如果从前向后的话，元素本来的值将被覆盖。&lt;/p&gt;&lt;p&gt;代码如下&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 打印杨辉三角形，参数n是层数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; YanghuiTriangle(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; n)&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 定义一个一维数组&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; a &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;[n] ;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; n; &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;i)&lt;br /&gt;        a[i] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; ;&lt;br /&gt;    a[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; ;&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; n; &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;i)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 计算当前行的数字，注意要从后向前计算，否则会覆盖以前的值&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; j &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; i; j &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #000000;"&gt;--&lt;/span&gt;&lt;span style="color: #000000;"&gt;j)&lt;br /&gt;            a[j] &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; a[j &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;];&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 打印空格&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; j &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; j &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; n &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; i; &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;j)&lt;br /&gt;            cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; ;&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 打印数字&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; j &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; j &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;j)&lt;br /&gt;            cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; a[j] &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; ;&lt;br /&gt;&lt;br /&gt;        cout &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; endl ;&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;输出如下，因为处理了空格，所以更美观一点。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011071117382379.png" /&gt;&lt;/p&gt;&lt;p&gt;Happy Coding!!!&lt;/p&gt;&lt;p&gt;== THE END ==&lt;/p&gt;&lt;img src="http://www.cnblogs.com/graphics/aggbug/2103117.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/graphics/archive/2011/07/11/2103117.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/graphics/archive/2011/07/08/2100909.html</id><title type="text">八进制字符与十六进制字符</title><summary type="text">一般形式在C中有两种特殊的字符，八进制转义字符和十六进制转义字符，八进制字符的一般形式是'\ddd'，d是0-9的数字。十六进制字符的一般形式是'\xhh'，h是0-9或A-F内的一个。八进制字符和十六进制字符表示的是字符的ASCII码对应的数值。比如'\063'表示的是字符'3'，因为'3'的ASCII码是30（十六进制），48（十进制），63（八进制）。'\x41'表示的是字符'A'，因为'A'的ASCII码是41（十六进制），65（十进制），101（八进制）。字</summary><published>2011-07-08T05:36:00Z</published><updated>2011-07-08T05:36:00Z</updated><author><name>zdd</name><uri>http://www.cnblogs.com/graphics/</uri></author><link rel="alternate" href="http://www.cnblogs.com/graphics/archive/2011/07/08/2100909.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/graphics/archive/2011/07/08/2100909.html"/><content type="html">&lt;p&gt;&lt;strong&gt;一般形式&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在C中有两种特殊的字符，八进制转义字符和十六进制转义字符，八进制字符的一般形式是'\ddd'，d是0-9的数字。十六进制字符的一般形式是'\xhh'，h是0-9或A-F内的一个。八进制字符和十六进制字符表示的是字符的ASCII码对应的数值。比如&lt;/p&gt;&lt;p&gt;'\063'表示的是字符'3'，因为'3'的ASCII码是30（十六进制），48（十进制），63（八进制）。&lt;/p&gt;&lt;p&gt;'\x41'表示的是字符'A'，因为'A'的ASCII码是41（十六进制），65（十进制），101（八进制）。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;字符长度&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;八进制字符和十六进制字符长度都是1，因为他们表示的是一个字节的字符。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;练习&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;下面字符的长度是？&lt;/p&gt;&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\t\"\062\xff\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;答案：5&lt;/p&gt;&lt;p&gt;分析：\t ，\" ，\062 ，\xff ，\n 。一共是5个转义字符，在C中，转义字符的长度都是1，字符串结束符'\0'不计长度。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/graphics/aggbug/2100909.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/graphics/archive/2011/07/08/2100909.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/graphics/archive/2011/06/03/1967193.html</id><title type="text">Direct2D教程（七）单色画刷</title><summary type="text">概述画刷是D2D中最重要的资源之一，无论绘制什么图形，都离不开画刷，它好比是画家手中的画笔。画刷由render target创建，是设备相关的资源，如果渲染设备重建了，那么需要重新建立画刷。Direct2D中有以下四种类型的画刷，这些画刷全部继承自ID2D1Brush，并且有一些共同特征（比如设置和获取opacity，以及transform）。ID2D1SolidColorBrush 单色画刷 ID2D1LinearGradientBrush 线性梯度色画刷 ID2D1RadialGradientBrush 放射梯度色画刷 ID2D1BitmapBrush 位图画刷下面是几种画刷及其对应的绘制</summary><published>2011-06-03T04:34:00Z</published><updated>2011-06-03T04:34:00Z</updated><author><name>zdd</name><uri>http://www.cnblogs.com/graphics/</uri></author><link rel="alternate" href="http://www.cnblogs.com/graphics/archive/2011/06/03/1967193.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/graphics/archive/2011/06/03/1967193.html"/><content type="html">&lt;p&gt;&lt;strong&gt;概述&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;画刷是D2D中最重要的资源之一，无论绘制什么图形，都离不开画刷，它好比是画家手中的画笔。画刷由render target创建，是设备相关的资源，如果渲染设备重建了，那么需要重新建立画刷。Direct2D中有以下四种类型的画刷，这些画刷全部继承自ID2D1Brush，并且有一些共同特征（比如设置和获取opacity，以及transform）。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;ID2D1SolidColorBrush 单色画刷  &lt;/li&gt;&lt;li&gt;ID2D1LinearGradientBrush 线性梯度色画刷  &lt;/li&gt;&lt;li&gt;ID2D1RadialGradientBrush 放射梯度色画刷  &lt;/li&gt;&lt;li&gt;ID2D1BitmapBrush 位图画刷&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;下面是几种画刷及其对应的绘制效果&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011022817221977.png" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;画刷属性&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;颜色&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在使用除位图画刷以外的任何一种画刷绘制之前，你必须首先指定颜色。在Direct2D中，颜色用D2D1_COLOR_F结构体表示（实际上相当于Direct3D中的D3DCOLORVALUE，只不过换了个名字而已）。D2D1_COLOR_F使用sRGB编码，sRGB编码将颜色分成四部分：红色，绿色，蓝色以及Alpha（透明值）。每个部分都由一个浮点数表示，范围是0.0-1.0。数值越大表示颜色越深，0.0表示无此颜色，1.0表示满色。对于Alpha（透明值），0.0表示完全透明，1.0表示完全不透明。可以使用D2D1::ColorF类的构造函数来创建颜色，这个类有三个构造函数，所以有下面三种方法。&lt;/p&gt;&lt;p&gt;使用ColorF(knownColor, FLOAT)，第一个参数是Direct2D预定义的一种颜色，第二个参数是Alpha值。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; m_pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateSolidColorBrush(&lt;br /&gt;    D2D1::ColorF(D2D1::ColorF::Black, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;),&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;m_pBlackBrush&lt;br /&gt;    );&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;使用ColorF(FLOAT, FLOAT, FLOAT, FLOAT)，参数分别是，红色值，绿色值，蓝色值和Alpha值。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;ID2D1SolidColorBrush &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;pGridBrush &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; NULL;&lt;br /&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pCompatibleRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateSolidColorBrush(&lt;br /&gt;    D2D1::ColorF(D2D1::ColorF(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0.93f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0.94f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0.96f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pGridBrush&lt;br /&gt;    );&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;使用ColorF(UINT32 rgb, FLOAT a)，第一个参数是十六进制格式的颜色，是0xRRGGBB的形式，第二个参数是Alpha值。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; m_pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateSolidColorBrush(&lt;br /&gt;    D2D1::ColorF(D2D1::ColorF(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0x9ACD32&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),  &lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;m_pYellowGreenBrush&lt;br /&gt;    );&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;透明度&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;英文叫opacity，当opacity值为0时，图形完全透明，当opacity值为1时，图形无影响。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;变换（Transform）&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;画刷的第三个属性是只对画刷所应用的变换，这通常是一个变换矩阵。注意这个属性目前只对位图画刷起作用，其他类型的画刷不受这个属性的影响。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;设置属性&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;有两种方法设置画刷的属性，第一种是在定义画刷的时候指定属性，可以使用如下的结构体进行设置。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1_BRUSH_PROPERTIES {&lt;br /&gt;  FLOAT             opacity;&lt;br /&gt;  D2D1_MATRIX_3X2_F transform;&lt;br /&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;下面代码使用该结构体设置属性并创建画刷。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;D2D1_BRUSH_PROPERTIES brushProperties &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; { &lt;/span&gt;&lt;span style="color: #800080;"&gt;1.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, D2D1::Matrix3x2F::Identity() } ;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Create brush&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateSolidColorBrush(&lt;br /&gt;    D2D1::ColorF(D2D1::ColorF::Black),&lt;br /&gt;    brushProperties,&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pStrokeBrush&lt;br /&gt;    ) ;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;D2D也提供了一个函数来快速常见属性，这个函数如下&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;D2D1_BRUSH_PROPERTIES BrushProperties(&lt;br /&gt;  __in  FLOAT opacity &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;br /&gt;  __in  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1_MATRIX_3X2_F &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;transform &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;  D2D1::IdentityMatrix() &lt;br /&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;所以上面创建画刷的代码可以改写成&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateSolidColorBrush(&lt;br /&gt;    D2D1::ColorF(D2D1::ColorF::Black),&lt;br /&gt;    D2D1::BrushProperties(),&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pStrokeBrush&lt;br /&gt;    ) ;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;第二种是先创建画刷，再设置属性。一般是在一个图形之前设置画刷的属性，在绘制另外一个图形之前再次设置其属性，这样同一个画刷可以绘制出不同的效果来。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;&lt;span style="color: #008000;"&gt;// 先创建画刷&lt;/span&gt;&lt;br /&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateSolidColorBrush(&lt;br /&gt;    D2D1::ColorF(D2D1::ColorF::Black),&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pStrokeBrush&lt;br /&gt;    ) ;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000;"&gt;// 再设置属性，注意SetTransform对于单色画刷是没有作用的，这里只做演示。&lt;/span&gt;&lt;br /&gt;pStrokeBrush&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;SetOpacity(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;pStrokeBrush&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;SetColor(D2D1::ColorF(D2D1::ColorF::Green)) ;&lt;br /&gt;pStrokeBrush&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;SetTransform(D2D1::Matrix3x2F::Rotation(&lt;/span&gt;&lt;span style="color: #800080;"&gt;45.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, D2D1::Point2F(&lt;/span&gt;&lt;span style="color: #800080;"&gt;150.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;150.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;))) ;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;使用单色画刷&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;下面以单色画刷为例，看看如何使用画刷。单色画刷并不影响性能，所以你可以在任何需要的时候创建它而不必考虑性能问题，但是梯度色画刷和位图画刷则不然。当我们创建了一个render target之后，就可以使用其成员函数CreateSolidColorBrush来创建单色画刷了。这个函数的定义如下。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;HRESULT CreateSolidColorBrush(&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt;]  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1_COLOR_F &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;color,&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt;]  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1_BRUSH_PROPERTIES &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;brushProperties,&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt;&lt;span style="color: #000000;"&gt;]  ID2D1SolidColorBrush &lt;/span&gt;&lt;span style="color: #000000;"&gt;**&lt;/span&gt;&lt;span style="color: #000000;"&gt;solidColorBrush&lt;br /&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;看一下参数，第一个参数是画刷的颜色。第二个参数是画刷的属性，这个属性是一个结构体，上面已经提到过了。最后一个参数是一个ID2D1SolidColorBrush**类型的变量，用来接收创建后的画刷。&lt;/p&gt;&lt;p&gt;这个函数还有一个重载版本，省略了上面的第二个参数，我们一般情况下使用这个重载版本就足够用了。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;HRESULT CreateSolidColorBrush(&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt;]  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1_COLOR_F &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;color,&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt;&lt;span style="color: #000000;"&gt;]  ID2D1SolidColorBrush &lt;/span&gt;&lt;span style="color: #000000;"&gt;**&lt;/span&gt;&lt;span style="color: #000000;"&gt;solidColorBrush&lt;br /&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;创建画刷&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;下面的代码创建了两个画刷，一个黑色的用来绘制矩形轮廓，一个黄色的用来填充矩形。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Create a black brush to draw rectangle outline&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateSolidColorBrush(&lt;br /&gt;    D2D1::ColorF(D2D1::ColorF::Black),&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pBlackBrush&lt;br /&gt;    ) ;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Create a yellow brush to fill in the rectangle&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateSolidColorBrush(&lt;br /&gt;    D2D1::ColorF(D2D1::ColorF(D2D1::ColorF::Yellow, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;)),&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pYellowBrush&lt;br /&gt;    );&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;使用画刷&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;下面的代码先使用黑色画刷绘制矩形，然后使用黄色画刷填充之。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Draw Rectangle&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;DrawRectangle(&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;rectangle,&lt;br /&gt;    pBlackBrush&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Fill rectangle&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;FillRectangle(&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;rectangle,&lt;br /&gt;    pYellowBrush&lt;br /&gt;    ) ;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;释放画刷&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;画刷使用完毕后要释放&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;pBlackBrush&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Release() ;&lt;br /&gt;pBlackBrush &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; NULL ;&lt;br /&gt;pYellowBrush&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Release() ;&lt;br /&gt;pYellowBrush &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; NULL ;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Happy Coding!!!&lt;/p&gt;&lt;p&gt;== THE END ==&lt;/p&gt;&lt;img src="http://www.cnblogs.com/graphics/aggbug/1967193.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/graphics/archive/2011/06/03/1967193.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/graphics/archive/2011/06/01/2060480.html</id><title type="text">Direct2D教程（六）图形也能做运算</title><summary type="text">概述大家都学过集合运算，给定两个集合，可以求他们的并集，交集，差集等。其实图形之间也能做运算，今天就带大家开始图形运算之旅，讲讲如何合并图形。在D2D中有四种方法合并图形，分别是并（UNION），交（INTERSECT），差（EXCLUDE）和异或（XOR）。那么图形之间是如何合并的呢？两个图形之间进行Xor的结果是什么呢？为了便于理解，我先把效果图贴上来。下面图片中第一副图示两个圆的原始图，第二副图是UNION的结果，取两个圆所有的部分，但是公共部分只保留一份。第三幅图是INTERSECT的结果，取两个圆的公共部分。第四幅图是XOR的结果，取两个圆公共部分以外的部分。最后一幅图是EXCLUD</summary><published>2011-06-01T01:37:00Z</published><updated>2011-06-01T01:37:00Z</updated><author><name>zdd</name><uri>http://www.cnblogs.com/graphics/</uri></author><link rel="alternate" href="http://www.cnblogs.com/graphics/archive/2011/06/01/2060480.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/graphics/archive/2011/06/01/2060480.html"/><content type="html">&lt;p&gt;&lt;strong&gt;概述&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;大家都学过集合运算，给定两个集合，可以求他们的并集，交集，差集等。其实图形之间也能做运算，今天就带大家开始图形运算之旅，讲讲如何合并图形。在D2D中有四种方法合并图形，分别是并（UNION），交（INTERSECT），差（EXCLUDE）和异或（XOR）。那么图形之间是如何合并的呢？两个图形之间进行Xor的结果是什么呢？为了便于理解，我先把效果图贴上来。下面图片中第一副图示两个圆的原始图，第二副图是UNION的结果，取两个圆所有的部分，但是公共部分只保留一份。第三幅图是INTERSECT的结果，取两个圆的公共部分。第四幅图是XOR的结果，取两个圆公共部分以外的部分。最后一幅图是EXCLUDE的结果，这个相当于集合的减法运算，在一个圆中去除两个圆的公共部分。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011053116574222.png" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;合并图形的基本步骤&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;图形的合并要经历以下几个步骤，合并后的图形是存放在&lt;a href="http://www.cnblogs.com/graphics/archive/2011/05/27/2057759.html"&gt;path geometry&lt;/a&gt;中的。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;创建待合并的图形&lt;/li&gt;&lt;li&gt;创建path geometry&lt;/li&gt;&lt;li&gt;获取path geometry中的sink对象&lt;/li&gt;&lt;li&gt;调用CombineWithGeometry函数进行合并&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;下面以UNION操作为例，详细演示如何合并图形。首先声明几个变量，pPathGeometryUnion用来存放合并后的图形，&lt;span style="color: #000000;"&gt;pCircleGeometry1和&lt;/span&gt;&lt;span style="color: #000000;"&gt;pCircleGeometry2表示待合并的两个圆。&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;ID2D1PathGeometry&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;    pPathGeometryUnion        &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; NULL ;&lt;br /&gt;ID2D1EllipseGeometry&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;   pCircleGeometry1        &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; NULL ;&lt;br /&gt;ID2D1EllipseGeometry&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;   pCircleGeometry2        &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; NULL ;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;创建待合并的图形&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这里创建两个圆，半径都是50.0f，一个圆心在（75.0f, 75.0f），另一个圆心在（125.0f, 75.0f），也就是说这两个圆是相交的。对应上面图片中第一副图。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 第一个圆&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1_ELLIPSE circle1 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1::Ellipse(&lt;br /&gt;    D2D1::Point2F(&lt;/span&gt;&lt;span style="color: #800080;"&gt;75.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;75.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;),&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #800080;"&gt;50.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #800080;"&gt;50.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;    ) ;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pD2DFactory&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateEllipseGeometry(&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;circle1,&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pCircleGeometry1&lt;br /&gt;    ) ;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 第二个圆&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1_ELLIPSE circle2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1::Ellipse(&lt;br /&gt;D2D1::Point2F(&lt;/span&gt;&lt;span style="color: #800080;"&gt;125.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;75.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;),&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;50.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;50.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;) ;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pD2DFactory&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateEllipseGeometry(&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;circle2,&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pCircleGeometry2&lt;br /&gt;    ) ;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;创建path geometry&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pD2DFactory&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreatePathGeometry(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pPathGeometryUnion) ;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;获取path geometry的sink对象&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(SUCCEEDED(hr))&lt;br /&gt;{&lt;br /&gt;    ID2D1GeometrySink &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;pGeometrySink &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; NULL;&lt;br /&gt;    hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pPathGeometryUnion&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Open(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pGeometrySink) ;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;调用CombineWithGeometry进行合并&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;CombineWithGeometry是ID2D1SimplifiedGeometrySink接口里面的一个函数，所以任何类型的geometry都可以进行合并操作，合并的方式就是一个图形调用这个函数，将另一个图形作为参数传进去，比如要合并A和B两个图形，调用方法就是A-&amp;gt;CombineWithGeometry(B, ...)。看一下这个函数的定义。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;HRESULT CombineWithGeometry(&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt;]   ID2D1Geometry &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;inputGeometry,&lt;br /&gt;         D2D1_COMBINE_MODE combineMode,&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt;&lt;span style="color: #000000;"&gt;]  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1_MATRIX_3X2_F &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;inputGeometryTransform,&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt;]   ID2D1SimplifiedGeometrySink &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;geometrySink&lt;br /&gt;) &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;第一个参数是待合并的图形，相当于上面例子中的B，第二个参数是合并的方式，目前有下面四种。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;D2D1_COMBINE_MODE_UNION （并-两个图形的所有部分）&lt;/li&gt;&lt;li&gt;D2D1_COMBINE_MODE_INTERSECT （交-两个图形的公共部分）&lt;/li&gt;&lt;li&gt;D2D1_COMBINE_MODE_XOR （异或-两个图形的所有部分，但公共部分除外）&lt;/li&gt;&lt;li&gt;D2D1_COMBINE_MODE_EXCLUDE （差-属于一个图形而不属于另外一个图形的部分）&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;第三个参数是一个变换矩阵，可以在合并之前对参数一进行一些变换。最后一个参数是path geometry的sink对象，用来接收合并后的图形。调用代码如下，这里我们选择UNION合并方式，合并前不做任何变换，所以第三个参数传入NULL。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pPathGeometryUnion&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Open(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pGeometrySink) ;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(SUCCEEDED(hr))&lt;br /&gt;{&lt;br /&gt;    hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pCircleGeometry1&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CombineWithGeometry(&lt;br /&gt;        pCircleGeometry2,&lt;br /&gt;        D2D1_COMBINE_MODE_UNION,&lt;br /&gt;        NULL,&lt;br /&gt;        pGeometrySink&lt;br /&gt;        ) ;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;绘制&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;由于图形已经合并，并且合并的结果已经存放到path geometry中，所以直接调用对应的path geometry即可进行绘制，也就是上面的pPathGeometryUnion。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;SetTransform(D2D1::Matrix3x2F::Translation(&lt;/span&gt;&lt;span style="color: #800080;"&gt;100&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;100&lt;/span&gt;&lt;span style="color: #000000;"&gt;));&lt;br /&gt;pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;DrawGeometry(pPathGeometryUnion, pBlackBrush) ;&lt;br /&gt;pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;FillGeometry(pPathGeometryUnion, pFillBrush) ;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;学习Direct2D已经有两个月的时间了，断断续续，现在的学习还比较浅，主要停留在如何使用API层面上，在随后的系列中，我会逐渐加入一些Demo，把相关的知识点整合到一起，这样也能一些整体的认识，对各种资源之间的协调有更深刻的认识。另外，这一篇也是Geometry系列的最后一篇，从下一篇开始学习（Brush）画刷。这是我第一次认真的写一个系列，以前曾经多次尝试，但都是有始无终，这次我想坚持下去，所以希望大家多多给我提意见，我一直觉得写一篇通俗易懂的文章绝非易事，我也经常把以前写过的文章从新拿出来重新审视并作些修改。因为一个技术点，你自己明白了，不一定能给别人讲明白，所以无论是什么意见，技术上的，写作技巧上的，或者其他方面的，越多越好！&lt;/p&gt;&lt;ul&gt;&lt;/ul&gt;&lt;img src="http://www.cnblogs.com/graphics/aggbug/2060480.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/graphics/archive/2011/06/01/2060480.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/graphics/archive/2011/05/31/2060095.html</id><title type="text">Direct2D教程（五）复合图形</title><summary type="text">概述Direct2D支持以下几种类型的几何图形。Simple Geometry（简单几何图形） 矩形 圆角矩形 椭圆Path Geometry（路径图形）Composite Geometry（复合图形） Geometry Group（图形组） Transformed Geometry（变换的图形）上一篇介绍了Path geometry，这篇介绍复合图形。复合图形也可以叫做合成图形，包含两种，一种是图形组，即由多个图形组成的一组图形，另一种是经过变换的图形，D2D支持的变换有四种，平移，旋转，缩放和倾斜。图形组由于图形组是一组图形的集合，所以如果对图形组进行操作，会影响到其中每一个图形，这对批量</summary><published>2011-05-31T02:05:00Z</published><updated>2011-05-31T02:05:00Z</updated><author><name>zdd</name><uri>http://www.cnblogs.com/graphics/</uri></author><link rel="alternate" href="http://www.cnblogs.com/graphics/archive/2011/05/31/2060095.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/graphics/archive/2011/05/31/2060095.html"/><content type="html">&lt;p&gt;&lt;strong&gt;概述&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Direct2D支持以下几种类型的几何图形。&lt;br /&gt;Simple Geometry（简单几何图形）&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 矩形&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 圆角矩形&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 椭圆&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Path Geometry（路径图形）&lt;br /&gt;Composite Geometry（复合图形）&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Geometry Group（图形组）&lt;/li&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Transformed Geometry（变换的图形）&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;上一篇介绍了Path geometry，这篇介绍复合图形。复合图形也可以叫做合成图形，包含两种，一种是图形组，即由多个图形组成的一组图形，另一种是经过变换的图形，D2D支持的变换有四种，平移，旋转，缩放和倾斜。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;图形组&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;由于图形组是一组图形的集合，所以如果对图形组进行操作，会影响到其中每一个图形，这对批量操作图形是很方便的。图形组在D2D中用接口ID2D1GeometryGroup来表示。创建图形组使用函数ID2D1Factory::CreateGeometryGroup，它的定义如下&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;virtual&lt;/span&gt;&lt;span style="color: #000000;"&gt; HRESULT CreateGeometryGroup(&lt;br /&gt;         D2D1_FILL_MODE fillMode,&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt;]   ID2D1Geometry &lt;/span&gt;&lt;span style="color: #000000;"&gt;**&lt;/span&gt;&lt;span style="color: #000000;"&gt;geometries,&lt;br /&gt;         UINT geometriesCount,&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt;&lt;span style="color: #000000;"&gt;]  ID2D1GeometryGroup &lt;/span&gt;&lt;span style="color: #000000;"&gt;**&lt;/span&gt;&lt;span style="color: #000000;"&gt;geometryGroup&lt;br /&gt;) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;第一个参数表示填充模式，可以是D2D1_FILL_MODE_ALTERNATE或者D2D1_FILL_MODE_WINDING，关于这两者的详细说明，后面有述。第二个参数是一个类型为&lt;span style="color: #000000;"&gt;ID2D1Geometry的数组，这个数组中包含了所有将被放入图形组的图形，第三个参数是数组中元素的个数，&lt;/span&gt;&lt;span style="color: #000000;"&gt;最后一个参数用来接收创建后的ID2D1GeometryGroup。 &lt;/span&gt;&lt;span style="color: #000000;"&gt;使用GeometryGroup的步骤如下。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #000000;"&gt;创建图形组中的所有图形&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;这里我们创建四个同心圆，为了简化程序，只给出第一个圆的创建代码。创建其他的圆只需更改一下半径即可。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1_ELLIPSE ellipse1 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1::Ellipse(&lt;br /&gt;    D2D1::Point2F(&lt;/span&gt;&lt;span style="color: #800080;"&gt;105.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;105.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;),&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #800080;"&gt;25.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #800080;"&gt;25.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pD2DFactory&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateEllipseGeometry(&lt;br /&gt;    ellipse1,&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pEllipseGeometry1&lt;br /&gt;    );&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #000000;"&gt;创建图形组&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;先将所有的图形放到一个数组里面&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;ID2D1Geometry &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;ppGeometries[] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;{&lt;br /&gt;    pEllipseGeometry1,&lt;br /&gt;    pEllipseGeometry2,&lt;br /&gt;    pEllipseGeometry3,&lt;br /&gt;    pEllipseGeometry4&lt;br /&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;然后使用&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateGeometryGroup来创建图形组。&lt;/span&gt;&lt;/p&gt;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pD2DFactory&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateGeometryGroup(&lt;br /&gt;    D2D1_FILL_MODE_ALTERNATE,&lt;br /&gt;    ppGeometries,&lt;br /&gt;    ARRAYSIZE(ppGeometries),&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pGeoGroup_AlternateFill&lt;br /&gt;    );&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #000000;"&gt;使用图形组进行绘制&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;对图形组的绘制，就是对组中所有的图形进行绘制。&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;FillGeometry(pGeoGroup_AlternateFill, pFillBrush);&lt;br /&gt;pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;DrawGeometry(pGeoGroup_AlternateFill, pStrokeBrush, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1.0f&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;D2D1_FILL_MODE_ALTERNATE和D2D1_FILL_MODE_WINDING这两个模式的区别见下图，两者线条的颜色都是一样的，只是填充色一个是交替模式，一个是统一模式。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011053109314556.png" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;变换图形&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在2D中变换图形主要有两种方式，一是对图形所在的Render target进行变换，二是对图形本身进行变换。这两者是有区别的，对render target进行变换将影响到render target上所有的图形，而对图形本身进行变换则只影响图形自己，而且这种方式只改变图形的填充，而不改变其轮廓（也即line width）。这里我们主要介绍如何对图形本身进行变换。函数&lt;span style="color: #000000;"&gt;CreateTransformedGeometry可以创建一个变换后的图形。该函数定义如下&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;virtual&lt;/span&gt;&lt;span style="color: #000000;"&gt; HRESULT CreateTransformedGeometry(&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt;]            ID2D1Geometry &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;sourceGeometry,&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt;, optional]  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; D2D1_MATRIX_3X2_F &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;transform,&lt;br /&gt;  [&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt;&lt;span style="color: #000000;"&gt;]           ID2D1TransformedGeometry &lt;/span&gt;&lt;span style="color: #000000;"&gt;**&lt;/span&gt;&lt;span style="color: #000000;"&gt;transformedGeometry&lt;br /&gt;) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;第一个参数sourceGeometry表示待变换的图形，第二个参数表示变换用的矩阵，最后一个参数用来存放变换后的结果&lt;span style="color: #000000;"&gt;。举个例子，下面的代码将pPathGeometry沿X轴和Y轴分别平移100个单位距离。平移后的图形保存在&lt;/span&gt;&lt;span style="color: #000000;"&gt;pTransformedGeometry中。&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; pD2DFactory&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateTransformedGeometry(&lt;br /&gt;    pPathGeometry,&lt;br /&gt;    D2D1::Matrix3x2F::Translation(&lt;/span&gt;&lt;span style="color: #800080;"&gt;100&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;100&lt;/span&gt;&lt;span style="color: #000000;"&gt;),&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pTransformedGeometry&lt;br /&gt;    );&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;前面说了对图形本身进行变换不影响线条的宽度，而对render target进行变换则会影响，来看一下两者的区别，我们以缩放变换为例。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;变换render target&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Transform the render target, then draw the rectangle geometry again.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;m_pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;SetTransform(&lt;br /&gt;    D2D1::Matrix3x2F::Scale(&lt;br /&gt;        D2D1::SizeF(&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;.f, &lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;.f),&lt;br /&gt;        D2D1::Point2F(&lt;/span&gt;&lt;span style="color: #800080;"&gt;175&lt;/span&gt;&lt;span style="color: #000000;"&gt;.f, &lt;/span&gt;&lt;span style="color: #800080;"&gt;175&lt;/span&gt;&lt;span style="color: #000000;"&gt;.f))&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;m_pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;DrawGeometry(m_pRectangleGeometry, m_pBlackBrush, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;效果图如下，注意，矩形的线条变宽了。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011053109592944.png" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;变换图形本身&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;hr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; m_pD2DFactory&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateTransformedGeometry(&lt;br /&gt;     m_pRectangleGeometry,&lt;br /&gt;     D2D1::Matrix3x2F::Scale(&lt;br /&gt;         D2D1::SizeF(&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;.f, &lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;.f),&lt;br /&gt;         D2D1::Point2F(&lt;/span&gt;&lt;span style="color: #800080;"&gt;175&lt;/span&gt;&lt;span style="color: #000000;"&gt;.f, &lt;/span&gt;&lt;span style="color: #800080;"&gt;175&lt;/span&gt;&lt;span style="color: #000000;"&gt;.f)),&lt;br /&gt;     &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;m_pTransformedGeometry&lt;br /&gt;     );&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Replace the previous render target transform.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;m_pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;SetTransform(D2D1::Matrix3x2F::Identity());&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Draw the transformed geometry.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;m_pRenderTarget&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;DrawGeometry(m_pTransformedGeometry, m_pBlackBrush, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;效果图如下，注意，矩形的线条保持原样。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/64257/2011053109591928.png" /&gt;&lt;/p&gt;&lt;p&gt;Happy Coding!!!&lt;/p&gt;&lt;p&gt;== THE END ==&lt;/p&gt;&lt;img src="http://www.cnblogs.com/graphics/aggbug/2060095.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/graphics/archive/2011/05/31/2060095.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
