Math's Trig Versus Basic's Trig Functions
#21
This is really good stuff. Hoping to learn a little trig I punted on in high school. Just enough to attempt some calculator functions in the future, if feasible.

Pete
Reply
#22
x = cx + r * cos(RadianAngle)
y = cy + r * sin(RadianAngle)
r = radial distance between x, y and cx, cy or r = SQR((x-cx)^2 + (y-cy)^2)

Yeah, for graphics it is really useful in plotting points (x,y) about another point (cx, cy): a given distance ( r ) and a given angle (RadianAngle = _D2R(DegreeAngle) ) from another point.
b = b + ...
Reply
#23
You forget, I'm a Conservative. I want an X and Y that solve for themselves!

A lot of folks go right back to approximation routines. Honestly, I wonder how close we are getting to a time where if technology dies, there will not be enough old school knowledge left to rebuild it. Scary thought.

Pete
Reply
#24
The Main difference between Math and Basic is Y axis in graphs. In math the Y values increase going up the axis vertically and in Basic y values decrease going up vertically.

This is an artifact from the fact we had printers long before screens to draw graphs and rows started at 1 and increased going down the page. If there were any graphics they were printed not drawn in text screens with characters not pixels.

In Basic, because the Y axis is flipped (and the X axis is not) angles increase going clockwise about any point including the origin which is another difference between Math and Basic. The origin in Math typically is conceived to go right in middle of the view screen whereas in Basic it is hard coded to upper Left corner.

Both Math and Basic start angles due East of origin because Cos(0) = 1 and Sin(0) = 0, Cos() always has been associated with x coordinate and Sin() with the Y coordinate.
b = b + ...
Reply
#25
Thumbs Up 
Really great program! You have a good handle on the graphics under Basic.
Reply
#26
not saying anyone copied anyone but this demo feels a lot like one we've already had for years:

Code: (Select All)
SCREEN 12

' Origin in Cartesian coordinates. (Changes when mouse is clicked.)
OriginX = -100
OriginY = -100

' Point of interest in Cartesian coordinates. (Changes while mouse moves.)
x = _MOUSEX
y = _MOUSEY
IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN
    GOSUB unconvert
    OriginX = x
    OriginY = y
ELSE
    ThePointX = 100
    ThePointY = 100
END IF

' Main loop.
DO
    DO WHILE _MOUSEINPUT
        x = _MOUSEX
        y = _MOUSEY
        IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN

            GOSUB unconvert
            ThePointX = x
            ThePointY = y

            IF _MOUSEBUTTON(1) THEN
                x = _MOUSEX
                y = _MOUSEY
                GOSUB unconvert
                OriginX = x
                OriginY = y
            END IF

        END IF
    LOOP
    GOSUB DrawEverything

LOOP

END

DrawEverything:
CLS
' Make Cartesian grid.
FOR x = OriginX TO 640 STEP 10
    LINE (x, 0)-(x, 480), 8
NEXT
FOR x = OriginX TO 0 STEP -10
    LINE (x, 0)-(x, 480), 8
NEXT
FOR y = OriginY TO 480 STEP 10
    LINE (0, -y + 240)-(640, -y + 240), 8
NEXT
FOR y = OriginY TO -240 STEP -10
    LINE (0, -y + 240)-(640, -y + 240), 8
NEXT
x = OriginX
y = OriginY
GOSUB convert
LINE (0, y)-(640, y), 7
LINE (x, 0)-(x, 480), 7
_PRINTSTRING (640 - 8 * 6, y), "X-axis"
_PRINTSTRING (x, 0), "Y-axis"
_PRINTSTRING (x, y), "Origin"
' Draw the circle on which the position vector lives.
Radius = SQR((ThePointX - OriginX) ^ 2 + (ThePointY - OriginY) ^ 2)
x = OriginX
y = OriginY
GOSUB convert
CIRCLE (x, y), Radius, 7
' Draw the vertical component.
x = OriginX
y = OriginY
GOSUB convert
x1 = x
y1 = y
x = ThePointX
y = OriginY
GOSUB convert
x2 = x
y2 = y
LINE (x1, y1)-(x2, y2), 9
LINE (x1, y1 + 1)-(x2, y2 + 1), 9
LINE (x1, y1 - 1)-(x2, y2 - 1), 9
' Draw the horizontal component.
x = ThePointX
y = OriginY
GOSUB convert
x1 = x
y1 = y
x = ThePointX
y = ThePointY
GOSUB convert
x2 = x
y2 = y
LINE (x1, y1)-(x2, y2), 4
LINE (x1 - 1, y1)-(x2 - 1, y2), 4
LINE (x1 + 1, y1)-(x2 + 1, y2), 4
' Draw position vector (aka the Hypotenuse).
x = OriginX
y = OriginY
GOSUB convert
x1 = x
y1 = y
x = ThePointX
y = ThePointY
GOSUB convert
x2 = x
y2 = y
LINE (x1, y1)-(x2, y2), 10
LINE (x1 + 1, y1)-(x2 + 1, y2), 10
LINE (x1, y1 + 1)-(x2, y2 + 1), 10
' Write text.
COLOR 7
LOCATE 1, 60: PRINT "-------Origin-------"
LOCATE 2, 60: PRINT "Cartesian/Polar/Qb64:"
LOCATE 3, 61: PRINT "X=0   , Y=0"
LOCATE 4, 61: PRINT "R=0   , Ang=undef"
LOCATE 5, 61: PRINT "x="; OriginX + 320; ", "; "y="; -OriginY + 240
LOCATE 7, 60: PRINT "-------Cursor-------"
LOCATE 8, 60: PRINT "Cartesian/Polar/Qb64:"
LOCATE 9, 61: PRINT "X="; ThePointX - OriginX; ", "; "Y="; ThePointY - OriginY
' Deal with radius calculation.
Radius = SQR((ThePointX - OriginX) ^ 2 + (ThePointY - OriginY) ^ 2)
IF Radius < .0001 THEN Radius = .0001
LOCATE 10, 61: PRINT "R="; INT(Radius); ", "; "Ang="; TheAngle
' Deal with the anlge calculation.
xdiff = ThePointX - OriginX
ydiff = ThePointY - OriginY
IF xdiff > 0 AND ydiff > 0 THEN ' First quadrant
    TheAngle = INT((180 / 3.14159) * ATN(ydiff / xdiff))
END IF
IF xdiff < 0 AND ydiff > 0 THEN ' Second quadrant
    TheAngle = 180 + INT((180 / 3.14159) * ATN(ydiff / xdiff))
END IF
IF xdiff < 0 AND ydiff < 0 THEN ' Third quadrant
    TheAngle = 180 + INT((180 / 3.14159) * ATN(ydiff / xdiff))
END IF
IF xdiff > 0 AND ydiff < 0 THEN ' Fourth quadrant
    TheAngle = 360 + INT((180 / 3.14159) * ATN(ydiff / xdiff))
END IF
IF SQR(ydiff ^ 2) < .0001 THEN ydiff = .0001
IF SQR(xdiff ^ 2) < .0001 THEN xdiff = .0001
LOCATE 11, 61: PRINT "x="; ThePointX + 320; ", "; "y="; -ThePointY + 240
LOCATE 13, 60: PRINT "--------Trig--------"
LOCATE 14, 61: PRINT "sin(Ang)=";: COLOR 4: PRINT "Opp";: COLOR 7: PRINT "/";: COLOR 10: PRINT "Hyp";: COLOR 7
LOCATE 15, 61: PRINT "        ="; USING "##.###"; ydiff / Radius
LOCATE 16, 61: PRINT "cos(Ang)=";: COLOR 9: PRINT "Adj";: COLOR 7: PRINT "/";: COLOR 10: PRINT "Hyp";: COLOR 7
LOCATE 17, 61: PRINT "        ="; USING "##.###"; xdiff / Radius
LOCATE 18, 61: PRINT "tan(Ang)=";: COLOR 4: PRINT "Opp";: COLOR 7: PRINT "/";: COLOR 9: PRINT "Adj";: COLOR 7
f = ydiff / xdiff
IF f < 9999.99 AND f > -9999.99 THEN
    LOCATE 19, 61: PRINT "        ="; USING "####.###"; f
END IF
_DISPLAY
RETURN

convert:
' Converts Cartesian coordinates to QB64 coordinates.
x0 = x: y0 = y
x = x0 + 320
y = -y0 + 240
RETURN

unconvert:
' Converts QB64 coordinates to Cartesian coordinates.
x0 = x: y0 = y
x = x0 - 320
y = -y0 + 240
RETURN
Reply
#27
This program has a major flaw. Because it's hardwired for "SCREEN 12", it also builds in the half-width and half-height.

Change "SCREEN 12" to "SCREEN _NEWIMAGE(...)" and the "320" and "240" near the bottom of the program to "_WIDTH \ 2" and "_HEIGHT \ 2" respectively. I didn't look at the whole source code: make other changes where needed. I say that because the program indicates converting to QB64 coordinates and therefore I felt there had to be an update to it.
Reply
#28
(10-04-2022, 02:28 PM)triggered Wrote: not saying anyone copied anyone but this demo feels a lot like one we've already had for years:

Code: (Select All)
SCREEN 12

' Origin in Cartesian coordinates. (Changes when mouse is clicked.)
OriginX = -100
OriginY = -100

' Point of interest in Cartesian coordinates. (Changes while mouse moves.)
x = _MOUSEX
y = _MOUSEY
IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN
    GOSUB unconvert
    OriginX = x
    OriginY = y
ELSE
    ThePointX = 100
    ThePointY = 100
END IF

' Main loop.
DO
    DO WHILE _MOUSEINPUT
        x = _MOUSEX
        y = _MOUSEY
        IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN

            GOSUB unconvert
            ThePointX = x
            ThePointY = y

            IF _MOUSEBUTTON(1) THEN
                x = _MOUSEX
                y = _MOUSEY
                GOSUB unconvert
                OriginX = x
                OriginY = y
            END IF

        END IF
    LOOP
    GOSUB DrawEverything

LOOP

END

DrawEverything:
CLS
' Make Cartesian grid.
FOR x = OriginX TO 640 STEP 10
    LINE (x, 0)-(x, 480), 8
NEXT
FOR x = OriginX TO 0 STEP -10
    LINE (x, 0)-(x, 480), 8
NEXT
FOR y = OriginY TO 480 STEP 10
    LINE (0, -y + 240)-(640, -y + 240), 8
NEXT
FOR y = OriginY TO -240 STEP -10
    LINE (0, -y + 240)-(640, -y + 240), 8
NEXT
x = OriginX
y = OriginY
GOSUB convert
LINE (0, y)-(640, y), 7
LINE (x, 0)-(x, 480), 7
_PRINTSTRING (640 - 8 * 6, y), "X-axis"
_PRINTSTRING (x, 0), "Y-axis"
_PRINTSTRING (x, y), "Origin"
' Draw the circle on which the position vector lives.
Radius = SQR((ThePointX - OriginX) ^ 2 + (ThePointY - OriginY) ^ 2)
x = OriginX
y = OriginY
GOSUB convert
CIRCLE (x, y), Radius, 7
' Draw the vertical component.
x = OriginX
y = OriginY
GOSUB convert
x1 = x
y1 = y
x = ThePointX
y = OriginY
GOSUB convert
x2 = x
y2 = y
LINE (x1, y1)-(x2, y2), 9
LINE (x1, y1 + 1)-(x2, y2 + 1), 9
LINE (x1, y1 - 1)-(x2, y2 - 1), 9
' Draw the horizontal component.
x = ThePointX
y = OriginY
GOSUB convert
x1 = x
y1 = y
x = ThePointX
y = ThePointY
GOSUB convert
x2 = x
y2 = y
LINE (x1, y1)-(x2, y2), 4
LINE (x1 - 1, y1)-(x2 - 1, y2), 4
LINE (x1 + 1, y1)-(x2 + 1, y2), 4
' Draw position vector (aka the Hypotenuse).
x = OriginX
y = OriginY
GOSUB convert
x1 = x
y1 = y
x = ThePointX
y = ThePointY
GOSUB convert
x2 = x
y2 = y
LINE (x1, y1)-(x2, y2), 10
LINE (x1 + 1, y1)-(x2 + 1, y2), 10
LINE (x1, y1 + 1)-(x2, y2 + 1), 10
' Write text.
COLOR 7
LOCATE 1, 60: PRINT "-------Origin-------"
LOCATE 2, 60: PRINT "Cartesian/Polar/Qb64:"
LOCATE 3, 61: PRINT "X=0   , Y=0"
LOCATE 4, 61: PRINT "R=0   , Ang=undef"
LOCATE 5, 61: PRINT "x="; OriginX + 320; ", "; "y="; -OriginY + 240
LOCATE 7, 60: PRINT "-------Cursor-------"
LOCATE 8, 60: PRINT "Cartesian/Polar/Qb64:"
LOCATE 9, 61: PRINT "X="; ThePointX - OriginX; ", "; "Y="; ThePointY - OriginY
' Deal with radius calculation.
Radius = SQR((ThePointX - OriginX) ^ 2 + (ThePointY - OriginY) ^ 2)
IF Radius < .0001 THEN Radius = .0001
LOCATE 10, 61: PRINT "R="; INT(Radius); ", "; "Ang="; TheAngle
' Deal with the anlge calculation.
xdiff = ThePointX - OriginX
ydiff = ThePointY - OriginY
IF xdiff > 0 AND ydiff > 0 THEN ' First quadrant
    TheAngle = INT((180 / 3.14159) * ATN(ydiff / xdiff))
END IF
IF xdiff < 0 AND ydiff > 0 THEN ' Second quadrant
    TheAngle = 180 + INT((180 / 3.14159) * ATN(ydiff / xdiff))
END IF
IF xdiff < 0 AND ydiff < 0 THEN ' Third quadrant
    TheAngle = 180 + INT((180 / 3.14159) * ATN(ydiff / xdiff))
END IF
IF xdiff > 0 AND ydiff < 0 THEN ' Fourth quadrant
    TheAngle = 360 + INT((180 / 3.14159) * ATN(ydiff / xdiff))
END IF
IF SQR(ydiff ^ 2) < .0001 THEN ydiff = .0001
IF SQR(xdiff ^ 2) < .0001 THEN xdiff = .0001
LOCATE 11, 61: PRINT "x="; ThePointX + 320; ", "; "y="; -ThePointY + 240
LOCATE 13, 60: PRINT "--------Trig--------"
LOCATE 14, 61: PRINT "sin(Ang)=";: COLOR 4: PRINT "Opp";: COLOR 7: PRINT "/";: COLOR 10: PRINT "Hyp";: COLOR 7
LOCATE 15, 61: PRINT "        ="; USING "##.###"; ydiff / Radius
LOCATE 16, 61: PRINT "cos(Ang)=";: COLOR 9: PRINT "Adj";: COLOR 7: PRINT "/";: COLOR 10: PRINT "Hyp";: COLOR 7
LOCATE 17, 61: PRINT "        ="; USING "##.###"; xdiff / Radius
LOCATE 18, 61: PRINT "tan(Ang)=";: COLOR 4: PRINT "Opp";: COLOR 7: PRINT "/";: COLOR 9: PRINT "Adj";: COLOR 7
f = ydiff / xdiff
IF f < 9999.99 AND f > -9999.99 THEN
    LOCATE 19, 61: PRINT "        ="; USING "####.###"; f
END IF
_DISPLAY
RETURN

convert:
' Converts Cartesian coordinates to QB64 coordinates.
x0 = x: y0 = y
x = x0 + 320
y = -y0 + 240
RETURN

unconvert:
' Converts QB64 coordinates to Cartesian coordinates.
x0 = x: y0 = y
x = x0 - 320
y = -y0 + 240
RETURN

Completely missed my point.
b = b + ...
Reply
#29
Here it is as simply stated as I can make it.

As angle increases, the points around a center point plot clockwise down from 3 o'clock to 6 o'clock and around to 9 o'clock then 12 o'clock and then back to 3 o'clock.

Code: (Select All)
_Title "... press any key to plot next point"
Screen _NewImage(800, 600, 32)
Print "Plot points around the center point according to Basic Cos(angle), Sin(angle)"
For angle = 0 To 2 * _Pi - .01 Step _Pi(2 / 36) ' <  these are 10 degree increments starting at 0
    x = 400 + 200 * Cos(angle)
    y = 300 + 200 * Sin(angle)
    _PrintString (x, y), Str$(Int(_R2D(angle) + .5)) ' <  this rounds radians to closest Degree
    Sleep
Next

I am not doing any Cartesian conversions, I am simply plotting points around a given one in a Basic graphics screen.

Notice the points go Clockwise around from the starting point 0 degrees or radians to full circle (2*Pi).
b = b + ...
Reply
#30
good explanations, bplus. This is probably why the original QB45 and VB for DOS only shipped with the ATN function and not Steve's new _ATAN2 -- that way you can can just pick to go either direction
Reply




Users browsing this thread: 16 Guest(s)