|
-
Dec 19th, 2001, 11:48 AM
#1
Thread Starter
Hyperactive Member
Plot a Cirlce
Hi,
I'm trying to plot a circle on a form.
I know that I could use the circle method, but I want to do it pixel by pixel, and to be able to control the spead in which it is drawn.
I thought I'd use PSet, but I'm not sure on where to start.
I'd like to get some help/direction on being able to do it, from just knowing a centre point on the form.
If anyone could advise me it would be gratefully appreciated.
Regards
-
Dec 19th, 2001, 02:16 PM
#2
Hyperactive Member
Well...you are lucky..I am in a jolly mood today..
VB Code:
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Const Pi = 3.14159265358979 'atn(1)*4
Private Sub Form_Load()
Me.AutoRedraw = True
Me.WindowState = 2
Me.BackColor = vbWhite
Me.Print "Double Click The form"
End Sub
Private Sub Form_DblClick()
Me.DrawWidth = 5
'Just Draw a Box
Me.Line (Me.ScaleWidth / 2 - 1000, Me.ScaleHeight / 2 - 1000)-(Me.ScaleWidth / 2 + 1000, Me.ScaleHeight / 2 + 1000), vbBlack, B
PlotArc Me.ScaleWidth / 2, Me.ScaleHeight / 2, 1000, vbRed, 270, 30
End Sub
'==============================================================
'PlotArc
'--------
'X - X coordinate of the center
'Y - Y Coordinate of the center
'R - Radius of the arc
'Color - Optional as a long value {default: black}
'Theta - Optional angle of sweep as integer {default:360}
'Delay - In milliseconds between each pixel. {default:No delay}
'==============================================================
Private Sub PlotArc(ByVal X As Single, ByVal Y As Single, ByVal R As Long, Optional Color As Long = vbBlack, Optional Theta As Integer = 360, Optional Delay As Long)
Dim i As Integer
For i = 0 To Theta
Me.PSet (X + (R * Cos(i * Pi / 180)), Y + (R * Sin(i * Pi / 180))), Color
'---- Note:
'You can change where the drawing starts, the default starts East..
'So.. for example to start from South...add 90 to i..
'Me.PSet (X + (R * Cos((i + 90) * Pi / 180)), Y + (R * Sin((i + 90) * Pi / 180))), Color
'You can change the direction of rotation.. Just Swap Sin and cos
'Me.PSet (X + (R * Sin((i + 90) * Pi / 180)), Y + (R * Cos((i + 90) * Pi / 180))), Color
If Not (IsMissing(Delay) Or Delay = 0) Then
Sleep Delay
Me.Refresh
End If
Next
End Sub
Last edited by thinktank2; Dec 19th, 2001 at 02:25 PM.
-
Dec 19th, 2001, 02:20 PM
#3
Hyperactive Member
Another Tip...to Increase the thickness of the arc...change your form's drawwidth property like..
Me.Drawwidth = 10
-
Dec 20th, 2001, 06:19 AM
#4
Thread Starter
Hyperactive Member
Many Thanks!
Hi,
Thanks alot for that, very much appreciated.
The only question I have is how do you get it to complete the circle?, at the moment it leaves a quarter of it un-finished.
Regards
-
Dec 20th, 2001, 06:22 AM
#5
Thread Starter
Hyperactive Member
Duh!!!!
Hi,
Please ignore the last question!!!!
Amazing what you see/find when you take your time to digest the code :-)
Thanks once again for your help.
Regards
-
Dec 22nd, 2001, 02:20 PM
#6
I once had to devise an algorithm that plotted a circle on the screen of a PalmOS device. It had to be a fast one since the language I had to work with was fairly slow.
I had a SetPixel(int x, Int y) native function to work with which would be more efficient than anything the language itself has to offer.
My algorithm was this...
Think of a horizontal line of length equal to the radius of the desired circle, the left hand end of which was at the center of the desired circle:
VB Code:
x,y <--r-->
o-----------------o
Now, think of the minute hand of a clock as it sweeps from 0 minutes to 7.5 minutes (000 degrees to 045 degrees). It's point moves faster to the right than it does downwards, this means that when we do and floating point trigonometry, we won't have any gaps in our circle.
VB Code:
| /
| /
| / <---minute hand
| /
|/
o---------------o
We only have to calculate the first eighth of the circle, and use the SetPixel() method to do the hard work of drawing the circle 8 pixels for each 'minute'.
thus, after a few iterations...
VB Code:
--[color=red]-[/color]
| |
---
'and a few more
,-----[color=red],[/color]
/ \
| |
\ /
`-----`
finally you end up with a full circle, the red point is the 'master point' and is similar to the point of the minute hand.
The algorithm is much faster for small circles since the point of the minute hand moves to the left by 1 pixel each time (the trig part determines the new height of the hand above the horizontal), it has a shorter distance to travel than a larger circle.
If I find the code I'll post it here, its not in a language normally associated with this forum, but its easy to see whats going on.
Its a difficult thing to visualise (and to describe), but I hope I have given you the right idea.
-
Dec 23rd, 2001, 12:51 AM
#7
VB Code:
Private Declare Function Arc Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long, ByVal X4 As Long, ByVal Y4 As Long) As Long
Private Sub Form_Load()
'KPD-Team 1998
'URL: [url]http://www.allapi.net/[/url]
'Set graphical mode to persistent
Me.AutoRedraw = True
'Draw to arcs
Arc Me.hdc, 0, 0, 100, 100, 100, 100, 100, 100
End Sub
-
Dec 23rd, 2001, 04:27 AM
#8
Hyperactive Member
Re: Plot a Cirlce
Pozzi:
------
You just have change the angle from 270 degrees to 360 degrees for a complete circle.
PlotArc Me.ScaleWidth / 2, Me.ScaleHeight / 2, 1000, vbRed, 270, 30
should be changed to..
PlotArc Me.ScaleWidth / 2, Me.ScaleHeight / 2, 1000, vbRed, 360, 30
{I know you later realized it... }
Wossname:
I posted a Solution that involves trig.
In fact, that comes about in one line... the rest are just wrappers.
Can you elaborate about your algorithm that you say is different from my idea ??
Daok see..
Originally posted by Pozzi
I know that I could use the circle method, but I want to do it pixel by pixel, and to be able to control the speed in which it is drawn.
-
Dec 23rd, 2001, 09:51 AM
#9
Well, thinktank2, from what I can gather from your code, it seems that your algorithm plots 1 pixel per trig expression (is that right?) mine does 8, and therefore has only to evaluate an 8th as many trig expressions as yours.
However, your algorithm does allow for drawing arcs, whereas mine doesn't. But since that wasn't a criterion of the starting post in this thread, it doesn't matter.
I havent found the code yet though, bear with me.
-
Dec 23rd, 2001, 11:40 AM
#10
Couldn't find the code so I re-wrote it (with much head scratching)........
Its in PocketC for PalmOS, but it's syntax is almost identical to normal C.
And don't complain about not knowing C because its bloody obvious what the code does! 
PHP Code:
//Circle Algorithm
library "PToolboxLib" //this is a library which contains the SetPixel() funtion, which simply draws a black dot on the screen
int i,k,a,b,c,d,e,f,g,h; //declare some integers and floats (like singles in VB)
float j,t;
//my algorithm
//##########################
circle(int x,int y,float r)
{
j=r*r; //radius squared
t=(0.7071068*r)+1;
for(i=0;i<=t;i++) //VB equivalent: [b]For i = 0 to t[/b]
{
k=sqrt(j-(i*i)); //k set to the height of the minute hand above 3 o'clock-9 o'clock line when i defines horizontal distance from (x,y), using pythagoras's theorem
//these next 8 lines are for speed, halves the number of calculations needed
a=x-i;
b=x+i;
c=x-k;
d=x+k;
e=y-i;
f=y+i;
g=y-k;
h=y+k;
//weirdly, the code ran a bit faster on my PalmOS device when I wrote each function call individually (rather than in a loop), this is at the expense of a larger executable file, but not by much...
SetPixel(b,g); //North-Right
SetPixel(a,g); //North-Left
SetPixel(d,e); //East-Up
SetPixel(d,f); //East-Down
SetPixel(a,h); //South-Left
SetPixel(b,h); //South-Right
SetPixel(c,e); //West-Up
SetPixel(c,f); //West-Down
} //end of for loop
} //end of function definition
//#########################
main() //this is just a demo program to show circle() in action
{
graph_on(); //clear form
circle(80,80,79.5); //call my function, circle radius at (80,80) and the radius is 79.5
wait(); //pauses so you can admire the beautiful circle
}
When I first wrote it, it was pretty fast, this time I haven't had time to optimise it fully, there are some quite glaring slow areas, but I'll edit the post if I get a free minute.
-
Dec 28th, 2001, 08:19 AM
#11
//weirdly, the code ran a bit faster on my PalmOS device when I wrote each function call individually (rather than in a loop), this is at the expense of a larger executable file, but not by much...
Not necessarily weird, at least not on a real PC. A loop slows code down, especially if there are only 1-2 instructions inside, because the loop jmp flushes the prefetch queue (read it up on the "art of assembly" page, you can reach it via the assembly forum here). A jmp instruction is always slow, so if you want spped, you should avoid it. I'm not sure if the Palm CPU has a prefetch queue, but I think so. Almost every cpu, including the old 8086 has one.
Last edited by CornedBee; Jan 6th, 2002 at 08:29 AM.
All the buzzt
 CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
-
Dec 28th, 2001, 03:15 PM
#12
Apparently the CPU is a Motorola M68000 DragonBall, according to the Palm website.
M68000 was what my old trusty Atari ST has (i still use it now and then )
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|