|
|
View previous topic :: View next topic |
Author |
Message |
artohautala
Joined: 17 Nov 2011 Posts: 187
|
how to draw circle to graphics display with ccs c-compiler |
Posted: Thu Jan 26, 2012 9:16 am |
|
|
HI,
I'm not very good in maths ... sorry
so I have graphics display 240x 128 pixels and I can set one
pixel at a time.
straight line is easy to draw but circle is very difficult !
but pls tell me how I can draw circle to my display ?
something like that: x^2 + y^ยจ2 = diameter ???
I don't know.
have fun |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Thu Jan 26, 2012 9:23 am |
|
|
Drawing lines, circles, ellipses and arcs are a well studied branch of computer science. These days this sort of thing is the bread and butter for graphics processors. Take a look at http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
RF Developer |
|
|
artohautala
Joined: 17 Nov 2011 Posts: 187
|
|
|
artohautala
Joined: 17 Nov 2011 Posts: 187
|
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Thu Jan 26, 2012 12:26 pm |
|
|
Can you show us the code you wrote for the algorithm? Then maybe we could help you. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
artohautala
Joined: 17 Nov 2011 Posts: 187
|
|
Posted: Thu Jan 26, 2012 12:44 pm |
|
|
SherpaDoug wrote: | Can you show us the code you wrote for the algorithm? Then maybe we could help you. |
thks for your answer and advice
Code: |
void rasterCircle(int x0, int y0, int radius)
{
int f,ddF_x,ddF_y,x,y;
f = (1 - radius);
ddF_x = 1;
ddF_y = -2 * radius;
x = 0;
y = radius;
pixel(x0, y0 + radius,1);
pixel(x0, y0 - radius,1);
pixel(x0 + radius, y0,1);
pixel(x0 - radius, y0,1);
while(x < y)
{
ddF_x == 2 * x + 1;
ddF_y == -2 * y;
f == x*x + y*y - radius*radius + 2*x - y + 1;
if(f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
pixel(x0 + x, y0 + y,1);
pixel(x0 - x, y0 + y,1);
pixel(x0 + x, y0 - y,1);
pixel(x0 - x, y0 - y,1);
pixel(x0 + y, y0 + x,1);
pixel(x0 - y, y0 + x,1);
pixel(x0 + y, y0 - x,1);
pixel(x0 - y, y0 - x,1);
}
}
my pixel function set x and y goordinates and "1" means pixel ON and "0"
means pixel "OFF"
and this is my call to draw circle
|
int8 x0,y0,radius;
x0 = 60;
y0 = 60;
radius = 60; |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Thu Jan 26, 2012 1:25 pm |
|
|
Well,
Circles are very symmetrical so we don't have to calculated every point.
In your code you are using 8 fold symmetry. This is like going from 0 degrees to 45 degrees ( the north by northeast octant of the compass)
The math goes like this
0=x^2+y^2-r^2 is true circle centered at 0,0
error is x^2+y^2-r^2
looking at north to north east octant
pixels are * 0
__________0
algorithm chooses pixel due east or south east
* has the coord (x,y) both 0 pixels have an x coord of x+1
mid pt has coord of (x+1,y+1/2)
error is (x+1)^2+(y+1/2)^2 -r^2
error >0 draw south east ( x+1,y-1) pixel else draw east pixel (x+1,y)
now we can compute the error in advance for the next iteration
change in error from (x+1,y-1/2) to (x+2,y-1/2) is 2x+3
(x+1,y-1/2) to (x+2,y-3/2) 2x+3 -2y+2
delta is the accumulated error
if delta is <0 then we decrement y
This branch of math is called finite differences wher the finite element is a pixel which is selected to be on or off. The choice of which generates a small error that is accumulated and will cause a shift in the choice of the pixel when it accumulates to a full pixel level. You might notice it has some similarity to the calculus that deals with infinitesimal differences.
Now once you know how to compute the pixels for the north northeast octant simply trans posing x for -x or y or -y and y for -y or x or -x and you have a full circle. Caution the math assumes the screen has a square pixel aspect ratio ( this is not the same as the screen horizontal to vertical size ratio) If you screen doesn't have square pixels then the circle will have an oval shape. If this is your issue I can help you with the mathematical correction needed.
Your code doesn't take advantage of the math available but instead computes in absolute terms then chooses a nearest pixel. This is expensive since with finite differences only addition is needed and a trivial multiplication by two but in your code there is a squaring of coordinates and there is no account for accumulating error the accumulated error can cause the situation where the nearest computed pixel isn't the best choice.
Last edited by Douglas Kennedy on Thu Jan 26, 2012 2:10 pm; edited 2 times in total |
|
|
artohautala
Joined: 17 Nov 2011 Posts: 187
|
|
Posted: Thu Jan 26, 2012 1:38 pm |
|
|
Douglas Kennedy wrote: | Well,
Circles are very symmetrical so we don't have to calculated every point.
In your code you are using 8 fold symmetry. This is like going from 0 degrees to 45 degrees ( the north by northeast octant of the compass)
The math goes like this
0=x^2+y^2-r^2 is true circle centered at 0,0
error is x^2+y^2-r^2
looking at north to north east octant
pixels are * 0
0
algorithm chooses pixel due east or south east
* has the coord (x,y) both 0 pixels have an x coord of x+1
mid pt has coord of (x+1,y+1/2)
error is (x+1)^2+(y+1/2)^2 -r^2
error >0 draw south east ( x+1,y-1) pixel else draw east pixel (x+1,y)
now we can compute the error in advance for the next iteration
change in error from (x+1,y-1/2) to (x+2,y-1/2) is 2x+3
(x+1,y-1/2) to (x+2,y-3/2) 2x+3 -2y+2
delta is the accumulated error
if delta is <0 then we decrement y
This branch of math is called finite differences her the finite element is a pixel which is selected to be on or off. The choice of which generates a small error that is accumulated and will cause a shift in the choice of the pixel when it accumulates to a full pixel level. You might notice it has some similarity to the calculus that deals with infinitesimal differences.
Now once you know how to compute the pixels for the north northeast octant simply trans posing x for -x or y or -y and y for -y or x or -x and you have a full circle. Caution the math assumes the screen has a square pixel aspect ratio ( this is not the same as the screen horizontal to vertical size ratio) If you screen doesn't have square pixels then the circle will have an oval shape. If this is your issue I can help you with the mathematical correction needed. |
ok nothing understood
sorry too difficult for me
I'm not so good in mathematics
I only like to draw circle to my graphics display with known diameter
to some known place ...
but anyway thanks for your good answer and advice
sorry I'm dummy and idiot I don't understand very much about maths.. |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Thu Jan 26, 2012 1:55 pm |
|
|
If math isn't your strong point then use proven solutions ....you'll find them in the GLCD library of this board. |
|
|
artohautala
Joined: 17 Nov 2011 Posts: 187
|
|
Posted: Thu Jan 26, 2012 2:28 pm |
|
|
Douglas Kennedy wrote: | If math isn't your strong point then use proven solutions ....you'll find them in the GLCD library of this board. |
HI,
thanks for your good answer ...
please if you can sharpen this : GLCD library
what it means
if you can help I'll be very satisfied |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1933 Location: Norman, OK
|
|
Posted: Thu Jan 26, 2012 2:44 pm |
|
|
The file GLCD.c in the PICC/examples directory on your hard drive is a
place to start. Read the header of the file for info on how to use it _________________ Google and Forum Search are some of your best tools!!!! |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Thu Jan 26, 2012 2:47 pm |
|
|
This might help
Code: | void lcd_circle(int8 x_ctr,int8 y_ctr,int8 radius,int8 pen_size,int8 solid,int8 set_clr)
{
int8 x,y,r,x1,y1;
signed int16 delta;
// y axis is shrunk to reflect the aspect ratio
// this uses bresenham's algorithm
// theory
// 0=x^2+y^2-r^2 is true circle centered at 0,0
// error is x^2+y^2-r^2
// looking at north to north east octant
// pixels are * 0
// 0
// algorithm chooses pixel due east or south east
// * has the coord (x,y) both 0 pixels have an x coord of x+1
// mid pt has coord of (x+1,y+1/2)
// error is (x+1)^2+(y+1/2)^2 -r^2
// error >0 draw south east ( x+1,y-1) pixel else draw east pixel (x+1,y)
// now we can compute the error in advance for the next iteration
// change in error from (x+1,y-1/2) to (x+2,y-1/2) is 2x+3
// (x+1,y-1/2) to (x+2,y-3/2) 2x+3 -2y+2
// Note: delta is the error in the code below
// if delta is <0 then we decrement y
//// max radius r for the nokia screen is 48
r=48;
if (radius<48) r=radius; // max radius is 48 pixels
if (solid) pen_size=1;
for (r=radius-pen_size;r<=radius;r++)
{
x=0;
y=r;
// assume last step was to south east pixel from (0,r) or 2*0-2*r+5
delta=(long)5-(long)2*(long)r;
loop:
y1=(long)y*(long)5/(long)6; /// aspect ratio
x1=(long)x*(long)5/(long)6; /// aspect ratio
if(solid)
{
lcd_line(x_ctr+x, y_ctr-y1, x_ctr+x, y_ctr+y1, set_clr);
lcd_line(x_ctr-x, y_ctr-y1, x_ctr-x, y_ctr+y1, set_clr);
lcd_line(x_ctr+y, y_ctr-x1, x_ctr+y, y_ctr+x1, set_clr);
lcd_line(x_ctr-y, y_ctr-x1, x_ctr-y, y_ctr+x1, set_clr);
}
else
{
lcd_setpixel(x_ctr+x,y_ctr+y1,set_clr); //SSE octant
lcd_setpixel(x_ctr+x,y_ctr-y1,set_clr); // NNE octant
lcd_setpixel(x_ctr-x,y_ctr+y1,set_clr); // SSW
lcd_setpixel(x_ctr-x,y_ctr-y1,set_clr); // NNW
lcd_setpixel(x_ctr+y,y_ctr+x1,set_clr); //ESE
lcd_setpixel(x_ctr+y,y_ctr-x1,set_clr); //ENE
lcd_setpixel(x_ctr-y,y_ctr+x1,set_clr); // WSW
lcd_setpixel(x_ctr-y,y_ctr-x1,set_clr); // WNW
}
}
if (delta<0) delta=delta+(long)2*(long)x+(long)3;
else {delta=delta+(long)2*((long)x-(long)y)+(long)5;y=y-1;}
x=x+1;
if (x<=y) goto loop;
} |
|
|
|
artohautala
Joined: 17 Nov 2011 Posts: 187
|
|
Posted: Thu Jan 26, 2012 3:04 pm |
|
|
RF_Developer wrote: | Drawing lines, circles, ellipses and arcs are a well studied branch of computer science. These days this sort of thing is the bread and butter for graphics processors. Take a look at http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
RF Developer |
problem solved!
it must be : SIGNED int f,ddF_x,ddF_y,x,y;
sure...
thank you have fun |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jan 26, 2012 4:07 pm |
|
|
Quote: | so I have graphics display 240x 128 pixels and I can set one
pixel at a time.
straight line is easy to draw but circle is very difficult !
|
I know you already have a solution, but for next time:
You can find example circle code (or other graphics algorithms) by
searching the CCS directories (for files *.c *.h) for "circle".
Quote: |
c:\program files\picc\drivers\glcd.c
c:\program files\picc\drivers\graphics.c
|
A text search program such as Examine32 is one of the most important
tools for a programmer. If you ever wondered how I am able to so
quickly point out CCS example code to people, it's because I use a text
search program. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|