从本章开始,我们介绍D2D几何图形。

D2D图形分类

Direct2D支持多种类型的几何图形,包括
Simple Geometry(简单几何图形)

  • 矩形
  • 圆角矩形
  • 椭圆

Path Geometry(路径图形)
Composite Geometry(复合图形)

  • Geometry Group(图形组)
  • Transformed Geometry(变换的图形)

各种图形对应的D2D接口如下,所有接口都继承自ID2D1Geometry。

  • 矩形-ID2D1RectangleGeometry
  • 圆角矩形-ID2D1RoundedRectangleGeometry
  • 椭圆-ID2D1EllipseGeometry
  • 路径图形-ID2D1PathGeometry
  • 图形组-ID2D1GeometryGroup
  • 经过变换的图形-ID2D1TransformedGeometry

今天我们先来看一下简单几何图形,其他类型的图形将在后续章节中介绍,上面的简单图形有三种,其实还有一种,就是直线,所以D2D目前支持的简单图形有如下四种。

  • Line - 直线
  • Rectangle - 矩形
  • Rounded Rectangle - 圆角矩形
  • Ellipse - 椭圆

下面逐个介绍每种图形的绘制方法,绘制某种图形是通过Render target对象调用相应的绘图函数来完成的,所以下面的代码都假定Render target对象已经创建好了。

直线

绘制直线使用函数DrawLine,先看一下函数定义,前两个参数分别是直线的起点和终点,第三个参数是画刷。第四个参数是线的宽度,最后一个参数是线的样式,比如实线,虚线或是其他风格的线,你可以使用D2D提供的样式,也可以自己定义样式。由于最后两个参数有默认值,所以我们通常只提供前三个参数即可。最后两个参数在下面的绘图函数中都有出现。

  1. virtual void DrawLine(
  2. D2D1_POINT_2F point0,
  3. D2D1_POINT_2F point1,
  4. [in] ID2D1Brush *brush,
  5. FLOAT strokeWidth = 1.0f,
  6. [in, optional] ID2D1StrokeStyle *strokeStyle = NULL
  7. ) = 0;

下面的代码绘制一条黑色直线,起点是(100, 100),终点是(500, 500)。

pRenderTarget->DrawLine(
    D2D1::Point2F(100.f, 100.f),
    D2D1::Point2F(500.f, 500.f),
pBlackBrush);

矩形

矩形使用如下的结构体表示。

struct D2D_RECT_F {
    FLOAT left;
    FLOAT top;
    FLOAT right;
    FLOAT bottom;
};

绘制矩形使用函数DrawRectangle,定义如下。第一个参数是D2D1_RECT_F结构,表示待绘制的矩形,它其他参数前面已经提到过,不再赘述。

void DrawRectangle(
    [ref] const D2D1_RECT_F &rect,
    [in] ID2D1Brush *brush,
    FLOAT strokeWidth =1.0f,
    [in, optional] ID2D1StrokeStyle *strokeStyle = NULL
);

下面的代码绘制一个矩形,该矩形的左上角坐标是(100, 100),右下角坐标是(500, 500)。

pRenderTarget->DrawRectangle(
    D2D1::RectF(100.f, 100.f, 500.f, 500.f),
    pBlackBrush
);

圆角矩形

D2D支持圆角矩形,先看看什么是圆角矩形。

可见圆角矩形就是常规矩形的改版,将尖角用圆弧代替即可。所以一个圆角矩形可以由一个普通矩形加上两个半径构造而成,这两个半径分别表示椭圆的X轴和Y轴,而这个椭圆则用来取代矩形的尖角。圆角矩形的定义如下:第一个参数是一个常规矩形,上面已经介绍过,后两个参数分别是椭圆的X轴半径和Y轴半径。

D2D1_ROUNDED_RECT RoundedRect(
    __in const D2D1_RECT_F &rect,
    FLOAT radiusX,
    FLOAT radiusY
);

绘制圆角矩形的函数定义如下,第一个参数是一个圆角矩形,后面的参数不再赘述。

void DrawRoundedRectangle(
    [ref] const D2D1_ROUNDED_RECT &roundedRect,
    [in] ID2D1Brush *brush,
    FLOAT strokeWidth =1.0f,
    [in, optional] ID2D1StrokeStyle *strokeStyle = NULL
);

下面的代码绘制一个圆角矩形,其左上角坐标是(100, 100),右下角坐标是(500, 500)。圆角的X轴半径是30,Y轴半径是50。

D2D1_ROUNDED_RECT roundedRect = D2D1::RoundedRect(
    D2D1::RectF(100.f, 100.f, 500.f, 500.f),
    30.0f,
    50.0f
);
pRenderTarget->DrawRoundedRectangle(roundedRect, pBlackBrush, 1.0f) ;

椭圆

椭圆由如下所示的结构体定义,第一个参数是椭圆的中心,后两个参数分别是X轴半径和Y轴半径。

struct D2D1_ELLIPSE {
    D2D1_POINT_2F point;
    FLOAT radiusX;
    FLOAT radiusY;
};

绘制椭圆的函数定义如下

void DrawEllipse(
    [ref] const D2D1_ELLIPSE &ellipse,
    [in] ID2D1Brush *brush,
    FLOAT strokeWidth =1.0f,
    [in, optional] ID2D1StrokeStyle *strokeStyle = NULL
);

下面的代码绘制一个椭圆,中心在(100, 100),长轴半径100,短轴半径50。

D2D1_ELLIPSE ellipse = D2D1::Ellipse(D2D1::Point2F(100.0f, 100.0f), 100.0f, 50.0f) ;
pRenderTarget->DrawEllipse(ellipse, pBlackBrush) ;

三角形

D2D没有提供绘制三角形的函数,不过我们可以使用DrawLine函数自己实现一个,代码很简单,对于给定的三个顶点,在每两个顶点之间调用上面的DrawLine函数即可。

void DrawTriangle(D2D1_POINT_2F p0, D2D1_POINT_2F p1, D2D1_POINT_2F p2,
    ID2D1HwndRenderTarget* pRenderTarget, 
    ID2D1Brush* brush,
    FLOAT strokeWidth =1.0f,
    ID2D1StrokeStyle *strokeStyle = NULL)
{
    pRenderTarget->DrawLine(p0, p1, brush);
    pRenderTarget->DrawLine(p1, p2, brush) ;
    pRenderTarget->DrawLine(p2, p0, brush) ;
}

D2D同样没有提供绘制圆的函数,因为圆是特殊的椭圆,可以通过绘制椭圆的函数来实现,只要使X轴半径和Y轴半径相等即可。

void DrawCircle(D2D1_POINT_2F center, FLOAT radius,
    ID2D1HwndRenderTarget* pRenderTarget,
    ID2D1Brush* brush,
    FLOAT strokeWidth =1.0f,
    ID2D1StrokeStyle *strokeStyle = NULL
)
{
    D2D1_ELLIPSE ellipse = D2D1::Ellipse(center, radius, radius) ;
    pRenderTarget->DrawEllipse(ellipse, brush) ;
}

线条的宽度

每个DrawXXX函数都有一个参数strokeWidth,代表的是线条的宽度,这个函数有个默认值1.0,所以通常情况下我们无需指定这个参数,但如果想让线条宽一些,那么可以设置成10.0,100.0等等,那么这个宽度是如何增长的呢?会影响图形的大小么?

通过实际绘图发现,这个宽度是向外增长的,也就是说线条的宽度不会影响图形的填充区域,比如一个10 x 10的矩形,当线条宽度是1.0时,它的填充面积是100,当线条宽度是10时,它的填充面积还是100。请看下图,黑色是线条颜色,黄色是填充色,可见无论线条多宽,黄色区域的面积始终不变。所以strokeWidth并不影响图形的填充区域。

Happy Coding!!!

== THE END ==

Direct2D教程(三)简单几何图形的更多相关文章

  1. SharpDX之Direct2D教程I——简单示例和Color(颜色)

    研究Direct2D已经有一段时间了,也写了一个系列的文章 Direct2D ,是基于Windows API Code Pack 1.1.在前文 Direct2D教程VIII——几何(Geometry ...

  2. SharpDX之Direct2D教程II——加载位图文件和保存位图文件

    本系列文章目录: SharpDX之Direct2D教程I——简单示例和Color(颜色) 绘制位图是绘制操作的不可缺少的一部分.在Direct2D中绘制位图,必须先利用WIC组件将位图加载到内存中,再 ...

  3. Direct2D教程(二)来看D2D世界中的Hello,World

    引子 任何一门语言的第一个教程几乎都是Hello,world.我们也不例外,但是这里不是教大家打印Hello,world,而是编写一个简单的D2D绘制程序,让大家对Direct2D的程序结构及编程方法 ...

  4. Direct2D教程(外篇)环境配置

    2014年世界杯首场淘汰赛马上开始了,闲着没事,整理以前的博客草稿打发时间,意外的发现这篇文章,本来是打算加入到Direct2D那个系列的,不知道为什么把它给遗漏了.环境配置,对于熟手来说,不是什么重 ...

  5. Direct2D教程VI——转换(Transform)

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  6. Direct2D教程II——绘制基本图形和线型(StrokeStyle)的设置详解

    目前,在博客园上,相对写得比较好的两个关于Direct2D的教程系列,分别是万一的Direct2D系列和zdd的Direct2D系列.有兴趣的网友可以去看看.本系列也是介绍Direct2D的教程,是基 ...

  7. Laravel教程 三:视图变量传递和Blade

    Laravel教程 三:视图变量传递和Blade 此文章为原创文章,未经同意,禁止转载. Blade 上一篇我们简单地说了Router,Views和Controllers的工作流程,这一次我就按照上一 ...

  8. NGUI系列教程三

    接下来我们再来看Progress Bar和Slider,对比参数我们可以发现,Progress Bar和slider的明显区别在于slider多一个Thumb选项,这里的Thumb就是我们拖动的时候点 ...

  9. Fastify 系列教程三 (验证、序列化和生命周期)

    Fastify 系列教程: Fastify 系列教程一 (路由和日志) Fastify 系列教程二 (中间件.钩子函数和装饰器) Fastify 系列教程三 (验证.序列化和生命周期) 验证 Fast ...

随机推荐

  1. HDU 3594 Cactus 有向仙人掌图判定

    题意 给出一个有向图,并给出仙人掌图的定义 图本身是强连通的 每条边属于且只属于一个环 判断输入的图是否是强连通的. 分析 杭电OJ上的数据比较弱,网上一些有明显错误的代码也能AC. 本着求真务实的精 ...

  2. SPOJ 1825 Free tour II 树分治

    题意: 给出一颗边带权的数,树上的点有黑色和白色.求一条长度最大且黑色节点不超过k个的最长路径,输出最长的长度. 分析: 说一下题目的坑点: 定义递归函数的前面要加inline,否则会RE.不知道这是 ...

  3. CodeForces 14D 树的直径 Two Paths

    给出一棵树,找出两条不相交即没有公共点的路径,使得两个路径的长度的乘积最大. 思路:枚举树中的边,将该边去掉,分成两棵树,分别求出这两棵树的直径,乘起来维护一个最大值即可. #include < ...

  4. MySQL数据库详解(二)执行SQL更新时,其底层经历了哪些操作?

    ​ 前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块.相信你还记得,一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后到达存储引擎. 那么,一条更 ...

  5. JS手风琴特效

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  6. Leetcode 456.132模式

    132模式 给定一个整数序列:a1, a2, ..., an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j < k 时,ai < ak < aj.设计 ...

  7. Flowerpot(单调队列)

    描述 Farmer John has been having trouble making his plants grow, and needs your help to water them pro ...

  8. pip installl安装包特别慢? 指定源进行安装

    指定源地址安装: pip install -i http://pypi.douban.com/simple/ packagename pip install -i http://pypi.tuna.t ...

  9. 开发者工具删除元素Delete Element

    开发者工具有个很好用的功能,通过删除元素,可以查看页面哪些元素比较特殊,同时也可以排除干扰.

  10. 九度oj 题目1177:查找

    题目描述: 读入一组字符串(待操作的),再读入一个int n记录记下来有几条命令,总共有2中命令:1.翻转  从下标为i的字符开始到i+len-1之间的字符串倒序:2.替换  命中如果第一位为1,用命 ...