Drawing an ellipse
#1
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?
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Reply
#2
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
b = b + ...
Reply
#3
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.  Big Grin
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Reply
#4
Would it be feasible to make an image of a circle, then use Rotozoom, which can scale the aspect ratio and rotate it too?
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#5
(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
b = b + ...
Reply
#6
(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?
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Reply
#7
(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).
Reply
#8
(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. Smile
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Reply
#9
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


Attached Files Image(s)
   
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#10
(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.  Smile
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.
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Reply




Users browsing this thread: 5 Guest(s)