drawing 2d geometries on 3d objects vectorworks
This browser is no longer supported.
Upgrade to Microsoft Border to take advantage of the latest features, security updates, and technical back up.
Geometries overview
This overview describes how to create and use ID2D1Geometry objects to define and manipulate 2D figures. It contains the following sections.
What is a Direct2D geometry?
A Direct2D geometry is an ID2D1Geometry object. This object can be a simple geometry (ID2D1RectangleGeometry, ID2D1RoundedRectangleGeometry, or ID2D1EllipseGeometry), a path geometry (ID2D1PathGeometry), or a composite geometry (ID2D1GeometryGroup and ID2D1TransformedGeometry).
Direct2D geometries enable you to draw two-dimensional figures and offer many uses, such equally defining hitting-exam regions, prune regions, and even blitheness paths.
Direct2D geometries are immutable and device-independent resources created by ID2D1Factory. Generally, you should create geometries once and proceed them for the life of the application, or until they have to exist inverse. For more information about device-independent and device-dependent resource, meet the Resource Overview.
The following sections describe the different kinds of geometries.
Simple geometries
Simple geometries include ID2D1RectangleGeometry, ID2D1RoundedRectangleGeometry, and ID2D1EllipseGeometry objects, and can be used to create bones geometric figures, such every bit rectangles, rounded rectangles, circles, and ellipses.
To create a unproblematic geometry, use one of the ID2D1Factory::Create<geometryType>Geometry methods. These methods create an object of the specified type. For example, to create a rectangle, telephone call ID2D1Factory::CreateRectangleGeometry, which returns an ID2D1RectangleGeometry object; to create a rounded rectangle, call ID2D1Factory::CreateRoundedRectangleGeometry, which returns an ID2D1RoundedRectangleGeometry object, and and so on.
The post-obit code case calls the CreateEllipseGeometry method, passing in an ellipse structure with the center fix to (100, 100), x-radius to 100, and y-radius to 50. Then, information technology calls DrawGeometry, passing in the returned ellipse geometry, a arrow to a black ID2D1SolidColorBrush, and a stroke width of five. The following illustration shows the output from the lawmaking example.
ID2D1EllipseGeometry *m_pEllipseGeometry;
if (SUCCEEDED(hr)) { 60 minutes = m_pD2DFactory->CreateEllipseGeometry( D2D1::Ellipse(D2D1::Point2F(100.f, lx.f), 100.f, fifty.f), &m_pEllipseGeometry ); }
m_pRenderTarget->DrawGeometry(m_pEllipseGeometry, m_pBlackBrush, five);
To describe the outline of any geometry, use the DrawGeometry method. To paint its interior, use the FillGeometry method.
Path geometries
Path geometries are represented by the ID2D1PathGeometry interface. These objects can be used to depict complex geometric figures composed of segments such equally arcs, curves, and lines. The following analogy shows a drawing created by using path geometry.
For more information and examples, meet the Path Geometries Overview.
Composite geometries
A composite geometry is a geometry grouped or combined with another geometry object, or with a transform. Composite geometries include ID2D1TransformedGeometry and ID2D1GeometryGroup objects.
Geometry groups
Geometry groups are a user-friendly way to grouping several geometries at the same time and then all figures of several distinct geometries are concatenated into ane. To create a ID2D1GeometryGroup object, phone call the CreateGeometryGroup method on the ID2D1Factory object, passing in the fillMode with possible values of D2D1_FILL_MODE_ALTERNATE (alternate) and D2D1_FILL_MODE_WINDING, an assortment of geometry objects to add to the geometry group, and the number of elements in this assortment.
The following code example beginning declares an array of geometry objects. These objects are four concentric circles that accept the post-obit radii: 25, 50, 75, and 100. So call the CreateGeometryGroup on the ID2D1Factory object, passing in D2D1_FILL_MODE_ALTERNATE, an array of geometry objects to add to the geometry group, and the number of elements in this assortment.
ID2D1Geometry *ppGeometries[] = { m_pEllipseGeometry1, m_pEllipseGeometry2, m_pEllipseGeometry3, m_pEllipseGeometry4 }; 60 minutes = m_pD2DFactory->CreateGeometryGroup( D2D1_FILL_MODE_ALTERNATE, ppGeometries, ARRAYSIZE(ppGeometries), &m_pGeoGroup_AlternateFill ); if (SUCCEEDED(hour)) { hr = m_pD2DFactory->CreateGeometryGroup( D2D1_FILL_MODE_WINDING, ppGeometries, ARRAYSIZE(ppGeometries), &m_pGeoGroup_WindingFill ); }
The following analogy shows the results of rendering the ii group geometries from the case.
Transformed geometries
There are multiple ways to transform a geometry. You can use the SetTransform method of a render target to transform everything that the render target draws, or you lot can acquaintance a transform directly with a geometry by using the CreateTransformedGeometry method to create an ID2D1TransformedGeometry.
The method that you should use depends on the effect that you desire. When you use the return target to transform and and then render a geometry, the transform affects everything about the geometry, including the width of whatever stroke that y'all have practical. On the other manus, when you utilise an ID2D1TransformedGeometry, the transform affects but the coordinates that draw the shape. The transformation volition not affect the stroke thickness when the geometry is drawn.
The post-obit example creates an ID2D1RectangleGeometry, and so draws information technology without transforming it. Information technology produces the output shown in the following illustration.
hour = m_pD2DFactory->CreateRectangleGeometry( D2D1::RectF(150.f, 150.f, 200.f, 200.f), &m_pRectangleGeometry );
// Describe the untransformed rectangle geometry. m_pRenderTarget->DrawGeometry(m_pRectangleGeometry, m_pBlackBrush, 1);
The next case uses the render target to scale the geometry by a factor of 3, then draws information technology. The following analogy shows the effect of drawing the rectangle without the transform and with the transform. Detect that the stroke is thicker subsequently the transform, even though the stroke thickness is 1.
// Transform the render target, then draw the rectangle geometry over again. m_pRenderTarget->SetTransform( D2D1::Matrix3x2F::Scale( D2D1::SizeF(three.f, 3.f), D2D1::Point2F(175.f, 175.f)) ); m_pRenderTarget->DrawGeometry(m_pRectangleGeometry, m_pBlackBrush, 1);
The next example uses the CreateTransformedGeometry method to scale the geometry by a cistron of 3, then draws it. It produces the output shown in the post-obit illustration. Notice that, although the rectangle is larger, its stroke hasn't increased.
// Create a geometry that is a scaled version // of m_pRectangleGeometry. // The new geometry is scaled by a factory of iii // from the center of the geometry, (35, 35). hour = m_pD2DFactory->CreateTransformedGeometry( m_pRectangleGeometry, D2D1::Matrix3x2F::Scale( D2D1::SizeF(3.f, three.f), D2D1::Point2F(175.f, 175.f)), &m_pTransformedGeometry );
// Supplant the previous render target transform. m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); // Describe the transformed geometry. m_pRenderTarget->DrawGeometry(m_pTransformedGeometry, m_pBlackBrush, 1);
Geometries equally masks
You can use an ID2D1Geometry object equally a geometric mask when you call the PushLayer method. The geometric mask specifies the surface area of the layer that is composited into the render target. For more information, come across the Geometric Masks section of the Layers Overview.
Geometric operations
The ID2D1Geometry interface provides several geometric operations that you lot tin apply to manipulate and measure out geometric figures. For example, you can use them to calculate and render their bounds, compare to see how 1 geometry is spatially related to another (useful for hit testing), calculate the areas and lengths, and more. The following table describes the common geometric operations.
Operation | Method |
---|---|
Combine | CombineWithGeometry |
Bounds/ Widened Bounds/Remember Premises, Dingy Region update | Widen, GetBounds, GetWidenedBounds |
Hitting Testing | FillContainsPoint, StrokeContainsPoint |
Stroke | StrokeContainsPoint |
Comparing | CompareWithGeometry |
Simplification (removes arcs and quadratic Bezier curves) | Simplify |
Tessellation | Tessellate |
Outline (remove intersection) | Outline |
Calculate the surface area or length of a geometry | ComputeArea, ComputeLength, ComputePointAtLength |
Combining geometries
To combine ane geometry with some other, call the ID2D1Geometry::CombineWithGeometry method. When yous combine the geometries, you specify i of the four ways to perform the combine operation: D2D1_COMBINE_MODE_UNION (union), D2D1_COMBINE_MODE_INTERSECT (intersect), D2D1_COMBINE_MODE_XOR (xor), and D2D1_COMBINE_MODE_EXCLUDE (exclude). The following code example shows two circles that are combined by using the union combine way, where the first circle has the heart signal of (75, 75) and the radius of 50, and the second circle has the center point of (125, 75) and the radius of 50.
HRESULT 60 minutes = S_OK; ID2D1GeometrySink *pGeometrySink = Null; // Create the first ellipse geometry to merge. const D2D1_ELLIPSE circle1 = D2D1::Ellipse( D2D1::Point2F(75.0f, 75.0f), 50.0f, 50.0f ); hr = m_pD2DFactory->CreateEllipseGeometry( circle1, &m_pCircleGeometry1 ); if (SUCCEEDED(60 minutes)) { // Create the second ellipse geometry to merge. const D2D1_ELLIPSE circle2 = D2D1::Ellipse( D2D1::Point2F(125.0f, 75.0f), l.0f, 50.0f ); hr = m_pD2DFactory->CreateEllipseGeometry(circle2, &m_pCircleGeometry2); } if (SUCCEEDED(hour)) { // // Utilize D2D1_COMBINE_MODE_UNION to combine the geometries. // hr = m_pD2DFactory->CreatePathGeometry(&m_pPathGeometryUnion); if (SUCCEEDED(hr)) { hr = m_pPathGeometryUnion->Open(&pGeometrySink); if (SUCCEEDED(hr)) { hour = m_pCircleGeometry1->CombineWithGeometry( m_pCircleGeometry2, D2D1_COMBINE_MODE_UNION, NULL, NULL, pGeometrySink ); } if (SUCCEEDED(60 minutes)) { hr = pGeometrySink->Close(); } SafeRelease(&pGeometrySink); } }
The following analogy shows two circles combined with a combine mode of union.
For illustrations of all the combine modes, see the D2D1_COMBINE_MODE enumeration.
Widen
The Widen method generates a new geometry whose make full is equivalent to stroking the existing geometry, and so writes the result to the specified ID2D1SimplifiedGeometrySink object. The following code example calls Open up on the ID2D1PathGeometry object. If Open succeeds, it calls Widen on the geometry object.
ID2D1GeometrySink *pGeometrySink = Null; hr = pPathGeometry->Open up(&pGeometrySink); if (SUCCEEDED(hr)) { hr = pGeometry->Widen( strokeWidth, pIStrokeStyle, pWorldTransform, pGeometrySink );
Tessellate
The Tessellate method creates a fix of clockwise-wound triangles that embrace the geometry after it is transformed past using the specified matrix and flattened past using the specified tolerance. The following lawmaking instance uses Tessellate to create a list of triangles that represent pPathGeometry. The triangles are stored in an ID2D1Mesh, pMesh, then transferred to a grade member, m_pStrokeMesh, for later use when rendering.
ID2D1Mesh *pMesh = NULL; hr = m_pRT->CreateMesh(&pMesh); if (SUCCEEDED(hr)) { ID2D1TessellationSink *pSink = Nada; 60 minutes = pMesh->Open(&pSink); if (SUCCEEDED(hr)) { hr = pPathGeometry->Tessellate( NULL, // world transform (already handled in Widen) pSink ); if (SUCCEEDED(hr)) { hr = pSink->Close(); if (SUCCEEDED(hr)) { SafeReplace(&m_pStrokeMesh, pMesh); } } pSink->Release(); } pMesh->Release(); }
FillContainsPoint and StrokeContainsPoint
The FillContainsPoint method indicates whether the area filled by the geometry contains the specified indicate. You tin can utilize this method to do hit testing. The following lawmaking instance calls FillContainsPoint on an ID2D1EllipseGeometry object, passing in a point at (0,0) and an Identity matrix.
BOOL containsPoint1; hr = m_pCircleGeometry1->FillContainsPoint( D2D1::Point2F(0,0), D2D1::Matrix3x2F::Identity(), &containsPoint1 ); if (SUCCEEDED(hr)) { // Procedure containsPoint. }
The StrokeContainsPoint method determines whether the geometry's stroke contains the specified bespeak. You can utilize this method to practise hit testing. The following code instance uses StrokeContainsPoint.
BOOL containsPoint; hour = m_pCircleGeometry1->StrokeContainsPoint( D2D1::Point2F(0,0), 10, // stroke width Zero, // stroke style NULL, // world transform &containsPoint ); if (SUCCEEDED(hr)) { // Procedure containsPoint. }
Simplify
The Simplify method removes arcs and quadratic Bezier curves from a specified geometry. So, the resulting geometry contains only lines and, optionally, cubic Bezier curves. The post-obit lawmaking instance uses Simplify to transform a geometry with Bezier curves into a geometry that contains simply line segments.
HRESULT D2DFlatten( ID2D1Geometry *pGeometry, float flatteningTolerance, ID2D1Geometry **ppGeometry ) { HRESULT hr; ID2D1Factory *pFactory = Aught; pGeometry->GetFactory(&pFactory); ID2D1PathGeometry *pPathGeometry = Goose egg; 60 minutes = pFactory->CreatePathGeometry(&pPathGeometry); if (SUCCEEDED(hr)) { ID2D1GeometrySink *pSink = NULL; hr = pPathGeometry->Open(&pSink); if (SUCCEEDED(hr)) { hr = pGeometry->Simplify( D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES, Aught, // globe transform flatteningTolerance, pSink ); if (SUCCEEDED(hr)) { hr = pSink->Close(); if (SUCCEEDED(hr)) { *ppGeometry = pPathGeometry; (*ppGeometry)->AddRef(); } } pSink->Release(); } pPathGeometry->Release(); } pFactory->Release(); return hr; }
ComputeLength and ComputeArea
The ComputeLength method calculates the length of the specified geometry if each segment were unrolled into a line. This includes the implicit closing segment if the geometry is closed. The following code example uses ComputeLength to compute the length of a specified circle (m_pCircleGeometry1).
bladder length; // Compute the area of circle1 hr = m_pCircleGeometry1->ComputeLength( D2D1::IdentityMatrix(), &length ); if (SUCCEEDED(hr)) { // Process the length of the geometry. }
The ComputeArea method calculates the expanse of the specified geometry. The following code instance uses ComputeArea to compute the area of a specified circle (m_pCircleGeometry1).
float surface area; // Compute the area of circle1 hr = m_pCircleGeometry1->ComputeArea( D2D1::IdentityMatrix(), &area );
CompareWithGeometry
The CompareWithGeometry method describes the intersection between the geometry that calls this method and the specified geometry. The possible values for intersection include D2D1_GEOMETRY_RELATION_DISJOINT (disjoint), D2D1_GEOMETRY_RELATION_IS_CONTAINED (is contained), D2D1_GEOMETRY_RELATION_CONTAINS (contains), and D2D1_GEOMETRY_RELATION_OVERLAP (overlap). "disjoint" ways that ii geometry fills do non intersect at all. "is contained" means that the geometry is completely contained past the specified geometry. "contains" means that the geometry completely contains the specified geometry, and "overlap" means the two geometries overlap only neither completely contains the other.
The following code example shows how to compare two circles that have the aforementioned radius of 50 simply are offset past fifty.
HRESULT hr = S_OK; ID2D1GeometrySink *pGeometrySink = Nix; // Create the beginning ellipse geometry to merge. const D2D1_ELLIPSE circle1 = D2D1::Ellipse( D2D1::Point2F(75.0f, 75.0f), 50.0f, fifty.0f ); hr = m_pD2DFactory->CreateEllipseGeometry( circle1, &m_pCircleGeometry1 ); if (SUCCEEDED(hr)) { // Create the 2d ellipse geometry to merge. const D2D1_ELLIPSE circle2 = D2D1::Ellipse( D2D1::Point2F(125.0f, 75.0f), l.0f, 50.0f ); hr = m_pD2DFactory->CreateEllipseGeometry(circle2, &m_pCircleGeometry2); }
D2D1_GEOMETRY_RELATION result = D2D1_GEOMETRY_RELATION_UNKNOWN; // Compare circle1 with circle2 hr = m_pCircleGeometry1->CompareWithGeometry( m_pCircleGeometry2, D2D1::IdentityMatrix(), 0.1f, &result ); if (SUCCEEDED(60 minutes)) { static const WCHAR szGeometryRelation[] = L"Two circles overlap."; m_pRenderTarget->SetTransform(D2D1::IdentityMatrix()); if (effect == D2D1_GEOMETRY_RELATION_OVERLAP) { m_pRenderTarget->DrawText( szGeometryRelation, ARRAYSIZE(szGeometryRelation) - 1, m_pTextFormat, D2D1::RectF(25.0f, 160.0f, 200.0f, 300.0f), m_pTextBrush ); } }
Outline
The Outline method computes the outline of the geometry (a version of the geometry in which no figure crosses itself or whatever other figure) and writes the consequence to an ID2D1SimplifiedGeometrySink. The post-obit lawmaking example uses Outline to construct an equivalent geometry without any cocky-intersections. It uses the default flattening tolerance.
HRESULT D2DOutline( ID2D1Geometry *pGeometry, ID2D1Geometry **ppGeometry ) { HRESULT hr; ID2D1Factory *pFactory = Zero; pGeometry->GetFactory(&pFactory); ID2D1PathGeometry *pPathGeometry = NULL; hr = pFactory->CreatePathGeometry(&pPathGeometry); if (SUCCEEDED(hr)) { ID2D1GeometrySink *pSink = NULL; hr = pPathGeometry->Open(&pSink); if (SUCCEEDED(hr)) { hour = pGeometry->Outline(NULL, pSink); if (SUCCEEDED(hr)) { hr = pSink->Close(); if (SUCCEEDED(hr)) { *ppGeometry = pPathGeometry; (*ppGeometry)->AddRef(); } } pSink->Release(); } pPathGeometry->Release(); } pFactory->Release(); return hour; }
GetBounds and GetWidenedBounds
The GetBounds method retrieves the bounds of the geometry. The following code instance uses GetBounds to retrieve the premises of a specified circle (m_pCircleGeometry1).
D2D1_RECT_F bounds; hr = m_pCircleGeometry1->GetBounds( D2D1::IdentityMatrix(), &bounds ); if (SUCCEEDED(hr)) { // Call up the premises. }
The GetWidenedBounds method retrieves the bounds of the geometry afterwards information technology is widened by the specified stroke width and style and transformed past the specified matrix. The following code example uses GetWidenedBounds to recollect the premises of a specified circumvolve (m_pCircleGeometry1) after information technology is widened by the specified stroke width.
float dashes[] = {1.f, 1.f, 2.f, 3.f, 5.f}; m_pD2DFactory->CreateStrokeStyle( D2D1::StrokeStyleProperties( D2D1_CAP_STYLE_FLAT, D2D1_CAP_STYLE_FLAT, D2D1_CAP_STYLE_ROUND, D2D1_LINE_JOIN_ROUND, // lineJoin 10.f, //miterLimit D2D1_DASH_STYLE_CUSTOM, 0.f //dashOffset ), dashes, ARRAYSIZE(dashes)-one, &m_pStrokeStyle );
D2D1_RECT_F bounds1; hr = m_pCircleGeometry1->GetWidenedBounds( five.0, m_pStrokeStyle, D2D1::IdentityMatrix(), &bounds1 ); if (SUCCEEDED(hr)) { // Retrieve the widened bounds. }
ComputePointAtLength
The ComputePointAtLength method calculates the betoken and tangent vector at the specified distance forth the geometry. The following code case uses ComputePointAtLength.
D2D1_POINT_2F point; D2D1_POINT_2F tangent; hr = m_pCircleGeometry1->ComputePointAtLength( 10, Nil, &indicate, &tangent);
-
Path Geometries Overview
-
Direct2D Reference
Source: https://docs.microsoft.com/en-us/windows/win32/direct2d/direct2d-geometries-overview
0 Response to "drawing 2d geometries on 3d objects vectorworks"
Post a Comment