diff options
| author | Yuval Adam <yuval@y3xz.com> | 2015-03-13 12:24:02 +0200 |
|---|---|---|
| committer | Yuval Adam <yuval@y3xz.com> | 2015-03-13 12:24:02 +0200 |
| commit | 788db64b8642bf31de6930d18a62177c64163ee0 (patch) | |
| tree | 38e8291d1fcfceac7ad2a393ad74396ed6453d24 /grlib/circle.c | |
| parent | c686407d271989d5c4bcc1b3c4f5bb6fcd1846a8 (diff) | |
Add grlib, fixes #5
Diffstat (limited to 'grlib/circle.c')
| -rw-r--r-- | grlib/circle.c | 564 |
1 files changed, 564 insertions, 0 deletions
diff --git a/grlib/circle.c b/grlib/circle.c new file mode 100644 index 0000000..a2d934f --- /dev/null +++ b/grlib/circle.c @@ -0,0 +1,564 @@ +//*****************************************************************************
+//
+// circle.c - Routines for drawing circles.
+//
+// Copyright (c) 2007-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Graphics Library.
+//
+//*****************************************************************************
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "driverlib/debug.h"
+#include "grlib/grlib.h"
+
+//*****************************************************************************
+//
+//! \addtogroup primitives_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! Draws a circle.
+//!
+//! \param pContext is a pointer to the drawing context to use.
+//! \param i32X is the X coordinate of the center of the circle.
+//! \param i32Y is the Y coordinate of the center of the circle.
+//! \param i32Radius is the radius of the circle.
+//!
+//! This function draws a circle, utilizing the Bresenham circle drawing
+//! algorithm. The extent of the circle is from \e i32X - \e i32Radius to
+//! \e i32X + \e i32Radius and \e i32Y - \e i32Radius to \e i32Y +
+//! \e i32Radius, inclusive.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+GrCircleDraw(const tContext *pContext, int32_t i32X, int32_t i32Y,
+ int32_t i32Radius)
+{
+ int_fast32_t i32A, i32B, i32D, i32X1, i32Y1;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(pContext);
+
+ //
+ // Initialize the variables that control the Bresenham circle drawing
+ // algorithm.
+ //
+ i32A = 0;
+ i32B = i32Radius;
+ i32D = 3 - (2 * i32Radius);
+
+ //
+ // Loop until the A delta is greater than the B delta, meaning that the
+ // entire circle has been drawn.
+ //
+ while(i32A <= i32B)
+ {
+ //
+ // Determine the row when subtracting the A delta.
+ //
+ i32Y1 = i32Y - i32A;
+
+ //
+ // See if this row is within the clipping region.
+ //
+ if((i32Y1 >= pContext->sClipRegion.i16YMin) &&
+ (i32Y1 <= pContext->sClipRegion.i16YMax))
+ {
+ //
+ // Determine the column when subtracting the B delta.
+ //
+ i32X1 = i32X - i32B;
+
+ //
+ // If this column is within the clipping region, then draw a pixel
+ // at that position.
+ //
+ if((i32X1 >= pContext->sClipRegion.i16XMin) &&
+ (i32X1 <= pContext->sClipRegion.i16XMax))
+ {
+ GrPixelDraw(pContext, i32X1, i32Y1);
+ }
+
+ //
+ // Determine the column when adding the B delta.
+ //
+ i32X1 = i32X + i32B;
+
+ //
+ // If this column is within the clipping region, then draw a pixel
+ // at that position.
+ //
+ if((i32X1 >= pContext->sClipRegion.i16XMin) &&
+ (i32X1 <= pContext->sClipRegion.i16XMax))
+ {
+ GrPixelDraw(pContext, i32X1, i32Y1);
+ }
+ }
+
+ //
+ // Determine the row when adding the A delta.
+ //
+ i32Y1 = i32Y + i32A;
+
+ //
+ // See if this row is within the clipping region, and the A delta is
+ // not zero (otherwise, it will be the same row as when the A delta was
+ // subtracted).
+ //
+ if((i32Y1 >= pContext->sClipRegion.i16YMin) &&
+ (i32Y1 <= pContext->sClipRegion.i16YMax) &&
+ (i32A != 0))
+ {
+ //
+ // Determine the column when subtracting the B delta.
+ //
+ i32X1 = i32X - i32B;
+
+ //
+ // If this column is within the clipping region, then draw a pixel
+ // at that position.
+ //
+ if((i32X1 >= pContext->sClipRegion.i16XMin) &&
+ (i32X1 <= pContext->sClipRegion.i16XMax))
+ {
+ GrPixelDraw(pContext, i32X1, i32Y1);
+ }
+
+ //
+ // Determine the column when adding the B delta.
+ //
+ i32X1 = i32X + i32B;
+
+ //
+ // If this column is within the clipping region, then draw a pixel
+ // at that position.
+ //
+ if((i32X1 >= pContext->sClipRegion.i16XMin) &&
+ (i32X1 <= pContext->sClipRegion.i16XMax))
+ {
+ GrPixelDraw(pContext, i32X1, i32Y1);
+ }
+ }
+
+ //
+ // Only draw the complementary pixels if the A and B deltas are
+ // different (otherwise, they describe the same set of pixels).
+ //
+ if(i32A != i32B)
+ {
+ //
+ // Determine the row when subtracting the B delta.
+ //
+ i32Y1 = i32Y - i32B;
+
+ //
+ // See if this row is within the clipping region.
+ //
+ if((i32Y1 >= pContext->sClipRegion.i16YMin) &&
+ (i32Y1 <= pContext->sClipRegion.i16YMax))
+ {
+ //
+ // Determine the column when subtracting the a delta.
+ //
+ i32X1 = i32X - i32A;
+
+ //
+ // If this column is within the clipping region, then draw a
+ // pixel at that position.
+ //
+ if((i32X1 >= pContext->sClipRegion.i16XMin) &&
+ (i32X1 <= pContext->sClipRegion.i16XMax))
+ {
+ GrPixelDraw(pContext, i32X1, i32Y1);
+ }
+
+ //
+ // Only draw the mirrored pixel if the A delta is non-zero
+ // (otherwise, it will be the same pixel).
+ //
+ if(i32A != 0)
+ {
+ //
+ // Determine the column when adding the A delta.
+ //
+ i32X1 = i32X + i32A;
+
+ //
+ // If this column is within the clipping region, then draw
+ // a pixel at that position.
+ //
+ if((i32X1 >= pContext->sClipRegion.i16XMin) &&
+ (i32X1 <= pContext->sClipRegion.i16XMax))
+ {
+ GrPixelDraw(pContext, i32X1, i32Y1);
+ }
+ }
+ }
+
+ //
+ // Determine the row when adding the B delta.
+ //
+ i32Y1 = i32Y + i32B;
+
+ //
+ // See if this row is within the clipping region.
+ //
+ if((i32Y1 >= pContext->sClipRegion.i16YMin) &&
+ (i32Y1 <= pContext->sClipRegion.i16YMax))
+ {
+ //
+ // Determine the column when subtracting the A delta.
+ //
+ i32X1 = i32X - i32A;
+
+ //
+ // If this column is within the clipping region, then draw a
+ // pixel at that position.
+ //
+ if((i32X1 >= pContext->sClipRegion.i16XMin) &&
+ (i32X1 <= pContext->sClipRegion.i16XMax))
+ {
+ GrPixelDraw(pContext, i32X1, i32Y1);
+ }
+
+ //
+ // Only draw the mirrored pixel if the A delta is non-zero
+ // (otherwise, it will be the same pixel).
+ //
+ if(i32A != 0)
+ {
+ //
+ // Determine the column when adding the A delta.
+ //
+ i32X1 = i32X + i32A;
+
+ //
+ // If this column is within the clipping region, then draw
+ // a pixel at that position.
+ //
+ if((i32X1 >= pContext->sClipRegion.i16XMin) &&
+ (i32X1 <= pContext->sClipRegion.i16XMax))
+ {
+ GrPixelDraw(pContext, i32X1, i32Y1);
+ }
+ }
+ }
+ }
+
+ //
+ // See if the error term is negative.
+ //
+ if(i32D < 0)
+ {
+ //
+ // Since the error term is negative, adjust it based on a move in
+ // only the A delta.
+ //
+ i32D += (4 * i32A) + 6;
+ }
+ else
+ {
+ //
+ // Since the error term is non-negative, adjust it based on a move
+ // in both the A and B deltas.
+ //
+ i32D += (4 * (i32A - i32B)) + 10;
+
+ //
+ // Decrement the B delta.
+ //
+ i32B -= 1;
+ }
+
+ //
+ // Increment the A delta.
+ //
+ i32A++;
+ }
+}
+
+//*****************************************************************************
+//
+//! Draws a filled circle.
+//!
+//! \param pContext is a pointer to the drawing context to use.
+//! \param i32X is the X coordinate of the center of the circle.
+//! \param i32Y is the Y coordinate of the center of the circle.
+//! \param i32Radius is the radius of the circle.
+//!
+//! This function draws a filled circle, utilizing the Bresenham circle drawing
+//! algorithm. The extent of the circle is from \e i32X - \e i32Radius to
+//! \e i32X + \e i32Radius and \e i32Y - \e i32Radius to \e i32Y +
+//! \e i32Radius, inclusive.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+GrCircleFill(const tContext *pContext, int32_t i32X, int32_t i32Y,
+ int32_t i32Radius)
+{
+ int_fast32_t i32A, i32B, i32D, i32X1, i32X2, i32Y1;
+
+ //
+ // Check the arguments.
+ //
+ ASSERT(pContext);
+
+ //
+ // Initialize the variables that control the Bresenham circle drawing
+ // algorithm.
+ //
+ i32A = 0;
+ i32B = i32Radius;
+ i32D = 3 - (2 * i32Radius);
+
+ //
+ // Loop until the A delta is greater than the B delta, meaning that the
+ // entire circle has been filled.
+ //
+ while(i32A <= i32B)
+ {
+ //
+ // Determine the row when subtracting the A delta.
+ //
+ i32Y1 = i32Y - i32A;
+
+ //
+ // See if this row is within the clipping region.
+ //
+ if((i32Y1 >= pContext->sClipRegion.i16YMin) &&
+ (i32Y1 <= pContext->sClipRegion.i16YMax))
+ {
+ //
+ // Determine the column when subtracting the B delta, and move it
+ // to the left edge of the clipping region if it is to the left of
+ // the clipping region.
+ //
+ i32X1 = i32X - i32B;
+ if(i32X1 < pContext->sClipRegion.i16XMin)
+ {
+ i32X1 = pContext->sClipRegion.i16XMin;
+ }
+
+ //
+ // Determine the column when adding the B delta, and move it to the
+ // right edge of the clipping region if it is to the right of the
+ // clipping region.
+ //
+ i32X2 = i32X + i32B;
+ if(i32X2 > pContext->sClipRegion.i16XMax)
+ {
+ i32X2 = pContext->sClipRegion.i16XMax;
+ }
+
+ //
+ // Draw a horizontal line if this portion of the circle is within
+ // the clipping region.
+ //
+ if(i32X1 <= i32X2)
+ {
+ GrLineDrawH(pContext, i32X1, i32X2, i32Y1);
+ }
+ }
+
+ //
+ // Determine the row when adding the A delta.
+ //
+ i32Y1 = i32Y + i32A;
+
+ //
+ // See if this row is within the clipping region, and the A delta is
+ // not zero (otherwise, this describes the same row of the circle).
+ //
+ if((i32Y1 >= pContext->sClipRegion.i16YMin) &&
+ (i32Y1 <= pContext->sClipRegion.i16YMax) &&
+ (i32A != 0))
+ {
+ //
+ // Determine the column when subtracting the B delta, and move it
+ // to the left edge of the clipping region if it is to the left of
+ // the clipping region.
+ //
+ i32X1 = i32X - i32B;
+ if(i32X1 < pContext->sClipRegion.i16XMin)
+ {
+ i32X1 = pContext->sClipRegion.i16XMin;
+ }
+
+ //
+ // Determine the column when adding the B delta, and move it to the
+ // right edge of the clipping region if it is to the right of the
+ // clipping region.
+ //
+ i32X2 = i32X + i32B;
+ if(i32X2 > pContext->sClipRegion.i16XMax)
+ {
+ i32X2 = pContext->sClipRegion.i16XMax;
+ }
+
+ //
+ // Draw a horizontal line if this portion of the circle is within
+ // the clipping region.
+ //
+ if(i32X1 <= i32X2)
+ {
+ GrLineDrawH(pContext, i32X1, i32X2, i32Y1);
+ }
+ }
+
+ //
+ // Only draw the complementary lines if the B delta is about to change
+ // and the A and B delta are different (otherwise, they describe the
+ // same set of pixels).
+ //
+ if((i32D >= 0) && (i32A != i32B))
+ {
+ //
+ // Determine the row when subtracting the B delta.
+ //
+ i32Y1 = i32Y - i32B;
+
+ //
+ // See if this row is within the clipping region.
+ //
+ if((i32Y1 >= pContext->sClipRegion.i16YMin) &&
+ (i32Y1 <= pContext->sClipRegion.i16YMax))
+ {
+ //
+ // Determine the column when subtracting the A delta, and move
+ // it to the left edge of the clipping regino if it is to the
+ // left of the clipping region.
+ //
+ i32X1 = i32X - i32A;
+ if(i32X1 < pContext->sClipRegion.i16XMin)
+ {
+ i32X1 = pContext->sClipRegion.i16XMin;
+ }
+
+ //
+ // Determine the column when adding the A delta, and move it to
+ // the right edge of the clipping region if it is to the right
+ // of the clipping region.
+ //
+ i32X2 = i32X + i32A;
+ if(i32X2 > pContext->sClipRegion.i16XMax)
+ {
+ i32X2 = pContext->sClipRegion.i16XMax;
+ }
+
+ //
+ // Draw a horizontal line if this portion of the circle is
+ // within the clipping region.
+ //
+ if(i32X1 <= i32X2)
+ {
+ GrLineDrawH(pContext, i32X1, i32X2, i32Y1);
+ }
+ }
+
+ //
+ // Determine the row when adding the B delta.
+ //
+ i32Y1 = i32Y + i32B;
+
+ //
+ // See if this row is within the clipping region.
+ //
+ if((i32Y1 >= pContext->sClipRegion.i16YMin) &&
+ (i32Y1 <= pContext->sClipRegion.i16YMax))
+ {
+ //
+ // Determine the column when subtracting the A delta, and move
+ // it to the left edge of the clipping region if it is to the
+ // left of the clipping region.
+ //
+ i32X1 = i32X - i32A;
+ if(i32X1 < pContext->sClipRegion.i16XMin)
+ {
+ i32X1 = pContext->sClipRegion.i16XMin;
+ }
+
+ //
+ // Determine the column when adding the A delta, and move it to
+ // the right edge of the clipping region if it is to the right
+ // of the clipping region.
+ //
+ i32X2 = i32X + i32A;
+ if(i32X2 > pContext->sClipRegion.i16XMax)
+ {
+ i32X2 = pContext->sClipRegion.i16XMax;
+ }
+
+ //
+ // Draw a horizontal line if this portion of the circle is
+ // within the clipping region.
+ //
+ if(i32X1 <= i32X2)
+ {
+ GrLineDrawH(pContext, i32X1, i32X2, i32Y1);
+ }
+ }
+ }
+
+ //
+ // See if the error term is negative.
+ //
+ if(i32D < 0)
+ {
+ //
+ // Since the error term is negative, adjust it based on a move in
+ // only the A delta.
+ //
+ i32D += (4 * i32A) + 6;
+ }
+ else
+ {
+ //
+ // Since the error term is non-negative, adjust it based on a move
+ // in both the A and B deltas.
+ //
+ i32D += (4 * (i32A - i32B)) + 10;
+
+ //
+ // Decrement the B delta.
+ //
+ i32B -= 1;
+ }
+
+ //
+ // Increment the A delta.
+ //
+ i32A++;
+ }
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
|
