Go Down

Topic: Drawing Curves.. (Read 2347 times) previous topic - next topic

WiredUp

Hey all, hopefully someone can help me with my problem. I am trying to draw a simple curved line on a ks0108 LCD.. Like a quarter circle from 0,0 to like 64,64 or similar point.

I can see from the example "FPS" sketch on the playground how a for loop was used to get a slight curve on the screen, and I have been trying to make this work. I was hoping it was as simple as GLCD.DrawCircle(0,64,64, BLACK) but alas it has a blobbed perimeter as if it is caused by the rest of the circle being drawn having no place to go.

I dunno, I have been playing with alot of things and I am getting no where. I haven't taken calculus so I am at a loss in trying to formulate an equation to draw a curve.

If anyone can help push me in the right direction I'd be forever greatful!

AWOL

Quote
I haven't taken calculus

Calculus isn't necessary - Pythagorus will get you there:

r2 = x2 + y2

You know "r", and then simply generate "x" or "y" for one octant, and transpose the coordinates for the second octant.

Quote
it has a blobbed perimeter as if it is caused by the rest of the circle being drawn having no place to go

I have no idea what this means.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

WiredUp

Thanks for the reply.. I think I understand.. I will play with this tonight, and post up some results. I'm sure there are others that are new to this that will probably be looking for an answer similar to this sometime in the future.

As for the second quote.. yea, its a little hard to explain without a picture. I need to setup a photobucket or something to be able to upload pics from, but in any event it came out distorted like when you draw something on an LCD over top of another output on the LCD.

WiredUp

Ok, so.. I have been messing with this since I got home, and I thought I understood what you were talking about.. and yea, nothing.. I'm a couple hours in and..

I've drawn alot of cool stuff.. but a curve is not one of them. I just don't get it.. doesn't help that I'm a visual learner either when it comes to this stuff..

Ok, so I'm including a picture of what I was talking about in the first post.. this is GLCD.DrawCircle(0,64,64, BLACK);

All I want to do is draw a stupid curve.. its amazing I did get my pressure transducer hooked up and working.. didn't goof the math there and thats great but yea, I'm really stumped here.. any more elaboration or help would be greatly appreciated!


cr0sh

Try this:

http://en.wikipedia.org/wiki/Midpoint_circle_algorithm

Also, google "circle algorithm".

I used to remember a general (but very slow) circle algorithm back when I was coding in BASIC; but I've plum forgot it. I think the pseudo-code was something like:

Code: [Select]
x = 0;
y = 0;
cx = 100;
cy = 100;
rx = 20;
ry = 20;

for (i = 0; i < 2 * pi; i += .01) {
 x = cx + sin(i) * rx;
 y = cy + cos(i) * ry;
 plot(x, y);
}


Amazingly, the above actually works - but like I said, it isn't fast (the sin/cos mainly is the issue). I guess my memory isn't too bad!

;D
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

WiredUp

Awesome.. its all coming back full circle now.. lol, pun intended. That wiki page really helped me understand what I was trying to do with the circle equation.. or what I was suppose to do. Gonna grab a late dinner, and start jamming some code..

Thanks guys.. I'll post back any success for future readers!

WiredUp

Ok, well.. if nothing else I'm going to get this curve drawn and mounted on the mantle place.

So.. good points: I understand alot more about the equation of a circle and Bresenham's algorithm.. I was able to derive an equation for a quarter of a circle: Y = sqrt(radius-sqrt(X)^4) Draws an awesome curve on the good ol' TI-83.

Now for the bad.. I still feel like a retard.. I can't even get a squiggle let alone a curve.

I could not get this code to work.. It might just be me.. I'm not terribly experienced at coding.

Code: [Select]
int x = 0;
int y = 0;
int cx = 100;
int cy = 100;
int rx = 20;
int ry = 20;

for (int i = 0; i < 2 * PI; i += .01) {
 x = cx + sin(i) * rx;
 y = cy + cos(i) * ry;
 GLCD.DrawLine(1,1,x,y,BLACK);
}


So, with this code I get:



Better yet: I tried this...

Code: [Select]
 for(int X = 1; X < 64; X++)
 {
   int Y = sqrt(64-sqrt(X)^4);
 GLCD.DrawLine(1, 1, X, Y, BLACK);
 }


I understand the error I am getting as far as declaring a double as an int.. apple!=orange

Well sqrt(x) = x^(1/2) so I tried that and well it looks really cool... but its not a ##*&%!!! curve!!




So yeah, as you have probably guessed by now I am completely lost.. If anyone has any insight or can point me in the right direction please point directly towards the screen and think of me.. Thanks guys!

cr0sh

Make x, y, and i "floats" - you may or may not have to cast the others, try declaring x, y and i as floats, first...

BTW - is PI declared (never played with it)?
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

AWOL

#8
Aug 03, 2010, 08:52 am Last Edit: Aug 03, 2010, 09:15 am by AWOL Reason: 1
The lines in the last photo in reply #6 are because you're drawing the radius, not plotting points on the circumference.

Forget sine and cosine (you'll either underplot or overplot at some point unless you vary your angular increment).

Forget pi - you're not interested in the area or the length of the circumference.

(sorry don't have any drawing tools to hand)
Imagine you're plotting the circumference of a circle about the origin (0, 0) - we can simply offset this later to whatever part of the screen we want to plot to.

The radius is "r".

r2 = x2 + y2

so, solving for y,
y = sqrt (r2 - x2), and importantly, remember this has two roots, not just the positive one "sqrt" returns.

So now write a "for" loop, from x = 0 to x = x * (sqrt(2) / 2), and plug your values for "x" into the equation for "y".
Then simply "plot(x,y);" where "plot" writes a single point.
This will generate one octant of the circle.
The rest of the circle comes by adding appropriate offsets (remember the observation about "sqrt") and transposing x and y.

Bonus marks for eliminating the "sqrt" operation.

BTW, this isn't a hardware problem.

[edit]Almost forgot - don't forget most graphics devices put the origin at the top left of the screen, and that y increases downwards[/edit]
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

cr0sh

AWOL: I don't doubt your algorithm for plotting a circle, but can it be generalized for any ellipse, or for an arc of an ellipse? I was kinda under the impression that maybe the OP wanted something more than just a circle - if your solution could be generalized, then it would be a lot quicker than what I posted, and more useful (I know what I posted is not fast by a long shot)...

:)
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

AWOL

Yes it can be generalised for ellipses, but then you obviously can't rely on octant symmetry, and have to use quadrant symmetry.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Go Up