• Direct2D教程(三)简单几何图形


    从本章开始,我们介绍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提供的样式,也可以自己定义样式。由于最后两个参数有默认值,所以我们通常只提供前三个参数即可。最后两个参数在下面的绘图函数中都有出现。

    virtual void DrawLine(
        D2D1_POINT_2F point0,
        D2D1_POINT_2F point1,
        [in] ID2D1Brush *brush,
        FLOAT strokeWidth = 1.0f,
        [in, optional] ID2D1StrokeStyle *strokeStyle = NULL
    ) = 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 ==

    作者:zdd
    出处:http://www.cnblogs.com/graphics/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    vue-cli3中热更新失效,修改完代码之后需要手动刷新页面才能看到改变,解决办法
    数组中的数据项包含逗号则需在首尾拼接中括号[]来区分每一项,最后数组转为字符串,以及数据恢复
    组件之间的拖拽
    工作心得
    Vue重点知识
    vue-router路由
    利用注解和反射,将Bean枚举字段的值填入相应的字段中,并转化为fastjson返回前台
    db2 获取自增主键的方法
    mybatis注解@selectKey对于db2数据库的使用
    @InsertProvider 根据bean属性,自动生成插入sql语句
  • 原文地址:https://www.cnblogs.com/graphics/p/1963563.html
Copyright © 2020-2023  润新知