Drawing an ellipse
#21
"gob·ble·dy·gook" = your instructions when served oatmeal.

@PhilOfPerth I like OldMoses tilted ellipse too, going to compare th STx I posted here
https://staging.qb64phoenix.com/showthre...8#pid17438
that I think Steve reposted. The Tilted Fill from Steve is different though (pretty complex!).

Don't like "semi axis" stuff which is like an x radius and a y radius for ellipse ie 2 radii for an ellipse as comapred to one for circle. Fitting a tilted ellipse inside a Width Height rectangle is no longer simple.

Now how you do this with Draw commands and without Trig, that's something! But it might be done with Pythagorus and some rotations.
b = b + ...
Reply
#22
(07-03-2023, 12:13 PM)bplus Wrote: Now how you do this with Draw commands and without Trig, that's something! But it might be done with Pythagorus and some rotations.
I've been trying to suss out how one might go about this using my standard vector functions (which require a good bit of setup overhead). The more I've struggled with it, the more I'm convinced the de La Hire and rotation matrix method is the way to go. After almost 100 lines of code that doesn't work, as opposed to a dozen or so that work fine using a couple SIN & COS functions, I'm about ready to throw in the towel on a non-trig solution. Even the vector approach would need 'some' trig to keep it manageable.
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#23
I was working on titled ellipse this afternoon, got through drawing an ellipse without trig but then I realized I needed trig to rotate all the points for tilting it, dang!

But got another idea! A doozy that should work with Draw!
b = b + ...
Reply
#24
I can't wait! I'm sure if it can be done, you'll do it!
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Reply
#25
LOL you know those dreams you have this brilliant idea and then awake you realize the folly and say, "What was I thinking?"

I can do the ellipse without trig but I need the trig in Point rotation for tilt:
Code: (Select All)
_Title "Experiment with Ellipse" 'b+ 2023-07-04
Type xy
    As Single x, y
End Type
Screen _NewImage(800, 600, 32)
_ScreenMove 250, 60

For tilt = 0 To 360 Step .25
    Line (0, 0)-(_Width, _Height), &H05000000, BF
    drawTiltedEllipse 400, 300, 250, 150, tilt, &HFFFFFF00
    _Limit 30
Next
Sub drawTiltedEllipse (xc, yc, xRadius, yRadius, Tilt, clr~&)
    ReDim a(xRadius * 4) As xy
    r2 = xRadius * xRadius
    fit = yRadius / xRadius
    For x = xRadius To -xRadius Step -1
        y = fit * Sqr(r2 - x ^ 2)
        a(i).x = xc + x
        a(i).y = yc + y
        'PSet (a(i).x, a(i).y), clr~&
        i = i + 1
    Next
    For x = -xRadius + 1 To xRadius
        y = fit * Sqr(r2 - x ^ 2)
        a(i).x = xc + x
        a(i).y = yc - y
        'PSet (a(i).x, a(i).y), clr~&
        i = i + 1
    Next
    ReDim _Preserve a(i - 1) As xy
    Dim temp As xy
    Rotate 400, 300, a(0).x, a(0).y, Tilt, temp
    PSet (temp.x, temp.y), &HFF0000FF
    For i = LBound(a) + 1 To UBound(a)
        Rotate 400, 300, a(i).x, a(i).y, Tilt, temp
        Line -(temp.x, temp.y), &HFF0000FF
    Next
End Sub
Sub Rotate (cx, cy, x, y, degAng, a As xy)
    'cx, cy is center of rotation
    'x, y the point to rotate
    'degAng the angle in degrees to rotate
    ' output a.X, a.Y ' our point of rotation
    d = _Hypot(cx - x, cy - y) ' distance between xc and x
    ang = _Atan2(y - cy, x - cx)
    a.x = cx + d * Cos(ang + _D2R(degAng))
    a.y = cy + d * Sin(ang + _D2R(degAng))
End Sub
b = b + ...
Reply
#26
That's a nice effect. Very ephemeral, almost space theme-ish- looks like it's back-lit.
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Reply
#27
This is a rough proof of concept sort of thing, but it does trace out an ellipse. By drawing the figure in quarters, I didn't deal with the headaches of line stepping, so I just used PSET. This makes the semi-major axis points spread out to leave gaps. Left & right mouse buttons drag the foci points, while the mouse wheel changes the base radius of the thing. Mostly vector math and distance formula, you won't find a single trig function. Which is why it's so damn long.


Code: (Select All)
'Vector Math Ellipse- OldMoses
TYPE V2
    x AS SINGLE
    y AS SINGLE
END TYPE

DIM AS V2 foci(1), fcomp(1), quad(3), origin, center, smaj, smin, smaj_n, smin_n, pt0, pt1, orth

SCREEN _NEWIMAGE(1024, 512, 32)

base_rad% = 100 '                                                   starting circle base radius
origin.x = 0: origin.y = 0 '
foci(0).x = 200: foci(0).y = 150
foci(1).x = 300: foci(1).y = 200

DO
    CLS
    WHILE _MOUSEINPUT
        base_rad% = base_rad% + _MOUSEWHEEL '                       base circle size
    WEND
    IF _MOUSEBUTTON(1) THEN R2_Mouse foci(0) '                      move foci(0) to left click position

    IF _MOUSEBUTTON(2) THEN R2_Mouse foci(1) '                      move foci(1) to right click position

    total% = _SHL(base_rad%, 1)

    R2_FCenter center, foci(0), foci(1) '                           compute center from foci data
    fcomp(0) = foci(0): R2_Add fcomp(0), center, -1 '               translate foci(0) relative to center as origin
    fcomp(1) = foci(1): R2_Add fcomp(1), center, -1 '               translate foci(1) relative to center as origin

    smaj = foci(0): R2_Add smaj, center, -1 '                       subtract foci from center to obtain semi-major axis vector <smaj>
    IF R2_Mag(smaj) = 0 THEN smaj.x = 1 '                           convert <smaj> to i-hat if <smaj> becomes a zero vector
    smin.x = smaj.y '                                               get minor axis orthogonal
    smin.y = -smaj.x

    FOR f% = 0 TO 1: CIRCLE (foci(f%).x, foci(f%).y), 3: NEXT f% '  draw marker circles at foci
    CIRCLE (center.x, center.y), 2 '                                draw marker circle at center
    'CIRCLE (center.x, center.y), base_rad% '                        draw base radius circle
    FOR x% = 1 TO base_rad% '                                       work along the semimajor axis one point at a time
        R2_Norm smaj, smaj, x% '                                    grow major axis vector
        R2_Norm smaj_n, smaj, -R2_Mag(smaj) '                       get its inverted twin
        flag = 0: m% = 0
        DO
            m% = m% + 1 '                                           grow an orthogonal <smin> from that point
            R2_Norm smin, smin, m%
            pt0 = smaj: R2_Add pt0, smin, 1: R2_Add pt0, fcomp(0), -1 '
            pt1 = smaj: R2_Add pt1, smin, 1: R2_Add pt1, fcomp(1), -1 '
            IF R2_Mag(pt0) + R2_Mag(pt1) >= total% THEN '           until its magnitude equals the hypotenuse to both foci
                R2_Norm smin_n, smin, -R2_Mag(smin) '               get its inverted twin
                flag = -1
            END IF
        LOOP UNTIL flag
        FOR curve% = 0 TO 3 '                                       plot point at each quadrant
            IF curve% MOD 2 = 0 THEN orth = smin ELSE orth = smin_n
            IF curve% > 1 THEN quad(curve%) = smaj_n ELSE quad(curve%) = smaj
            R2_Add quad(curve%), orth, 1 '                          add semi-major and semi-minor moves
            R2_Add quad(curve%), center, 1 '                        and add center position to result
            PSET (quad(curve%).x, quad(curve%).y), &HFFFF00FF '     plot the point
        NEXT curve%
    NEXT x%
    _DISPLAY
    _LIMIT 30
LOOP UNTIL _KEYDOWN(27)
END

SUB R2_Add (re AS V2, se AS V2, m AS SINGLE) 'Add a scalar multiple of <se> to <re>
    re.x = re.x + se.x * m
    re.y = re.y + se.y * m
END SUB 'R2_Add

SUB R2_FCenter (re AS V2, f AS V2, f1 AS V2) 'find center <re> between two points <f> & <f1>
    re = f1 '                                                       set center to second foci initially
    R2_Add re, f, -1 '                                              subtract first foci from center
    R2_Add re, re, -.5 '                                            subtract 1/2 of center from center
    R2_Add re, f, 1 '                                               add 1/2 center to first foci
END SUB 'R2_FCenter

FUNCTION R2_Mag! (v AS V2) 'Obtain magnitude of <v>
    R2_Mag! = _HYPOT(v.x, v.y)
END FUNCTION 'R2_Mag!

SUB R2_Mouse (re AS V2)
    re.x = _MOUSEX
    re.y = _MOUSEY
END SUB 'R2_Mouse

SUB R2_Norm (re AS V2, v AS V2, scalar AS INTEGER) 'grow <v> to scalar length <re>
    x! = v.x: y! = v.y
    m! = _HYPOT(x!, y!)
    IF m! = 0 THEN
        re.x = 0: re.y = 0
    ELSE
        re.x = (x! / m!) * scalar
        re.y = (y! / m!) * scalar
    END IF
END SUB 'R2_Norm
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply




Users browsing this thread: 5 Guest(s)