Also, props to anyone who can add a Simple and Clean precision step to this, so only the pixels that need to be drawn are, rather than just 0 to 360 step 1. With a small ellipse, it's a waste of CPU speed and with a larger ellipse, it's not enough to simply go 1 degree at a time for some.
Code: Select all
#include once "fbgfx.bi"
#define pi 3.14159265
#define RadToDeg(__rad__) (__rad__ * (180/Pi))
#define DegToRad(__rad__) (__rad__ * (pi/180))
Declare Sub DrawEllipse( ByVal X as Integer, ByVal Y as Integer, ByVal W as Integer, ByVal H as Integer, ByVal Ang as Integer )
Screenres 640, 480, 32
'' Our settings.
Dim as Integer X = 319, Y = 239, W = 60, H = 60, Ang
Screenlock
Do
'' Get Key Presses
'' Move the Ellipse
If Multikey(FB.SC_LEFT) then X -= 1
If Multikey(FB.SC_RIGHT) then X += 1
If Multikey(FB.SC_UP) then Y -= 1
If Multikey(FB.SC_DOWN) then Y += 1
'' Change Ellipse Width
If Multikey(FB.SC_A) then W -= 1
If Multikey(FB.SC_D) then W += 1
'' Change Ellipse Height
If Multikey(FB.SC_W) then H += 1
If Multikey(FB.SC_S) then H -= 1
'' Increase Our Angle
Ang += 1
'' Check all of our variables and make sure they are valid.
If W < 1 then W = 1
If H < 1 then H = 1
If Ang > 359 then Ang = 0
'' Draw our ellipse.
DrawEllipse( X, Y, W, H, Ang )
'' "GUI" - Uhmm...Just text information ;p
'' Background
Line (0,0)-(250, 40), rgb(10, 20, 80), bf
Line (0,0)-(250, 40), rgb(80, 20, 10), b
Locate 1, 1
'' Text
Draw String (2,2), "Move with Arrow Keys"
Draw String (2,10), "Stretch Ellipse with WASD"
Draw String (2,18), "Pos: " & "(" & str(x) & "," & str(y) & "," & str(Ang) & ")"
Draw String (2,26), "W/H: " & "(" & str(w) & "," & str(h) & ")"
'' Flip our Page
screenunlock
sleep 15, 1
screenlock
cls
Loop until multikey(FB.SC_ESCAPE)
screenunlock
Sub DrawEllipse( ByVal X as Integer, ByVal Y as Integer, ByVal W as Integer, ByVal H as Integer, ByVal Ang as Integer )
'' Ellipse Drawing Positions
Dim as Integer EX, EY
'' Rotated Positions
Dim as Double RX, RY
'' Our Sin/Cos Angles. No reason to calculate it every step.
Dim as Double SinAng = Sin(DegToRad(Ang)), CosAng = Cos(DegToRad(Ang))
'' Custom Ratios. Normally this would be r*cos(ang)
Ex = ( W * Cos(0) )
Ey = ( H * -Sin(0) )
'' Rotate our Ellipse. We're rotating around our own center.
'' Since we didn't include our Drawing Positions, no complex math needed!
'' FYI: This is rotate around ourself math, using our own center as origin!
Rx = ( Ex * CosAng ) - ( Ey * SinAng )
Ry = ( Ey * CosAng ) + ( Ex * SinAng )
'' Draw First Point.
'' We don't include X in the above math so we can have rotation free from
'' Our Ellipse Center
Pset ( X + Rx, Y + Ry ), rgb(255, 255, 255)
'' Loop through our ellipse angles.
For CurAng as Double = 1 to 360
'' Custom Ratios instead of Rad
Ex = ( W * Cos(DegToRad(CurAng)) )
Ey = ( H * -Sin(DegToRad(CurAng)) )
'' Rotate our Ellipse
Rx = ( Ex * CosAng ) - ( Ey * SinAng )
Ry = ( Ey * CosAng ) + ( Ex * SinAng )
'' A version of Line (x,y) - step (x2, y2)
'' Except this is nothing but a step.
Line - ( X + Rx, Y + Ry ), rgb(255, 255, 255)
Next
End Sub
Here's the more advanced version:
Code: Select all
#include once "fbgfx.bi"
#define pi 3.14159265
#define RadToDeg(__rad__) (__rad__ * (180/Pi))
#define DegToRad(__rad__) (__rad__ * (pi/180))
'' An ellipse object.
'' Store info on the object here, render it.
Type Ellipse
'' Ellipse Drawing Center
X as Integer
Y as Integer
'' Width/Height Ratios
W as Integer
H as Integer
'' Rotation Angle
Rot as Double = 0
'' Start/End Ang
BegAng as Double = 0
EndAng as Double = 360
'' Direction. This is our loop step.
ArcStep as Integer = 1
'' Fill or not? 0 = No Fill. <> 0 = Fill
'' Only fills if BegAng is 0, and EndAng is 360
Fill as Integer = 0
'' Draw the Ellipse.
Declare Sub Draw()
End Type
Screenres 640, 480, 32
'' Our settings.
Dim as Ellipse MyArc
'' Position
MyArc.X = 319
MyArc.Y = 239
'' Size
MyArc.W = 60
MyArc.H = 60
Screenlock
Do
'' Get Key Presses
'' Move the Ellipse
If Multikey(FB.SC_LEFT) then MyArc.BegAng -= 1
If Multikey(FB.SC_RIGHT) then MyArc.BegAng += 1
If Multikey(FB.SC_UP) then MyArc.EndAng -= 1
If Multikey(FB.SC_DOWN) then MyArc.EndAng += 1
'' Change Ellipse Width
If Multikey(FB.SC_A) then MyArc.W -= 1
If Multikey(FB.SC_D) then MyArc.W += 1
'' Change Ellipse Height
If Multikey(FB.SC_W) then MyArc.H += 1
If Multikey(FB.SC_S) then MyArc.H -= 1
'' Increase Our Angle
MyArc.Rot += 1
'' Check all of our variables and make sure they are valid.
If MyArc.W < 1 then MyArc.W = 1
If MyArc.H < 1 then MyArc.H = 1
If MyArc.Rot > 359 then MyArc.Rot = 0
If MyArc.BegAng < 0 then MyArc.BegAng += 360
If MyArc.BegAng > 360 then MyArc.BegAng -= 360
If MyArc.EndAng < 0 then MyArc.EndAng += 360
If MyArc.EndAng > 360 then MyArc.EndAng -= 360
'' Reverse Drawing Direction if our End Angle's less than our start angle.
If MyArc.EndAng < MyArc.BegAng then
MyArc.ArcStep = -1
Else
MyArc.ArcStep = 1
End If
'' Fill if we have a full Ellipse.
If ( MyArc.BegAng = 0 ) then
If ( MyArc.EndAng = 360 ) then
MyArc.Fill = 1
Else
MyArc.Fill = 0
End If
Else
MyArc.Fill = 0
End If
'' Draw our ellipse.
MyArc.Draw()
'' "GUI" - Uhmm...Just text information ;p
'' Background
Line (0,0)-(250, 48), rgb(10, 20, 80), bf
Line (0,0)-(250, 48), rgb(80, 20, 10), b
Locate 1, 1
'' Text
Draw String (2,2), "Change Arc With Arrow Keys"
Draw String (2,10), "Stretch Ellipse with WASD"
Draw String (2,18), "Pos: " & "(" & str(MyArc.x) & "," & str(MyArc.y) & "," & str(MyArc.Rot) & ")"
Draw String (2,26), "W/H: " & "(" & str(MyArc.w) & "," & str(MyArc.h) & ")"
Draw String (2,34), "Start/End Ang: " & "(" & str(MyArc.BegAng) & "," & str(MyArc.EndAng) & ")"
'' Flip our Page
screenunlock
sleep 15, 1
screenlock
cls
Loop until multikey(FB.SC_ESCAPE)
screenunlock
Sub Ellipse.Draw()
'' Ellipse Drawing Positions
Dim as Integer EX, EY
'' Rotated Positions
Dim as Double RX, RY
'' Our Sin/Cos Angles. No reason to calculate it every step.
Dim as Double SinAng = Sin(DegToRad(This.Rot)), CosAng = Cos(DegToRad(This.Rot))
'' Custom Ratios. Normally this would be r*cos(ang)
Ex = ( This.W * Cos(DegToRad(This.BegAng)) )
Ey = ( This.H * -Sin(DegToRad(This.BegAng)) )
'' Rotate our Ellipse. We're rotating around our own center.
'' Since we didn't include our Drawing Positions, no complex math needed!
'' FYI: This is rotate around ourself math, using our own center as origin!
Rx = ( Ex * CosAng ) - ( Ey * SinAng )
Ry = ( Ey * CosAng ) + ( Ex * SinAng )
'' Draw First Point.
'' We don't include X in the above math so we can have rotation free from
'' Our Ellipse Center
Pset ( This.X + Rx, This.Y + Ry ), rgb(255, 255, 255)
'' Loop through our ellipse angles.
For CurAng as Double = This.BegAng + 1 to This.EndAng step This.ArcStep
'' Custom Ratios instead of Rad
Ex = ( This.W * Cos(DegToRad(CurAng)) )
Ey = ( This.H * -Sin(DegToRad(CurAng)) )
'' Rotate our Ellipse
Rx = ( Ex * CosAng ) - ( Ey * SinAng )
Ry = ( Ey * CosAng ) + ( Ex * SinAng )
'' A version of Line (x,y) - step (x2, y2)
'' Except this is nothing but a step.
Line - ( This.X + Rx, This.Y + Ry ), rgb(255, 255, 255)
Next
'' Fill our ellipse if we have chosen to do so.
If This.Fill <> 0 then
Paint (This.X, This.Y), rgb(255, 255, 255), rgb(255, 255, 255)
End If
End Sub
Code: Select all
Sub Ellipse.Draw()
'' Ellipse Drawing Positions
Dim As Integer EX, EY
'' Rotated Positions
Dim As Double RX, RY
'' Origin Position
Dim as Integer OX, OY
'' Our Sin/Cos Angles. No reason to calculate it every step.
Dim As Double SinAng = Sin(DegToRad(This.Rot)), CosAng = Cos(DegToRad(This.Rot))
'' Set an origin point for all of the ellipse drawing.
Ox = ( This.W * Cos(DegToRad(This.BegAng)) )
Oy = ( This.H * -Sin(DegToRad(This.BegAng)) )
'' Custom Ratios. Normally this would be r*cos(ang)
Ex = ( This.W * Cos(DegToRad(This.BegAng)) ) + OX
Ey = ( This.H * -Sin(DegToRad(This.BegAng)) ) + OY
'' Rotate our Ellipse. We're rotating around our own center.
'' Since we didn't include our Drawing Positions, no complex math needed!
'' FYI: This is rotate around ourself math, using our own center as origin!
Rx = ( Ex * CosAng ) - ( Ey * SinAng )
Ry = ( Ey * CosAng ) + ( Ex * SinAng )
'' Draw First Point.
'' We don't include X in the above math so we can have rotation free from
'' Our Ellipse Center
Pset ( This.X + Rx, This.Y + Ry ), rgb(255, 255, 255)
'' Loop through our ellipse angles.
For CurAng As Double = This.BegAng + 1 To This.EndAng Step This.ArcStep
'' Custom Ratios instead of Rad
Ex = ( This.W * Cos(DegToRad(CurAng)) ) + OX
Ey = ( This.H * -Sin(DegToRad(CurAng)) ) + OY
'' Rotate our Ellipse
Rx = ( Ex * CosAng ) - ( Ey * SinAng )
Ry = ( Ey * CosAng ) + ( Ex * SinAng )
'' A version of Line (x,y) - step (x2, y2)
'' Except this is nothing but a step.
Line - ( This.X + Rx, This.Y + Ry ), rgb(255, 255, 255)
Next
'' Fill our ellipse if we have chosen to do so.
If This.Fill <> 0 Then
Paint (This.X + Rx / 2, This.Y + Ry / 2), rgb(255, 255, 255), rgb(255, 255, 255)
End If
End Sub