Add DrawArcSegment() GAL method, to support drawing outlined arcs
This commit is contained in:
parent
0be56451b1
commit
3208d24ad4
|
@ -199,6 +199,8 @@ void CAIRO_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPo
|
|||
|
||||
cairo_save( currentContext );
|
||||
|
||||
cairo_set_source_rgba( currentContext, strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
cairo_translate( currentContext, aStartPoint.x, aStartPoint.y );
|
||||
cairo_rotate( currentContext, lineAngle );
|
||||
|
||||
|
@ -255,6 +257,51 @@ void CAIRO_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double aS
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle,
|
||||
double aEndAngle, double aWidth )
|
||||
{
|
||||
SWAP( aStartAngle, >, aEndAngle );
|
||||
|
||||
if( isFillEnabled )
|
||||
{
|
||||
cairo_arc( currentContext, aCenterPoint.x, aCenterPoint.y, aRadius, aStartAngle, aEndAngle );
|
||||
cairo_set_source_rgba( currentContext, fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
cairo_stroke( currentContext );
|
||||
}
|
||||
else
|
||||
{
|
||||
double width = aWidth / 2.0;
|
||||
VECTOR2D startPoint( cos( aStartAngle ) * aRadius,
|
||||
sin( aStartAngle ) * aRadius );
|
||||
VECTOR2D endPoint( cos( aEndAngle ) * aRadius,
|
||||
sin( aEndAngle ) * aRadius );
|
||||
|
||||
cairo_save( currentContext );
|
||||
|
||||
cairo_set_source_rgba( currentContext, strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
cairo_translate( currentContext, aCenterPoint.x, aCenterPoint.y );
|
||||
|
||||
cairo_new_sub_path( currentContext );
|
||||
cairo_arc( currentContext, 0, 0, aRadius - width, aStartAngle, aEndAngle );
|
||||
|
||||
cairo_new_sub_path( currentContext );
|
||||
cairo_arc( currentContext, 0, 0, aRadius + width, aStartAngle, aEndAngle );
|
||||
|
||||
cairo_new_sub_path( currentContext );
|
||||
cairo_arc_negative( currentContext, startPoint.x, startPoint.y, width, aStartAngle, aStartAngle + M_PI );
|
||||
|
||||
cairo_new_sub_path( currentContext );
|
||||
cairo_arc( currentContext, endPoint.x, endPoint.y, width, aEndAngle, aEndAngle + M_PI );
|
||||
|
||||
cairo_restore( currentContext );
|
||||
flushPath();
|
||||
}
|
||||
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
// Calculate the diagonal points
|
||||
|
|
|
@ -589,6 +589,96 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle,
|
||||
double aEndAngle, double aWidth )
|
||||
{
|
||||
if( aRadius <= 0 )
|
||||
return;
|
||||
|
||||
// Swap the angles, if start angle is greater than end angle
|
||||
SWAP( aStartAngle, >, aEndAngle );
|
||||
|
||||
const double alphaIncrement = 2.0 * M_PI / CIRCLE_POINTS;
|
||||
|
||||
Save();
|
||||
currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0 );
|
||||
|
||||
if( isStrokeEnabled )
|
||||
{
|
||||
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
double width = aWidth / 2.0;
|
||||
VECTOR2D startPoint( cos( aStartAngle ) * aRadius,
|
||||
sin( aStartAngle ) * aRadius );
|
||||
VECTOR2D endPoint( cos( aEndAngle ) * aRadius,
|
||||
sin( aEndAngle ) * aRadius );
|
||||
|
||||
drawStrokedSemiCircle( startPoint, width, aStartAngle + M_PI );
|
||||
drawStrokedSemiCircle( endPoint, width, aEndAngle );
|
||||
|
||||
VECTOR2D pOuter( cos( aStartAngle ) * ( aRadius + width ),
|
||||
sin( aStartAngle ) * ( aRadius + width ) );
|
||||
|
||||
VECTOR2D pInner( cos( aStartAngle ) * ( aRadius - width ),
|
||||
sin( aStartAngle ) * ( aRadius - width ) );
|
||||
|
||||
double alpha;
|
||||
|
||||
for( alpha = aStartAngle + alphaIncrement; alpha <= aEndAngle; alpha += alphaIncrement )
|
||||
{
|
||||
VECTOR2D pNextOuter( cos( alpha ) * ( aRadius + width ),
|
||||
sin( alpha ) * ( aRadius + width ) );
|
||||
VECTOR2D pNextInner( cos( alpha ) * ( aRadius - width ),
|
||||
sin( alpha ) * ( aRadius - width ) );
|
||||
|
||||
DrawLine( pOuter, pNextOuter );
|
||||
DrawLine( pInner, pNextInner );
|
||||
|
||||
pOuter = pNextOuter;
|
||||
pInner = pNextInner;
|
||||
}
|
||||
|
||||
// Draw the last missing part
|
||||
if( alpha != aEndAngle )
|
||||
{
|
||||
VECTOR2D pLastOuter( cos( aEndAngle ) * ( aRadius + width ),
|
||||
sin( aEndAngle ) * ( aRadius + width ) );
|
||||
VECTOR2D pLastInner( cos( aEndAngle ) * ( aRadius - width ),
|
||||
sin( aEndAngle ) * ( aRadius - width ) );
|
||||
|
||||
DrawLine( pOuter, pLastOuter );
|
||||
DrawLine( pInner, pLastInner );
|
||||
}
|
||||
}
|
||||
|
||||
if( isFillEnabled )
|
||||
{
|
||||
currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
SetLineWidth( aWidth );
|
||||
|
||||
VECTOR2D p( cos( aStartAngle ) * aRadius, sin( aStartAngle ) * aRadius );
|
||||
double alpha;
|
||||
|
||||
for( alpha = aStartAngle + alphaIncrement; alpha <= aEndAngle; alpha += alphaIncrement )
|
||||
{
|
||||
VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
|
||||
DrawLine( p, p_next );
|
||||
|
||||
p = p_next;
|
||||
}
|
||||
|
||||
// Draw the last missing part
|
||||
if( alpha != aEndAngle )
|
||||
{
|
||||
VECTOR2D p_last( cos( aEndAngle ) * aRadius, sin( aEndAngle ) * aRadius );
|
||||
DrawLine( p, p_last );
|
||||
}
|
||||
}
|
||||
|
||||
Restore();
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
// Compute the diagonal points of the rectangle
|
||||
|
|
|
@ -115,6 +115,10 @@ public:
|
|||
virtual void DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
double aStartAngle, double aEndAngle ) override;
|
||||
|
||||
/// @copydoc GAL::DrawArcSegment()
|
||||
virtual void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
double aStartAngle, double aEndAngle, double aWidth ) override;
|
||||
|
||||
/// @copydoc GAL::DrawRectangle()
|
||||
virtual void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) override;
|
||||
|
||||
|
|
|
@ -133,6 +133,23 @@ public:
|
|||
virtual void
|
||||
DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle, double aEndAngle ) {};
|
||||
|
||||
/**
|
||||
* @brief Draw an arc segment.
|
||||
*
|
||||
* This method differs from DrawArc() in what happens when fill/stroke are on or off.
|
||||
* DrawArc() draws a "pie piece" when fill is turned on, and a thick stroke when fill is off.
|
||||
* DrawArcSegment() with fill *on* behaves like DrawArc() with fill *off*.
|
||||
* DrawArcSegment() with fill *off* draws the outline of what it would have drawn with fill on.
|
||||
*
|
||||
* @param aCenterPoint is the center point of the arc.
|
||||
* @param aRadius is the arc radius.
|
||||
* @param aStartAngle is the start angle of the arc.
|
||||
* @param aEndAngle is the end angle of the arc.
|
||||
*/
|
||||
virtual void
|
||||
DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle,
|
||||
double aEndAngle, double aWidth ) {};
|
||||
|
||||
/**
|
||||
* @brief Draw a rectangle.
|
||||
*
|
||||
|
|
|
@ -129,6 +129,10 @@ public:
|
|||
virtual void DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
double aStartAngle, double aEndAngle ) override;
|
||||
|
||||
/// @copydoc GAL::DrawArcSegment()
|
||||
virtual void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
double aStartAngle, double aEndAngle, double aWidth ) override;
|
||||
|
||||
/// @copydoc GAL::DrawRectangle()
|
||||
virtual void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) override;
|
||||
|
||||
|
|
Loading…
Reference in New Issue