c draw function not drawing properly - c

I'm trying to write a program that writes a digital car speedo onto an LCD screen (ST7735) with a Tiva C (Tm4C123GXL). The attached code is the draw line function that should draw a straight line between the two distances. if I put in (speed_x1, speed_y1, 80, 60, ST7735_WHITE) into the function, up until 45 degrees, the line drawn is horizontal, not angled like it should be. After 45 degrees up until 90, the drawing is fine, then after 90 it breaks again.
speed_x1 = 80 - 55 * cos((PI / 180) * (speed * 1.8))
speed_y1 = 60 - 55 * sin((PI / 180) * (speed * 1.8))
(I want the speedo to max out at 100, hence speed * 1.8 is 1.8 degress/km/hr)
Any help in solving my problem here would be greatly appreciated. Thanks :)
void ST7735_DrawLine(short x1, short y1, short x2, short y2, unsigned short color) {
// unsigned char hi = color >> 8, lo = color;
//int x=x1;
//int y=y1;
int dy = y2 - y1;
int dx = x2 - x1;
double m = dy / dx;
double c = y1 - m * x1;
if ((x1 >= _width) || (y1 >= _height) || (x2 >= _width) || (y2 >= _height) ) return;
setAddrWindow(x1, y1, x1 + x2 - 1, y2);
while(x1 <= x2)
{
if (m <= 1)
{
x1 = x1 + 1;
y1 = m * x1 + c;
ST7735_DrawPixel(x1,y1,color);
}
else
{
y1 = y1 + 1;
x1 = (y1 - c) / m;
ST7735_DrawPixel(x1,y1,color);
}
}
}
void ST7735_DrawPixel(short x, short y, unsigned short color) {
if ((x < 0) || (x >= _width) || (y < 0) || (y >= _height))
return;
setAddrWindow(x,y,x+1,y+1);
pushColor(color);
}

Typecast problem. M results in 0 when dy/dx is below one. Typecast them to floats to get a float as a result.

If that would be a bresenham line drawing algorithm note that it only works within 45 deg. (Always wonder why ppl not even have a look at WP first.)
Not sure, but as your surname has a german origin: you will also find this in german on WP.
For other angles you would have to swap/reorder coordinates. It might even be better to have seperate drawing algorithms for hor/vert and diagonal lines, if performance is an issue (but as you use double, it is obviously none at all).

Related

What does the variable D do inside the while in this Bresenham's line drawing algorithm?

I've found this Generalized Bresenham's Line Drawing Algorithm and I'm having a hard time understanding what the while is doing here.
Any help is greatly appreciated.
the code:
#define sign(x) ((x > 0)? 1 : ((x < 0)? -1: 0))
x = x1;
y = y1;
dx = abs(x2 - x1);
dy = abs(y2 - y1);
s1 = sign(x2 - x1);
s2 = sign(y2 - y1);
swap = 0;
if (dy > dx) {
temp = dx;
dx = dy;
dy = temp;
swap = 1;
}
D = 2*dy - dx;
for (i = 0; i < dx; i++) {
display_pixel (x, y);
while (D >= 0) {
D = D - 2*dx;
if (swap)
x += s1;
else
y += s2;
}
D = D + 2*dy;
if (swap)
y += s2;
else
x += s1;
}
D is the scaled distance from the line to the candidate x, y coordinate.
Better: D is scaled difference of the distance from the line to the candidates x+1, y+0 and x+1, y+1.
That is, as x increments, the sign of D indicates should the closer y increment by 0 or 1?
(The role of x, y interchanges depending on which octant the algorithm is applied.)
I expected while (D >= 0) { as if (D >= 0) {. Bresenham's line algorithm
Note that OP's code is subject to overflow in abs(x2 - x1) and 2*dy - dx. Alternates exist that do not rely on wider math.

C Mid Point Circle Algorithm Split Circle Into 4

In my program I am currently rendering circles using the Midpoint Circle Algorithm with the following code.
void drawcircle(int x0, int y0, int radius)
{
int x = radius-1;
int y = 0;
int dx = 1;
int dy = 1;
int err = dx - (radius << 1);
while (x >= y)
{
putpixel(x0 + x, y0 + y);
putpixel(x0 + y, y0 + x);
putpixel(x0 - y, y0 + x);
putpixel(x0 - x, y0 + y);
putpixel(x0 - x, y0 - y);
putpixel(x0 - y, y0 - x);
putpixel(x0 + y, y0 - x);
putpixel(x0 + x, y0 - y);
if (err <= 0)
{
y++;
err += dy;
dy += 2;
}
if (err > 0)
{
x--;
dx += 2;
err += (-radius << 1) + dx;
}
}
}
But my question is, is it possible to have this function work the same way, but split the circle into 4 separate sections? i.e. so rather than rendering a normal circle, it would look somewhat like this
Putting holes in circles
The implementation you had had some overlapping pixels where the 8 subsections meet. Also the circle was the wrong diameter (should always be even because radius * 2) the cause of some of the overlap.
To fix the size and remove the overlap I move half the circle out (to the right down) by one pixel and prevented half the last iteration pixels being rendered.
Also the statement if(err <= 0) is not needed as at that point err will always meet that condition. The y offset steps up 1 pixel each iteration, the err is to find when x needs to step.
Easy solution
With that the solution to your question regarding putting holes in the circle. You just need a counter to count down the number of pixels you want to skip. While that counter is > 0 don't draw any pixels.
I added it to the snippet below as a 4th argument hole. An int that is half the size of the hole at the top, bottom, left and right of the circle.
So if you want a 20 pixel hole then the last argument is 10.
See right circles in image below.
Limit and geek stuff
Note that the max size of hole is sin(PI / 4) * radius if you make it bigger, no pixels will be drawn. As a side note the number of pixel drawn (without the holes) is approx sin(PI / 4) * radius * 8 - 4 which is almost 10% less than the circumference.
Solution for answer
void drawcircle(int x0, int y0, int radius, int hole) {
int x = radius-1;
int y = 0;
int dx = 1;
int dy = 1;
int err = dx - (radius << 1);
int x1 = x0 + 1;
int y1 = x0 + 1;
while (x >= y) {
if(hole == 0){
putpixel(x1 + x, y1 + y);
putpixel(x0 - x, y0 - y);
putpixel(x0 - y, y1 + x);
putpixel(x1 + x, y0 - y);
if (x > y) {
putpixel(x1 + y, y1 + x);
putpixel(x0 - x, y1 + y);
putpixel(x0 - y, y0 - x);
putpixel(x1 + y, y0 - x);
}
} else {
hole--;
}
y++;
err += dy;
dy += 2;
if (err > 0) {
x--;
dx += 2;
err += (-radius << 1) + dx;
}
}
}
Also as I geeked out on this function as it makes some good high performance shapes like rounded cross and boxes with only very minor changes that I thought worth sharing. See image
To get other shapes...
Add back the y err test and then change the delta X, and delta y error change to values other than 2.
if(err <= 0){ // needed
y++;
err += dy;
dy += 8; << change this
}
if (err > 0) {
x--;
dx += 8; << change this
err += (-radius << 1) + dx;
}
// See image in answer
// 8 made bottom right cross,
// 18 top right
// 28 top left
// 0.8 bottom left
The image shows the shapes and the result of the holes

Can this line drawing algorithm be optimized? - SDL

For a project I have been working on, the ability to draw lines with a gradient (I.E. they change color over the interval they are drawn) would be very useful. I have an algorithm for this, as I will paste below, but it turns out to be DREADFULLY slow. I'm using the Bresenham algorithm to find each point, but I fear that I have reached the limits of software rendering. I've been using SDL2 thus far, and my line drawing algorithm appears 200x slower than SDL_RenderDrawLine. This is an estimate, and gathered from comparing the two functions' times to draw 10,000 lines. My function would take near 500ms, and SDL_RenderDrawLine did it in 2-3ms on my machine. I even tested the functions with horizontal lines to ensure it wasn't just a botched Bresenham algorithm, and similar slowness hatched. Unfortunately, SDL doesn't have an API for drawing lines with a gradient (or if it does, I'm blind). I knew that any software rendering would be significantly slower than hardware, but the shear magnitude of slowness caught me by surprise. Is there a method that can be used to speed this up? Have I just botched the drawing system beyond reason? I've considered saving an array of the pixels I wish to draw and then shoving them to the screen all at once, but I don't know how to do this with SDL2 and I can't seem to find the API in the wiki or documentation that allows for this. Would that even be faster?
Thanks for the consideration!
void DRW_LineGradient(SDL_Renderer* rend, SDL_Color c1, int x1, int y1, SDL_Color c2, int x2, int y2){
Uint8 tmpr, tmpg, tmpb, tmpa;
SDL_GetRenderDrawColor(rend, &tmpr, &tmpg, &tmpb, &tmpa);
int dy = y2 - y1;
int dx = x2 - x1;
/* Use doubles for a simple gradient */
double d = (abs(x1 - x2) > abs(y1 - y2) ? abs(x1 - x2) : abs(y1 - y2));
double dr = (c2.r - c1.r) / d;
double dg = (c2.g - c1.g) / d;
double db = (c2.b - c1.b) / d;
double da = (c2.a - c1.a) / d;
double r = c1.r, g = c1.g, b = c1.b, a = c1.a;
/* The line is vertical */
if (dx == 0) {
int y;
if (y2 >= y1) {
for (y = y1; y <= y2; y++) {
SDL_SetRenderDrawColor(rend, r, g, b, a);
SDL_RenderDrawPoint(rend, x1, y);
r += dr;
g += dg;
b += db;
a += da;
}
return;
}
else{
for (y = y1; y >= y2; y--) {
SDL_SetRenderDrawColor(rend, r, g, b, a);
SDL_RenderDrawPoint(rend, x1, y);
r += dr;
g += dg;
b += db;
a += da;
}
return;
}
}
/* The line is horizontal */
if (dy == 0) {
int x;
if (x2 >= x1) {
for (x = x1; x <= x2; x++) {
SDL_SetRenderDrawColor(rend, r, g, b, a);
SDL_RenderDrawPoint(rend, x, y1);
r += dr;
g += dg;
b += db;
a += da;
}
return;
}
else{
for (x = x1; x >= x2; x--) {
SDL_SetRenderDrawColor(rend, r, g, b, a);
SDL_RenderDrawPoint(rend, x, y1);
r += dr;
g += dg;
b += db;
a += da;
}
return;
}
}
/* The line has a slope of 1 or -1 */
if (abs(dy) == abs(dx)) {
int xmult = 1, ymult = 1;
if (dx < 0) {
xmult = -1;
}
if (dy < 0) {
ymult = -1;
}
int x = x1, y = y1;
do {
SDL_SetRenderDrawColor(rend, r, g, b, a);
SDL_RenderDrawPoint(rend, x, y);
x += xmult;
y += ymult;
r += dr;
g += dg;
b += db;
a += da;
} while (x != x2);
return;
}
/* Use bresenham's algorithm to render the line */
int checky = dx >> 1;
int octant = findOctant((Line){x1, y1, x2, y2, dx, dy});
dy = abs(dy);
dx = abs(dx);
x2 = abs(x2 - x1) + x1;
y2 = abs(y2 - y1) + y1;
if (octant == 1 || octant == 2 || octant == 5 || octant == 6) {
int tmp = dy;
dy = dx;
dx = tmp;
}
int x, y = 0;
for (x = 0; x <= dx; x++) {
SDL_SetRenderDrawColor(rend, r, g, b, a);
switch (octant) {
case 0:
SDL_RenderDrawPoint(rend, x + x1, y + y1);
break;
case 1:
SDL_RenderDrawPoint(rend, y + x1, x + y1);
break;
case 2:
SDL_RenderDrawPoint(rend, -y + x1, x + y1);
break;
case 3:
SDL_RenderDrawPoint(rend, -x + x1, y + y1);
break;
case 4:
SDL_RenderDrawPoint(rend, -x + x1, -y + y1);
break;
case 5:
SDL_RenderDrawPoint(rend, -y + x1, -x + y1);
break;
case 6:
SDL_RenderDrawPoint(rend, y + x1, -x + y1);
break;
case 7:
SDL_RenderDrawPoint(rend, x + x1, -y + y1);
break;
default:
break;
}
checky += dy;
if (checky >= dx) {
checky -= dx;
y++;
}
r += dr;
g += dg;
b += db;
a += da;
}
SDL_SetRenderDrawColor(rend, tmpr, tmpg, tmpb, tmpa);
}
SIDE NOTE:
I am reluctant to just move on to using OpenGL 3.0+ (Which I hear SDL2 has support for) because I don't know how to use it. Most tutorials I have found have explained the process of setting up the contexts with SDL and then coloring the screen one solid color, but then stop before explaining how to draw shapes and such. If someone could offer a good place to start learning about this, that would also be extremely helpful.
A lot of the overhead of your function is in repeated calls to SDL_RenderDrawPoint. This is (most likely) a generic function which needs to do the following operations:
check if x and y are in range for your current surface;
calculate the position inside the surface by multiplying y with surface->pitch and x with surface->format->BytesPerPixel;
check the current color model of the surface using SDL_PixelFormat;
convert the provided color to the correct format for this color model.
All of the above must be done for each single pixel. In addition, calling a function in itself is overhead -- small as it may be, it still needs to be done for each separate pixel, even if it is not visible.
You can:
omit x and y range checking if you are sure the line start and end points are always visible;
omit the convert-to-address step by calculating it once for the start of the line, then updating it by adding BytesPerPixel and pitch for a horizontal or vertical movement;
omit the convert-to-color model step by calculating the correct RGB values once (well, for a single color line, at least -- it's a bit harder for a gradient);
omit the function call by inlining the code to set a single pixel inside the line routine.
Another -- smaller -- issue: you call your own routine "Bresenham's ... but it isn't. Bresenham's optimization is actually that it avoids double calculations entirely (and its strongest point is that it still gives the mathematically correct output; something I would not count on when using double variables...).
The following routine does not check for range, color model, color values, or (indeed) if the surface should be locked. All of these operations should be ideally done outside the tight drawing loop. As it is, it assumes a 24-bit RGB color screen, with the Red byte first. [*]
I wrote this code for my current SDL environs, which is still SDL-1.0, but it should work for newer versions as well.
It is possible to use Bresenham's calculations for the delta-Red, delta-Green, and delta-Blue values as well, but I deliberately omitted them here :) They would add a lot of extra variables -- at a guess, three per color channel --, extra checks, and, not least of all, not really a visibly better quality. The difference between two successive values for Red, say 127 and 128, are usually too small to notice in a single pixel wide line. Besides, this small step would only occur if your line is at least 256 pixels long and you cover the entire range of Red from 0 to 255 in the gradient.
[*] If you are 100% sure you are targeting a specific screen model with your own program, you can use this (adjusted for that particular screen model, of course). It's feasible to target a couple of different screen models as well; write a customized routine for each, and use a function pointer to call the correct one.
Most likely this is how SDL_RenderDrawLine is able to squeeze out every millisecond of performance. Well worth writing all that code for a library (which will be used on a wide variety of screen set-ups), but most likely not for a single program such as yours. Notice I commented out a single range check, which falls back to a plain line routine if necessary. You could do the same for unusual or unexpected screen set-ups, and in that case simply call your own, slower, drawing routine. (Your routine is more robust as it uses SDL's native routines.)
The original line routine below was copied from The Internet more than a single decade ago, as I have been using it for ages. I'd gladly attribute it to someone; if anybody recognizes the comments (they are mostly as appeared in the original code), do post a comment.
void gradient_line (int x1,int y1,int x2,int y2,
int r1,int g1, int b1,
int r2,int g2, int b2)
{
int d; /* Decision variable */
int dx,dy; /* Dx and Dy values for the line */
int Eincr,NEincr; /* Decision variable increments */
int t; /* Counters etc. */
unsigned char *ScrPos;
int LineIncr;
int rd,gd,bd;
if (x1 < 0 || y1 < 0 || x2 < 0 || y2 < 0 ||
x1 >= SCREEN_WIDE || x2 >= SCREEN_WIDE ||
y1 >= SCREEN_HIGH || y2 >= SCREEN_HIGH)
{
line (x1,y1, x2,y2, (r1<<16)+(g1<<8)+b1);
return;
}
rd = (r2-r1)<<8;
gd = (g2-g1)<<8;
bd = (b2-b1)<<8;
dx = x2 - x1;
if (dx < 0)
dx = -dx;
dy = y2 - y1;
if (dy < 0)
dy = -dy;
if (dy <= dx)
{
/* We have a line with a slope between -1 and 1
*
* Ensure that we are always scan converting the line from left to
* right to ensure that we produce the same line from P1 to P0 as the
* line from P0 to P1.
*/
if (x2 < x1)
{
t = x2; x2 = x1; x1 = t; /* Swap X coordinates */
t = y2; y2 = y1; y1 = t; /* Swap Y coordinates */
/* Swap colors */
r1 = r2;
g1 = g2;
b1 = b2;
rd = -rd;
gd = -gd;
bd = -bd;
}
r1 <<= 8;
g1 <<= 8;
b1 <<= 8;
if (y2 > y1)
{
LineIncr = screen->pitch;
} else
{
LineIncr = -screen->pitch;
}
d = 2*dy - dx; /* Initial decision variable value */
Eincr = 2*dy; /* Increment to move to E pixel */
NEincr = 2*(dy - dx); /* Increment to move to NE pixel */
ScrPos = (unsigned char *)(screen->pixels+screen->pitch*y1+x1*screen->format->BytesPerPixel);
rd /= dx;
gd /= dx;
bd /= dx;
/* Draw the first point at (x1,y1) */
ScrPos[0] = r1 >> 8;
ScrPos[1] = g1 >> 8;
ScrPos[2] = b1 >> 8;
r1 += rd;
g1 += gd;
b1 += bd;
/* Incrementally determine the positions of the remaining pixels */
for (x1++; x1 <= x2; x1++)
{
if (d < 0)
{
d += Eincr; /* Choose the Eastern Pixel */
} else
{
d += NEincr; /* Choose the North Eastern Pixel */
ScrPos += LineIncr;
}
ScrPos[0] = r1>>8;
ScrPos[1] = g1>>8;
ScrPos[2] = b1>>8;
ScrPos += screen->format->BytesPerPixel;
r1 += rd;
g1 += gd;
b1 += bd;
}
} else
{
/* We have a line with a slope between -1 and 1 (ie: includes
* vertical lines). We must swap our x and y coordinates for this.
*
* Ensure that we are always scan converting the line from left to
* right to ensure that we produce the same line from P1 to P0 as the
* line from P0 to P1.
*/
if (y2 < y1)
{
t = x2; x2 = x1; x1 = t; /* Swap X coordinates */
t = y2; y2 = y1; y1 = t; /* Swap Y coordinates */
/* Swap colors */
r1 = r2;
g1 = g2;
b1 = b2;
rd = -rd;
gd = -gd;
bd = -bd;
}
r1 <<= 8;
g1 <<= 8;
b1 <<= 8;
if (x2 > x1)
{
LineIncr = screen->format->BytesPerPixel;
} else
{
LineIncr = -screen->format->BytesPerPixel;
}
d = 2*dx - dy; /* Initial decision variable value */
Eincr = 2*dx; /* Increment to move to E pixel */
NEincr = 2*(dx - dy); /* Increment to move to NE pixel */
rd /= dy;
gd /= dy;
bd /= dy;
/* Draw the first point at (x1,y1) */
ScrPos = (unsigned char *)(screen->pixels+screen->pitch*y1+x1*screen->format->BytesPerPixel);
ScrPos[0] = r1 >> 8;
ScrPos[1] = g1 >> 8;
ScrPos[2] = b1 >> 8;
r1 += rd;
g1 += gd;
b1 += bd;
/* Incrementally determine the positions of the remaining pixels
*/
for (y1++; y1 <= y2; y1++)
{
ScrPos += screen->pitch;
if (d < 0)
{
d += Eincr; /* Choose the Eastern Pixel */
} else
{
d += NEincr; /* Choose the North Eastern Pixel */
ScrPos += LineIncr; /* (or SE pixel for dx/dy < 0!) */
}
ScrPos[0] = r1 >> 8;
ScrPos[1] = g1 >> 8;
ScrPos[2] = b1 >> 8;
r1 += rd;
g1 += gd;
b1 += bd;
}
}
}
.. and this is a section of a screenful of random lines with random colors, with on the right a close-up:
I did not time the difference between "native" SDL line drawing, your naive method, a pure solid color Bresenham's implementation and this one; then again, this ought not be very much slower than an SDL native line.

Point on a straight line specific distance away in C

How do I find the point on the straight line that is specific distance away from a given point. I am writing this code in C but I do not get the right answer..Could you anyone guide me on what I am doing wrong.
I get the x1,y1,x2,y2 values and the distance left fine. Using these I can find the slope m and the y-intercept also fine.
Now, I need to find the point on the straight line connecting these two points that is 10 units away from the point x1,y1. I seem to be going wrong here. here's the code that I wrote.
int x1 = node[n].currentCoordinates.xCoordinate;
int y1 = node[n].currentCoordinates.yCoordinate;
int x2 = node[n].destinationLocationCoordinates.xCoordinate;
int y2 = node[n].destinationLocationCoordinates.yCoordinate;
int distanceleft = (y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1);
distanceleft = sqrt(distanceleft);
printf("Distance left to cover is %d\n",distanceleft);
int m = (y2 - y1)/(x2 - x1); // slope.
int b = y1 - m * x1; //y-intercept
//find point on the line that is 10 units away from
//current coordinates on equation y = mx + b.
if(x2 > x1)
{
printf("x2 is greater than x1\n");
int tempx = 0;
int tempy = 0;
for(tempx = x1; tempx <= x2; tempx++)
{
tempy = y1 + (y2 - y1) * (tempx - x1)/(x2 - x1);
printf("tempx = %d, tempy = %d\n",tempx,tempy);
int distanceofthispoint = (tempy - y1) * (tempy - y1) + (tempx - x1) * (tempx - x1);
distanceofthispoint = sqrt((int)distanceofthispoint);
if(distanceofthispoint >= 10)
{
//found new points.
node[n].currentCoordinates.xCoordinate = tempx;
node[n].currentCoordinates.yCoordinate = tempy;
node[n].TimeAtCurrentCoordinate = clock;
printf("Found the point at the matching distance\n");
break;
}
}
}
else
{
printf("x2 is lesser than x1\n");
int tempx = 0;
int tempy = 0;
for(tempx = x1; tempx >= x2; tempx--)
{
tempy = y1 + (y2 - y1) * (tempx - x1)/(x2 - x1);
printf("tempx = %d, tempy = %d\n",tempx,tempy);
int distanceofthispoint = (tempy - y1) * (tempy - y1) + (tempx - x1) * (tempx - x1);
distanceofthispoint = sqrt((int)distanceofthispoint);
if(distanceofthispoint >= 10)
{
//found new points.
node[n].currentCoordinates.xCoordinate = tempx;
node[n].currentCoordinates.yCoordinate = tempy;
node[n].TimeAtCurrentCoordinate = clock;
printf("Found the point at the matching distance\n");
break;
}
}
}
printf("at time %f, (%d,%d) are the coordinates of node %d\n",clock,node[n].currentCoordinates.xCoordinate,node[n].currentCoordinates.yCoordinate,n);
Here is how it is in math, I don't have time to write something in C.
You have a point (x1,y1) and another one (x2,y2), when linked it gives you a segment.
Thus you have a directional vector v=(xv, yv) where xv=x2-x1 and yv=y2-y1.
Now, you need to divide this vector by its norm, you get a new vector: vector = v / sqrt(xv2 + yv2).
Now, you just have to add to your origin point the vector multiplied by the distance at which you want your point:
Position = (x origin, y origin) + distance × vector
I hope this helps!
Or simpler,
Find the angle from the slope
θ = arctan(y2-y1/x2-x1)
You might want to modify the quadrant of θ based on the numerator and denominator of the slope. Then you can find any point on the line at distance d from (x1, y1)
x_new = x1 + d×cos(θ)
y_new = y1 + d×sin(θ)
In this case, you have d=10

pieslice() function in C

How can I draw a major pieslice in C, using the function pieslice()?
pieslice(X-centre,Y-centre,StrtAngle,EndAngle,Radius).
I am trying to draw a major sector or pieslice in C, using the pieslice function; I want the start angle to be 135 degrees and end angle to be 235 degrees, but at the same time it should be the major sector, not the minor sector.
I tried all the four combinations
pieslice(100,100,135,-135,20)
pieslice(200,200,225,135,30)
pieslice(300,300,225,360+135,30)
pieslice(400,400,135,225,20)
pieslice(50,50,0,135,30);
pieslice(50,50,225,0,30);
But all of them draw the corresponding minor sector not the major sector. Can someone please advise me how to do that?
Here is a screenshot of the output:
Thanks for your effort and time.
Now, I could not make the pieslice to work my way. However with the following tweak, I am able to get around the problem and get the desired output. I wrote a user defined function slice(int x-centre, int y-centre,int sangle, int eangle, int radius) similar to pieslice.
I hope it is useful for those who get stuck in a similar kind of situation:
void slice(int x, int y, int sangle, int eangle, int rad)
{
int i,j,color;
if(sangle>eangle){
color=getcolor();
setcolor(getcolor()) ;
setfillstyle(SOLID_FILL,color);
circle(x,y,rad);
floodfill(x,y,color);
setcolor(getbkcolor());
setfillstyle(SOLID_FILL,getbkcolor());
pieslice(x,y,eangle,sangle,rad);
setcolor(color);
}
}
Draw two pie slices with the same centre and radius, one from 0 to 135 degrees, and one from 225 to 0 degrees. It seems that the function is forcing the pie slices to be always less than 180 degrees, so this should work around that.
See also: http://electrosofts.com/cgraphics/
here is my game loop using pieslice . pacman moves to and fro.
for (int dx = 10, dy = 0, dt = 100; c != 'q';) {
if ((x + rx + dx) > getmaxx() || (x + rx + dx) < 0) {
dx = -dx;
rx = -rx;
}
if ((y + ry + dy) > getmaxy() || (y + ry + dy) < 0) {
dy = -dy;
ry = -ry;
}
delay(dt);
cleardevice();
//gotoxy(1,1);
//cout << x+rx << " " << y+ry << " " << m;
pieslice(x, y, (sa + m), (ea - m), RADIUS);
//floodfill(x,y,getcolor());
if (m + dm < 0 || m + dm > ea)
dm = -dm;
m += dm;
x += dx;
y += dy;
if (kbhit())
c = getch();
}

Resources