如何在C ++ / Direct X中绘制圆的一部分?

时间:2016-03-17 20:03:42

标签: c++ directx direct3d direct2d

使用直接x(直接3d或2d)我想通过指定theta,起点和终点来绘制圆的一部分。例如,我想将源x / y坐标设置为0/0,将θ设置为20度,将结束x / y设置为200/200以绘制圆的一部分。

平坦的2D圆形或更确切地说它的部分可以做到。有任何想法吗?谢谢。

我已经添加了代码,但是这已经经过了很多修改,但它没有用,所以我从那时起就没有看过它。

D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &pD2DFactory);


RECT rc = {dx,dy,dx+dw,dy+dh};
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
   D2D1_RENDER_TARGET_TYPE_DEFAULT,
   D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,D2D1_ALPHA_MODE_IGNORE),
   0,0, D2D1_RENDER_TARGET_USAGE_NONE, D2D1_FEATURE_LEVEL_DEFAULT);

pD2DFactory->CreateDCRenderTarget(&props,&pD2DDCRenderTarget);
pD2DDCRenderTarget->BindDC(hDC,&rc);
pD2DDCRenderTarget->CreateBitmap (D2D1::SizeU(sw,sh),(void*)p_bmp,pitch,
        D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,D2D1_ALPHA_MODE_IGNORE)),
        &pD2DBitmap);

pD2DDCRenderTarget->BeginDraw();    
pD2DDCRenderTarget->DrawBitmap(pD2DBitmap,
        D2D1::RectF((FLOAT)dx,(FLOAT)dy,(FLOAT)dw,(FLOAT)dh),1.0,D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
        D2D1::RectF((FLOAT)sx,(FLOAT)sy,(FLOAT)sw,(FLOAT)sh));  
pD2DDCRenderTarget->EndDraw();      

SafeRelease(&pD2DBitmap);
SafeRelease(&pD2DDCRenderTarget);       
SafeRelease(&pD2DFactory);  

1 个答案:

答案 0 :(得分:2)

在Direct2D中,您希望使用几何来完成此任务。以下是如何执行此操作的示例。下面的函数使用三个点创建路径几何:p0是起点,p1是终点,p2只是p1围绕p0旋转θ度。下面的函数要求thetaDegrees是<= 180度。

在Direct3D中,您可以使用三角形风扇/条带/列表来近似圆弧;三角形越多,形状越平滑。 Direct2D会为您解决所有这些问题。

void DrawArc(
    ID2D1Factory* factory, 
    ID2D1DeviceContext* context,
    ID2D1Brush* brush,
    D2D1_POINT_2F p0, 
    D2D1_POINT_2F p1, 
    float thetaDegrees
    )
{
    // rotate p1 around p0 by theta degrees
    D2D1_POINT_2F p2 = D2D1::Matrix3x2F::Rotation(thetaDegrees, p0).TransformPoint(p1);

    // distance between p0 and p1 is the radius
    float dx = p1.x - p0.x;
    float dy = p1.y - p0.y;
    float radius = std::sqrt(dx * dx + dy * dy);

    ComPtr<ID2D1PathGeometry> pathGeometry;
    factory->CreatePathGeometry(&pathGeometry);

    ComPtr<ID2D1GeometrySink> geometrySink;
    pathGeometry->Open(&geometrySink);

    // begin figure at p0
    geometrySink->BeginFigure(p0, D2D1_FIGURE_BEGIN_FILLED);

    // draw a line between p0 and p1
    geometrySink->AddLine(p1);

    // draw an arc segment between p1 and p2
    geometrySink->AddArc(D2D1::ArcSegment(
        p2,
        D2D1::SizeF(radius, radius),
        0.0f,
        D2D1_SWEEP_DIRECTION_CLOCKWISE,
        D2D1_ARC_SIZE_SMALL
        ));

    // end the figure in a closed state (automatically adds a line from p2 back to p0)
    geometrySink->EndFigure(D2D1_FIGURE_END_CLOSED);
    geometrySink->Close();

    // fill the interior of the geometry with the given brush
    context->FillGeometry(pathGeometry.Get(), brush);
}