Drawing an ellipse - PhilOfPerth - 07-01-2023
Is there a way provided for drawing an ellipse (an oval), without resorting to trig functions etc?
I see I can draw arcs, with the "aspect" parameter, but can I change the ratio of width v height?
RE: Drawing an ellipse - bplus - 07-01-2023
Oh I messed up this is easier than I thought to fit width and height: (leave the start and stop radians blank)
Code: (Select All) Screen _NewImage(800, 600, 32)
For aspect = .5 To 1.51 Step .1
Cls
Line (200, 100)-(600, 500), &HFFFF00FF, B
Circle (400, 300), 200, &HFFFFFF00, , , aspect
_PrintString (400 - 8, 300 - 8), _Trim$(Str$(aspect))
_Delay 2
Next
So to draw an ellipse with width and height:
Code: (Select All) Screen _NewImage(800, 600, 32)
Do
Cls
Input "Please enter height, width integers don't forget comma "; h, w
Line (400 - w / 2, 300 - h / 2)-(400 + w / 2, 300 + h / 2), &HFFFF0000, B
drawEllipse 400, 300, w, h, &HFFFFFF00
Sleep
Paint (400, 300), &HFF008800, &HFFFFFF00
Sleep
Loop
Sub drawEllipse (OriginX, OriginY, Wide, High, clr~&)
If Wide > High Then r = Wide / 2 Else r = High / 2
Circle (OriginX, OriginY), r, clr~&, , , High / Wide
End Sub
RE: Drawing an ellipse - PhilOfPerth - 07-01-2023
Thanks bplus.
I caught your earlier posts, and, would you believe, I found the first one the most helpful!
I experimented with it and ended up with this:
Code: (Select All) Screen _NewImage(800, 600, 32)
start:
Cls
Input "aspect"; aspect
Input "radius"; radius
Circle (400, 300), radius, , , , aspect
Sleep 5
GoTo start
Now, I'm trying to colour it... I still have trouble with this, but I'll get there.
RE: Drawing an ellipse - OldMoses - 07-01-2023
Would it be feasible to make an image of a circle, then use Rotozoom, which can scale the aspect ratio and rotate it too?
RE: Drawing an ellipse - bplus - 07-01-2023
(07-01-2023, 05:23 PM)OldMoses Wrote: Would it be feasible to make an image of a circle, then use Rotozoom, which can scale the aspect ratio and rotate it too?
Yeah sure, used that method for Tilting a Filled Ellipse, see also STaX method for tilted Ellipse:
Code: (Select All) Screen _NewImage(800, 600, 32)
EllipseTilt 100, 100, 100, 50, _Pi(1 / 4), &HFFFFFF00
fTiltEllipse 0, 400, 400, 100, 300, _Pi(1 / 3), &HFF0000FF
'thanks STxAxTIC from Toolbox
Sub EllipseTilt (CX, CY, a, b, ang, C As _Unsigned Long)
Dim k, i, j
' CX = center x coordinate
' CY = center y coordinate
' a = semimajor axis major radius
' b = semiminor axis minor radius
' ang = clockwise orientation of semimajor axis in radians (0 default)
' C = fill color
For k = 0 To 6.283185307179586 Step .025 'not sure about the stepper it should depend on a and b
i = a * Cos(k) * Cos(ang) + b * Sin(k) * Sin(ang)
j = -a * Cos(k) * Sin(ang) + b * Sin(k) * Cos(ang)
i = i + CX
j = -j + CY
If k <> 0 Then
Line -(i, j), C
Else
PSet (i, j), C
End If
Next
End Sub
'relace toolbox code 2019-12-16
'this needs RotoZoom3 to rotate image and EllipseFill to make the image BUT it can now scale it also!
Sub fTiltEllipse (destH As Long, ox As Long, oy As Long, majorRadius As Long, minorRadius As Long, radianAngle As Single, c As _Unsigned Long)
'setup isolated area, draw fFlatEllipse and then RotoZoom the image into destination
'ox, oy is center of ellipse
'majorRadius is 1/2 the lonest axis
'minorRadius is 1/2 the short axis
'radianAngle is the Radian Angle of Tilt
'c is of course color
Dim sd&, temp&
sd& = _Dest
temp& = _NewImage(2 * majorRadius, 2 * minorRadius, 32)
_Dest temp&
_DontBlend temp& '<< test 12-16
FEllipse majorRadius, minorRadius, majorRadius, minorRadius, c
'FEllipse majorRadius, minorRadius, majorRadius, minorRadius, c
_Blend temp& '<< test 12-16
_Dest destH
RotoZoom3 ox, oy, temp&, 1, 1, radianAngle
_FreeImage temp&
_Dest sd&
End Sub
Sub FEllipse (CX As Long, CY As Long, xr As Long, yr As Long, C As _Unsigned Long)
If xr = 0 Or yr = 0 Then Exit Sub
Dim h2 As _Integer64, w2 As _Integer64, h2w2 As _Integer64
Dim x As Long, y As Long
w2 = xr * xr: h2 = yr * yr: h2w2 = h2 * w2
Line (CX - xr, CY)-(CX + xr, CY), C, BF
Do While y < yr
y = y + 1
x = Sqr((h2w2 - y * y * w2) \ h2)
Line (CX - x, CY + y)-(CX + x, CY + y), C, BF
Line (CX - x, CY - y)-(CX + x, CY - y), C, BF
Loop
End Sub
'modified 2020-03-02 _seamless added, rotation convert to radians, fixed xScale and yScale for drawn image size in 000Graphics\Spike\...
Sub RotoZoom3 (X As Long, Y As Long, Image As Long, xScale As Single, yScale As Single, radianRotation As Single) ' 0 at end means no scaling of x or y
Dim px(3) As Single: Dim py(3) As Single
Dim W&, H&, sinr!, cosr!, i&, x2&, y2&
W& = _Width(Image&): H& = _Height(Image&)
px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
sinr! = Sin(-radianRotation): cosr! = Cos(-radianRotation)
For i& = 0 To 3
x2& = xScale * (px(i&) * cosr! + sinr! * py(i&)) + X: y2& = yScale * (py(i&) * cosr! - px(i&) * sinr!) + Y
px(i&) = x2&: py(i&) = y2&
Next
_MapTriangle _Seamless(0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
_MapTriangle _Seamless(0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
End Sub
Oh and even another method to draw the Filled Ellipse before RotoZoom3
RE: Drawing an ellipse - PhilOfPerth - 07-01-2023
(07-01-2023, 05:34 PM)bplus Wrote: (07-01-2023, 05:23 PM)OldMoses Wrote: Would it be feasible to make an image of a circle, then use Rotozoom, which can scale the aspect ratio and rotate it too?
Yeah sure, used that method for Tilting a Filled Ellipse, see also STaX method for tilted Ellipse:
Code: (Select All) Screen _NewImage(800, 600, 32)
EllipseTilt 100, 100, 100, 50, _Pi(1 / 4), &HFFFFFF00
fTiltEllipse 0, 400, 400, 100, 300, _Pi(1 / 3), &HFF0000FF
'thanks STxAxTIC from Toolbox
Sub EllipseTilt (CX, CY, a, b, ang, C As _Unsigned Long)
Dim k, i, j
' CX = center x coordinate
' CY = center y coordinate
' a = semimajor axis major radius
' b = semiminor axis minor radius
' ang = clockwise orientation of semimajor axis in radians (0 default)
' C = fill color
For k = 0 To 6.283185307179586 Step .025 'not sure about the stepper it should depend on a and b
i = a * Cos(k) * Cos(ang) + b * Sin(k) * Sin(ang)
j = -a * Cos(k) * Sin(ang) + b * Sin(k) * Cos(ang)
i = i + CX
j = -j + CY
If k <> 0 Then
Line -(i, j), C
Else
PSet (i, j), C
End If
Next
End Sub
'relace toolbox code 2019-12-16
'this needs RotoZoom3 to rotate image and EllipseFill to make the image BUT it can now scale it also!
Sub fTiltEllipse (destH As Long, ox As Long, oy As Long, majorRadius As Long, minorRadius As Long, radianAngle As Single, c As _Unsigned Long)
'setup isolated area, draw fFlatEllipse and then RotoZoom the image into destination
'ox, oy is center of ellipse
'majorRadius is 1/2 the lonest axis
'minorRadius is 1/2 the short axis
'radianAngle is the Radian Angle of Tilt
'c is of course color
Dim sd&, temp&
sd& = _Dest
temp& = _NewImage(2 * majorRadius, 2 * minorRadius, 32)
_Dest temp&
_DontBlend temp& '<< test 12-16
FEllipse majorRadius, minorRadius, majorRadius, minorRadius, c
'FEllipse majorRadius, minorRadius, majorRadius, minorRadius, c
_Blend temp& '<< test 12-16
_Dest destH
RotoZoom3 ox, oy, temp&, 1, 1, radianAngle
_FreeImage temp&
_Dest sd&
End Sub
Sub FEllipse (CX As Long, CY As Long, xr As Long, yr As Long, C As _Unsigned Long)
If xr = 0 Or yr = 0 Then Exit Sub
Dim h2 As _Integer64, w2 As _Integer64, h2w2 As _Integer64
Dim x As Long, y As Long
w2 = xr * xr: h2 = yr * yr: h2w2 = h2 * w2
Line (CX - xr, CY)-(CX + xr, CY), C, BF
Do While y < yr
y = y + 1
x = Sqr((h2w2 - y * y * w2) \ h2)
Line (CX - x, CY + y)-(CX + x, CY + y), C, BF
Line (CX - x, CY - y)-(CX + x, CY - y), C, BF
Loop
End Sub
'modified 2020-03-02 _seamless added, rotation convert to radians, fixed xScale and yScale for drawn image size in 000Graphics\Spike\...
Sub RotoZoom3 (X As Long, Y As Long, Image As Long, xScale As Single, yScale As Single, radianRotation As Single) ' 0 at end means no scaling of x or y
Dim px(3) As Single: Dim py(3) As Single
Dim W&, H&, sinr!, cosr!, i&, x2&, y2&
W& = _Width(Image&): H& = _Height(Image&)
px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
sinr! = Sin(-radianRotation): cosr! = Cos(-radianRotation)
For i& = 0 To 3
x2& = xScale * (px(i&) * cosr! + sinr! * py(i&)) + X: y2& = yScale * (py(i&) * cosr! - px(i&) * sinr!) + Y
px(i&) = x2&: py(i&) = y2&
Next
_MapTriangle _Seamless(0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
_MapTriangle _Seamless(0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
End Sub
Oh and even another method to draw the Filled Ellipse before RotoZoom3
Could the DRAW ("TAn...") (turn-angle) be incorporated into the CIRCLE command, or vice versa? maybe using the Varptr thingy?
RE: Drawing an ellipse - mnrvovrfc - 07-02-2023
(07-01-2023, 11:26 PM)PhilOfPerth Wrote: Could the DRAW ("TAn...") (turn-angle) be incorporated into the CIRCLE command, or vice versa? maybe using the Varptr thingy?
It would be a 360-sided shape then, not a circle. Then it would take more calculation to draw it at an aspect ratio which is not 1 (which is perfect circle).
RE: Drawing an ellipse - PhilOfPerth - 07-02-2023
(07-02-2023, 01:07 AM)mnrvovrfc Wrote: (07-01-2023, 11:26 PM)PhilOfPerth Wrote: Could the DRAW ("TAn...") (turn-angle) be incorporated into the CIRCLE command, or vice versa? maybe using the Varptr thingy?
It would be a 360-sided shape then, not a circle. Then it would take more calculation to draw it at an aspect ratio which is not 1 (which is perfect circle).
Got it! Thanks Minerva. Back to the drawing board.
RE: Drawing an ellipse - OldMoses - 07-02-2023
I know you wanted to avoid trig functions, but they are rather handy in this case. Here is one of the simplest trig methods I've found to construct an elliptical shape. The granularity of the image is 1/100th of a radian, so it is quite smooth to the eye. At least as good as my old eyes and laptop screen can reveal.
Code: (Select All) 'de La Hire's method of ellipse
'geometric construction of two concentric circles
'the outermost diameter equals the desired ellipse's
'semi major axis, while the inner circle matches the
'semi minor axis.
'a full 360ø rotation is executed and the positions
'are plotted using a COS function of the outer circle's
'resulting X position and SIN function of the inner
'circle's Y position.
SCREEN _NEWIMAGE(1024, 512, 32)
cen_x% = 512 ' screen center x
cen_y% = 256 ' screen center y
semi_maj% = 200 ' Semi major axis of ellipse i.e. outer circle
semi_min% = 50 ' Semi minor axis of ellipse i.e. inner circle
PSET (semi_maj% + cen_x%, cen_y%) ' pre-position graphics cursor
FOR ang = 0 TO 2 * _PI STEP .01 ' granularity of 1/100 radian
x% = semi_maj% * COS(ang) + cen_x% ' x position a COS function of the outer circle
y% = semi_min% * SIN(ang) + cen_y% ' y position a SIN function of the inner circle
LINE STEP(0, 0)-(x%, y%) ' line from previous cursor position
NEXT ang
RE: Drawing an ellipse - PhilOfPerth - 07-03-2023
(07-02-2023, 02:12 AM)OldMoses Wrote: I know you wanted to avoid trig functions, but they are rather handy in this case. Here is one of the simplest trig methods I've found to construct an elliptical shape. The granularity of the image is 1/100th of a radian, so it is quite smooth to the eye. At least as good as my old eyes and laptop screen can reveal.
Code: (Select All) 'de La Hire's method of ellipse
'geometric construction of two concentric circles
'the outermost diameter equals the desired ellipse's
'semi major axis, while the inner circle matches the
'semi minor axis.
'a full 360ø rotation is executed and the positions
'are plotted using a COS function of the outer circle's
'resulting X position and SIN function of the inner
'circle's Y position.
SCREEN _NEWIMAGE(1024, 512, 32)
cen_x% = 512 ' screen center x
cen_y% = 256 ' screen center y
semi_maj% = 200 ' Semi major axis of ellipse i.e. outer circle
semi_min% = 50 ' Semi minor axis of ellipse i.e. inner circle
PSET (semi_maj% + cen_x%, cen_y%) ' pre-position graphics cursor
FOR ang = 0 TO 2 * _PI STEP .01 ' granularity of 1/100 radian
x% = semi_maj% * COS(ang) + cen_x% ' x position a COS function of the outer circle
y% = semi_min% * SIN(ang) + cen_y% ' y position a SIN function of the inner circle
LINE STEP(0, 0)-(x%, y%) ' line from previous cursor position
NEXT ang
Thanks OM.
I can cope with those few trig terms.
When I run your code I get a perfect ellipse. But I was looking to change the angle (the two axes of the ellipse). I'm experimenting with ang at the moment.
No luck so far.
|