Circles
Circles
Can someone give me a sample program to a circle, looping through radians and using sin() and cos() to solve x and y.
I forgot how to get a circle.
I forgot how to get a circle.
Code: Select all
Screen 19
Window (-12, 8)-(12,-8)
Dim As Double Pi, twoPi, theta, radius, xctr, yctr, x, y
Pi = 4 * Atn(1)
TwoPi = 2 * Pi
radius = 2 ' radius of circle
xctr = 1 ' position of centre
yctr = 2
Pset(radius + xctr, yctr), 14 ' start circle
For theta = 0 To TwoPi Step .05 ' theta in radians
x = xctr + radius * Cos(theta)
y = yctr + radius * Sin(theta)
Line -(x,y), 14 ' sector
Next theta
Line -(radius + xctr, yctr), 14 ' close circle
Sleep
Re: Circles
In FB, the easiest way is to look up the CIRCLE statement in the wiki. In general, if you have a radius r and an angle a (which you will vary from 0 to 2 * Pi):albert wrote:Can someone give me a sample program to a circle, looping through radians and using sin() and cos() to solve x and y.
I forgot how to get a circle.
FOR a = 0 to 2 * Pi STEP stepsize
x = r * COS(a)
y = r * SIN(a)
PSet(x, y)
a += stepsize
NEXT
This assumes that the stepsize is small enough that the result looks like a smooth circle instead of an array of isolated points.
There are faster ways, such as using the relatively slow trig functions to plot only 1/8 of the circle and using the 2D symmetry of the circle to get the rest. For example, once you have a point (x, y), then (x, -y), (-x, y), (-x, -y), (y, x), (y, -x), (-y, x) and (-y, -x) are all on the circle.
-
- Posts: 605
- Joined: Feb 18, 2006 13:30
- Location: Alexandria / Egypt
- Contact:
Code: Select all
Const PI As Double = 3.1415926535897932
sub drawmeacircle(byval x as integer, byval y as integer, byval radius as integer)
for i as double = 0 to PI * 2 step 0.005
var x2 = cos(i), y2 = sin(i)
pset ((x2 * radius) + x, (y2 * radius) + y)
next
end sub
screen 13
drawmeacircle(10,10, 3)
drawmeacircle(100,100, 30)
sleep
Thanks!
Thanks you guys. I had forgotten how to make a circle.
I'm testing the sin() and cos() function by:
creating a circle 90 degrees using just sines.
creating a circle 90 degrees using just cosines.
incrementing and decrementing through 1/2 pi.
I want to see the accuracy of the two functions.
I remember playing around with the formula and plugging in the log() somehow and remember that it smoothes out the rough edges on large circles. (corrects sin(),cos())
i think it was:
Y = Y * sin(log(r))
X = x * cos(log(r))
it might have been sin(?) * log(?)
I'll try to recreate the formula.
I'm testing the sin() and cos() function by:
creating a circle 90 degrees using just sines.
creating a circle 90 degrees using just cosines.
incrementing and decrementing through 1/2 pi.
I want to see the accuracy of the two functions.
I remember playing around with the formula and plugging in the log() somehow and remember that it smoothes out the rough edges on large circles. (corrects sin(),cos())
i think it was:
Y = Y * sin(log(r))
X = x * cos(log(r))
it might have been sin(?) * log(?)
I'll try to recreate the formula.
Circles
Here is my test on sin() circles and cos() circles
They both make perfect circles.
They both make perfect circles.
Code: Select all
dim x1 as double
dim y1 as double
dim x2 as double
dim y2 as double
dim r1 as double
dim r2 as double
dim a1 as double
dim a2 as double
dim stepsize as double
dim pi as double
pi = 3.14159
screen 12
stepsize = .00001
r1 = 100
r2 = 105
a1 = 0
a2 = pi /2
do
' fOR a1 = 0 to Pi/2 STEP stepsize
'x1 = -500 + (r1 * COS(log(a1)))
'y1 = 0 + (r1 * SIN(log(a1)))
x1 = 200 + (r1 * COS(a2))
y1 = 200 + (r1 * cos(a1))
x2 = 200 + (r2 * sin(a2))
y2 = 200 + (r2 * sin(a1))
PSet(x1, y1),13
pset(x2, y2),14
circle(200,200),95,2
a1 = a1 + stepsize
a2 = a2 - stepsize
loop until a1 >= pi*2
'a1 += stepsize
'NEXT
sleep
The double precision Sin and Cos functions in FB are correct to 16 digits. When Pset(x,y) sets a pixel on the screen it's position is quantised to the resolution of the screen. For 1000 pixels that is at best 3 digits.
There is a rule of thumb that says, when a human sees a circle drawn with 60 straight lines it looks smooth. For circles on the screen I use steps of .05 radians which gives 125 segments. That makes sure the polygon that approximates the circle will not have visible corners, the resolution of the screen is the limiting factor.
There is a rule of thumb that says, when a human sees a circle drawn with 60 straight lines it looks smooth. For circles on the screen I use steps of .05 radians which gives 125 segments. That makes sure the polygon that approximates the circle will not have visible corners, the resolution of the screen is the limiting factor.
Ideally stepsize should be 2*PI/circumference as to only draw the exact number of points on the edge of circle. Using an arbitrary number is nonsense since you are either doing too much work or not enough. A stepsize of 0.05 would be a circle with a circumference of ~125 which would be a radius of 20. Since the circumference of a circle is defined as 2*PI*r you can reduce the whole stepsize from 2 * PI / 2 * PI * r to simply 1 / r.
Note, I have fbgfx circle in yellow then manually draw the circle in grey so you can see it's the same approximate shape and size. The differences come from fbgfx using a different circle drawing algorithm which does not use floats.
Code: Select all
Const As Single PI = 4 * Atn( 1 )
Dim As Single radius
Dim As Single circumference
Dim As Single stepsize
ScreenRes 640, 480
Window Screen (-320, 240)-(319,-239)
Print "Enter a negative value to exit."
Do
Line( -320, -232 )-( 319, -224 ), 0, bf
Locate 2, 1
Input "Radius"; radius
If( radius < 0 )Then Exit Do
circumference = 2 * PI * radius
Print "Circumference:"; circumference
'stepsize = 2 * PI / circumference
stepsize = 1 / radius
Circle ( 0, 0 ), radius, 14
For theta As Single = 0 To 2 * PI Step stepsize
PSet( radius * Cos( theta ), radius * Sin( theta ) ), 7
Next
Loop
Here is a fast circle & ellipse drawing function I made a little while back:
http://www.freebasic.net/forum/viewtopi ... ht=ellipse
It only uses roughly 1/8 as many calls to sin() or cos() as the simpler brute-force methods and therefore takes up much less system ressources.
Cheers,
Mike
http://www.freebasic.net/forum/viewtopi ... ht=ellipse
It only uses roughly 1/8 as many calls to sin() or cos() as the simpler brute-force methods and therefore takes up much less system ressources.
Cheers,
Mike
There is no need to ever use sine or cosine to draw a circle on the screen.
Code: Select all
Screen 19
Window (-12, 8)-(12,-8)
Const As Double s = .05 ' unity vector ( c + j s )
Const As Double c = Sqr(1 - s * s) ' evaluated at compile time only
'-----------------------------------------------------------
Sub Circ(Byval xc As Double, Byval yc As Double, Byval radius As Double)
Dim As Double x = radius, y = 0, t
Pset(x + xc, yc), 14 ' start circle
For seg As Integer = 1 To 126 ' segments
t = x
x = c * x - s * y
y = s * t + c * y
Line -(x + xc, y + yc), 14
Next seg
End Sub
'-----------------------------------------------------------
' test circ routine
Dim As Double ctrx = 2 ' position of centre
Dim As Double ctry = 1
Dim As Double rad = 6 ' radius of circle
Circ( ctrx, ctry, rad)
'-----------------------------------------------------------
Sleep
'-----------------------------------------------------------
I wrote a huge number calculator, (its on the projects page under "I got my calculator working finally!")
I want to add sin() cos() and tan() functions to it and was testing a therory, that sines and cosines return the same values 90 degrees out of phase with each other, and i was right they do.
What i need is a faster method of figuring the functions other than rasing the number to powers and dividing by the factorial.
I want to add sin() cos() and tan() functions to it and was testing a therory, that sines and cosines return the same values 90 degrees out of phase with each other, and i was right they do.
What i need is a faster method of figuring the functions other than rasing the number to powers and dividing by the factorial.
I modified the no sin(),cos() circle a little
Hi everyone i modified richards circle program.
Code: Select all
Screen 19
'Window (-12, 8)-(12,-8)
Const As Double s = .001 ' unity vector ( c + j s )
Const As Double c = Sqr(1 - s * s) ' evaluated at compile time only
'-----------------------------------------------------------
Sub Circ(Byval xc As Double, Byval yc As Double, Byval radius As Double)
Dim As Double x = radius, y = 0, t
dim seg as integer
Pset(x + xc, y + yc), 14 ' start circle
For seg = 0 To 6.28 / s '125 ' segments
t = x
x = c * x - s * y
y = s * t + c * y
'Line -(x + xc, y + yc), 14
pset(x+xc,y+yc),14
Next seg
End Sub
'-----------------------------------------------------------
' test circ routine
Dim As Double ctrx = 250 ' position of centre
Dim As Double ctry = 250
Dim As Double rad = 200 ' radius of circle
Circ( ctrx, ctry, rad)
'-----------------------------------------------------------
Sleep
'-----------------------------------------------------------
@h4tt3n; Here is an expanded version to do aspect with one extra multiply.
Color now included. Implementation of aspect depends on how you define aspect.
Color now included. Implementation of aspect depends on how you define aspect.
Code: Select all
'-----------------------------------------------------------------------
' Circle or ellipse
'-----------------------------------------------------------------------
Screen 19
Window (-12, 8)-(12, -8)
Const As Double s = .05 ' unity vector ( c + j s )
Const As Double c = Sqr(1 - s * s) ' evaluated at compile time only
'-----------------------------------------------------------------------
Sub Circ(_ ' circle
Byval cx As Double,_ ' centre x
Byval cy As Double,_ ' centre y
Byval r As Double,_ ' x radius
Byval e As Double,_ ' y eccentricity
Byval k As Integer) ' colour
Dim As Double t, x = r, y = 0
Pset(x + cx, cy), 0 ' start circle
For seg As Integer = 1 To 126 ' segments
t = x
x = t * c - y * s
y = t * s + y * c
Line -(x + cx, y * e + cy), k
Next seg
End Sub
'-----------------------------------------------------------------------
' test circ routine
Dim As Double Xctr = 0 ' x position of centre
Dim As Double Yctr = 0 ' y
Dim As Double rad = 3 ' radius of circle
Dim As Double ecc = 2 ' y eccentricity
Dim As Double col = 14 ' colour
Circ( Xctr, Yctr, rad, ecc, col)
Circ( Xctr, Yctr, rad, .5, 12)
Line (-10, rad) -(10, rad),7
Line (-10, -rad) -(10, -rad),7
Line (rad, -16) -(rad, 16),7
Line (-rad, -16) -(-rad, 16),7
'-----------------------------------------------------------------------
Sleep
'-----------------------------------------------------------------------
Thanks Richard your a god!
I decided instead of adding sin(), cos() and tan() functions to the calculator, I'll put and X and Y button to return the x and y locations, given an input of radians and radius.
Thankyou!
I wrote a program for QBasic back in 1995 that let the user rotate a line with the arrow keys, and did it without sin(),cos() or tan() but for the life of me i couldn't remember how i did it, your example brings back some memories. (I still can't remember exactly how i did it. but your program works.)
I'll go ahead and add the "X" and "Y" buttons to the calculator.
at a thousand precision it should only take a 1/2 minut or so to come up with a X or Y coordinate.
I decided instead of adding sin(), cos() and tan() functions to the calculator, I'll put and X and Y button to return the x and y locations, given an input of radians and radius.
Thankyou!
I wrote a program for QBasic back in 1995 that let the user rotate a line with the arrow keys, and did it without sin(),cos() or tan() but for the life of me i couldn't remember how i did it, your example brings back some memories. (I still can't remember exactly how i did it. but your program works.)
I'll go ahead and add the "X" and "Y" buttons to the calculator.
at a thousand precision it should only take a 1/2 minut or so to come up with a X or Y coordinate.