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 ==


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM