Code: (Select All)
'** TRIG Demo
'** By Terry Ritchie
'** 09/03/22
'** Created for the QB64 tutorial located at www.qb64tutorial.com
'------------------------------------------------------------------------------------------------------------
'Graphics Line Input Library by Terry Ritchie
'Creates interactive LINE INPUT statements
'$INCLUDE:'glinputtop.bi'
'------------------------------------------------------------------------------------------------------------
TYPE XYPAIR ' 2D point location definition
x AS SINGLE ' x coordinate
y AS SINGLE ' y coordinate
END TYPE
TYPE XY2PAIR ' two 2D point locations and associated vectors definition
p1 AS XYPAIR ' point 1 x,y
p2 AS XYPAIR ' point 2 x,y
p1v AS XYPAIR ' point 1 vectors
p2v AS XYPAIR ' point 2 vectors
END TYPE
TYPE VALUES ' display values definition
Vec AS XYPAIR ' calculated vector
Rad AS SINGLE ' calculated radian
Deg AS SINGLE ' calculated degree
x1 AS SINGLE ' point 1 x
x2 AS SINGLE ' point 2 x
y1 AS SINGLE ' point 1 y
y2 AS SINGLE ' point 2 y
END TYPE
CONST FALSE = 0, TRUE = NOT FALSE ' truth detectors
CONST PI = 3.1415926, PI2 = PI * 2 ' useful PI values
CONST DARKGRAY = _RGB32(96, 96, 96) ' define colors
CONST DARKERGRAY = _RGB32(32, 32, 32)
CONST YELLOW = _RGB32(255, 255, 0)
CONST RED = _RGB32(255, 0, 0)
CONST GREEN = _RGB32(0, 255, 0)
CONST WHITE = _RGB32(255, 255, 255)
CONST BLACK = _RGB32(0, 0, 0)
CONST DARKRED = _RGB32(127, 0, 0)
CONST CYAN = _RGB32(0, 255, 255)
CONST MAGENTA = _RGB32(255, 0, 255)
DIM Value AS VALUES ' calculated display values
DIM InputDegree AS INTEGER ' interactive degree input
DIM InputRadian AS INTEGER ' interactive radian input
DIM InputVector AS INTEGER ' interactive vector input
DIM InputPoint1 AS INTEGER ' interactive point 1 input
DIM InputPoint2 AS INTEGER ' interactive point 2 input
DIM RadianScreen AS LONG ' radian static screen image
DIM VectorScreen AS LONG ' vector static screen image
DIM CoordGrid AS LONG ' coordinate grid image
DIM CoordGridCopy AS LONG ' copy of coordinate grid image
DIM CurrentScreen AS INTEGER ' 0 for radian screen, 1 for vector screen
DIM ButtonDown AS INTEGER ' left mouse button status
SCREEN _NEWIMAGE(800, 600, 32) ' graphics screen
_TITLE "Trig Demo" ' give window a title
_SCREENMOVE _MIDDLE ' center window on desktop
_ICON ' use QB64 icon
DrawScreens ' create static screen images
DO ' begin main program loop
MakeGLInputs CurrentScreen ' create interactive inputs for current screen (library)
IF CurrentScreen = 0 THEN ' radian screen active?
ShowRadianScreen ' yes, switch to it
ELSE ' no, vector screen is active
ShowVectorScreen ' switch to it
END IF
LOOP UNTIL _KEYDOWN(27) ' leave when ESC key pressed
SYSTEM ' return to operating system
'----------------------------------------------------------------------------------------------------------------
SUB ShowVectorScreen ()
'** Display and interactive with the vector screen display
SHARED InputPoint1 AS INTEGER ' interactive point 1 input
SHARED InputPoint2 AS INTEGER ' interactive point 2 input
SHARED Value AS VALUES ' calculated display values
SHARED VectorScreen AS LONG ' static vector screen image
SHARED CurrentScreen AS INTEGER ' current screen showing
SHARED ButtonDown AS INTEGER ' left mouse button status
SHARED CoordGrid AS LONG ' coordinate grid image
SHARED CoordGridCopy AS LONG ' copy of coordinate grid image
DIM Vector AS XYPAIR ' vector values
DIM Radian AS SINGLE ' radian value
DIM Degree AS SINGLE ' degree value
DIM Coord AS XY2PAIR ' coordinates and vectors of points
DIM OldCoord AS XY2PAIR ' copy of current coordinates and vectors of points
DIM Speed AS INTEGER ' speed of moving points
DIM Radius AS SINGLE ' radius of circle to be drawn
DIM PlotVector AS XYPAIR ' vectors used to plot right triangle
DIM Intro AS INTEGER ' intro mode status
DIM Message AS STRING ' message to user
DIM Comma AS INTEGER ' comma location within input fields
DIM Ps1 AS STRING ' interactive point 1 input field
DIM Ps2 AS STRING ' interactive point 2 input field
DIM MsgTimer AS INTEGER ' 5 second count down message timer
RANDOMIZE TIMER ' seed the RND generator
Intro = TRUE ' enable intro mode
Speed = 2 ' set speed of moving points
Coord.p1.x = INT(RND * 360) ' random moving point coordinates
Coord.p1.y = INT(RND * 360)
Coord.p2.x = INT(RND * 360)
Coord.p2.y = INT(RND * 360)
P2PVector Coord.p1, Coord.p2, Coord.p1v ' vectors pointing at each other
P2PVector Coord.p2, Coord.p1, Coord.p2v
DO ' begin main loop
_LIMIT 60 ' restrict to 60 frames per second
GLICLEAR ' restore background image (library)
_PUTIMAGE , VectorScreen ' restore static vector screen
WHILE _MOUSEINPUT: WEND ' get latest mouse updates
IF NOT _MOUSEBUTTON(1) THEN ButtonDown = FALSE ' has mouse button been released?
IF _MOUSEBUTTON(1) AND NOT ButtonDown THEN ' left click and previously released?
IF _MOUSEX > 30 AND _MOUSEX < 152 AND _MOUSEY > 190 AND _MOUSEY < 225 THEN ' yes, within button?
CurrentScreen = 1 - CurrentScreen ' yes, switch to next screen
ButtonDown = TRUE ' remember mouse button is down
END IF
END IF
COLOR YELLOW ' yellow text
SELECT CASE GLICURRENT ' which input is user on? (library)
CASE InputPoint1 ' point1
LOCATE 11, 3: PRINT "From: X,Y 0-359,0-359"; ' display point format help
CASE InputPoint2 ' point2
LOCATE 11, 3: PRINT "To : X,Y 0-359,0-359"; ' display point format help
END SELECT
COLOR WHITE ' white text
OldCoord = Coord ' remember current point information
IF GLIENTERED(0) THEN ' both fields been ENTERed? (library)
Message = "" ' yes, reset message
Ps1 = GLIOUTPUT$(InputPoint1) ' get user input for point 1 (libaray)
Ps2 = GLIOUTPUT$(InputPoint2) ' get user input for point 2 (library)
IF INSTR(Ps1, ",") = 0 OR INSTR(Ps2, ",") = 0 THEN ' user forget commas?
SOUND 800, 1 ' yes, warning sound
Message = " YOU MUST SUPPLY A COORDINATE X,Y PAIR " ' message to user
MsgTimer = 360 ' 5 second count down timer
ELSE ' no, both fields have commas
Intro = FALSE ' leave intro mode
Comma = INSTR(Ps1, ",") ' comma location in first field
Coord.p1.x = INT(VAL(LEFT$(Ps1, Comma - 1))) ' get X1 coordinate
Coord.p1.y = INT(VAL(MID$(Ps1, Comma + 1, LEN(Ps1)))) ' get Y1 coordinate
Comma = INSTR(Ps2, ",") ' comma location in second field
Coord.p2.x = INT(VAL(LEFT$(Ps2, Comma - 1))) ' get X2 coordinate
Coord.p2.y = INT(VAL(MID$(Ps2, Comma + 1, LEN(Ps2)))) ' get Y2 coordinate
IF Coord.p1.x < 0 OR Coord.p1.x > 359 OR Coord.p2.x < 0 OR_
Coord.p2.x > 359 OR Coord.p1.y < 0 OR Coord.p1.y > 359 OR_
Coord.p2.y < 0 OR Coord.p2.y > 359 THEN ' values outside of limits?
SOUND 800, 1 ' yes, warning sound
Message = " VALUES CAN ONLY RANGE FROM 0 TO 359 " ' message to user
MsgTimer = 360 ' 5 second count down timer
Coord = OldCoord ' restore previous point information
END IF
END IF
GLICLOSE 0, TRUE ' close input fields (library)
MakeGLInputs 1 ' recreate input fields (library)
END IF
IF Intro THEN ' intro mode active?
Coord.p1.x = Coord.p1.x + Coord.p1v.x * Speed ' yes, move the points along vectors
Coord.p1.y = Coord.p1.y + Coord.p1v.y * Speed
Coord.p2.x = Coord.p2.x + Coord.p2v.x * Speed
Coord.p2.y = Coord.p2.y + Coord.p2v.y * Speed
IF Coord.p1.x <= 0 OR Coord.p1.x > 359 THEN Coord.p1v.x = -Coord.p1v.x ' keep points within boundary
IF Coord.p1.y <= 0 OR Coord.p1.y > 359 THEN Coord.p1v.y = -Coord.p1v.y
IF Coord.p2.x <= 0 OR Coord.p2.x > 359 THEN Coord.p2v.x = -Coord.p2v.x
IF Coord.p2.y <= 0 OR Coord.p2.y > 359 THEN Coord.p2v.y = -Coord.p2v.y
END IF
IF _HYPOT(Coord.p2.x - Coord.p1.x, Coord.p2.y - Coord.p1.y) = 0 THEN ' same coordinates both fields?
SOUND 800, 1 ' yes, warning sounds
Message = " SUPPLY TWO DIFFERENT COORDINATE VALUES " ' message to user
MsgTimer = 360 ' 5 second count down timer
Coord = OldCoord ' restore previous point information
END IF
P2PVector Coord.p1, Coord.p2, Vector ' get vector between the points
Radian = Vector2Radian(Vector) ' calculate radian from vector
Degree = Radian2Degree(Radian) ' calculate degree from radian
Value.Vec.x = Vector.x ' record screen values
Value.Vec.y = Vector.y
Value.Rad = Radian
Value.Deg = Degree
Value.x1 = Coord.p1.x
Value.y1 = Coord.p1.y
Value.x2 = Coord.p2.x
Value.y2 = Coord.p2.y
UpdateScreenValues ' display screen values
Radius = _HYPOT(Coord.p2.x - Coord.p1.x, Coord.p2.y - Coord.p1.y) ' calculate distance between points
PlotVector.x = Coord.p1.x + Vector.x * Radius ' plot second point on circle
PlotVector.y = Coord.p1.y + Vector.y * Radius
_DEST CoordGrid ' switch to grid image
_PUTIMAGE (0, 0), CoordGridCopy ' restore the grid image
LINE (PlotVector.x, PlotVector.y)-(Coord.p1.x, Coord.p1.y), YELLOW 'draw right triangle
LINE -(PlotVector.x, Coord.p1.y), GREEN
LINE -(PlotVector.x, PlotVector.y), RED
CIRCLE (Coord.p1.x, Coord.p1.y), Radius, DARKGRAY ' draw circle between points
CIRCLE (Coord.p1.x, Coord.p1.y), 3, CYAN ' draw first point
PAINT (Coord.p1.x, Coord.p1.y), CYAN, CYAN
CIRCLE (PlotVector.x, PlotVector.y), 3, MAGENTA ' draw second point
PAINT (PlotVector.x, PlotVector.y), MAGENTA, MAGENTA
_DEST 0 ' switch to vector screen
_PUTIMAGE (225, 20), CoordGrid ' display grid coordinate image
IF LEN(Message) THEN ' does an error message exist?
COLOR YELLOW, DARKRED ' yes, yellow text dark red background
LOCATE 18, 51 - (LEN(Message) / 2) ' center text
PRINT Message; ' print error message
COLOR WHITE, BLACK ' white text on black background
Intro = TRUE ' enable intro mode
MsgTimer = MsgTimer - 1 ' decrement count down timer
IF MsgTimer = 0 THEN Message = "" ' timer finished, remove message
END IF
GLIUPDATE ' update interactive inputs (library)
_DISPLAY ' update screen with changes
LOOP UNTIL CurrentScreen = 0 OR _KEYDOWN(27) ' leave when screen switched or ESC
GLICLOSE 0, TRUE ' close interactive inputs (library)
END SUB ' well that was fun! :p
'----------------------------------------------------------------------------------------------------------------
SUB UpdateScreenValues ()
'** Updates screen formula values
SHARED Value AS VALUES ' calculated display values
DIM x2_x1 AS SINGLE ' point 2 x - point 1 x
DIM y2_y1 AS SINGLE ' point 2 y - point 1 y
DIM x2_x1squared AS SINGLE ' point 2 x - point 1 x squared
DIM y2_y1squared AS SINGLE ' point 2 y - point 1 y squared
DIM hypot AS SINGLE ' distance between point 1 and point 2
x2_x1 = Value.x2 - Value.x1 ' calculate screen values
y2_y1 = Value.y2 - Value.y1
x2_x1squared = x2_x1 * x2_x1
y2_y1squared = y2_y1 * y2_y1
hypot = _HYPOT(x2_x1, y2_y1)
COLOR YELLOW, BLACK ' RESULT
LOCATE 3, 85: PRINT USING "###.####"; Value.Deg;
LOCATE 4, 87: PRINT USING "#.######"; Value.Rad;
LOCATE 5, 86: PRINT USING "##.###,##.###"; Value.Vec.x; Value.Vec.y;
LOCATE 24, 8: COLOR YELLOW: PRINT USING "#.######"; Value.Rad; ' RADIAN TO DEGREE
LOCATE 25, 8: PRINT USING "###.####"; Value.Deg;
LOCATE 29, 14: COLOR GREEN: PRINT USING "##.##"; Value.Vec.x; ' VECTOR TO DEGREE
LOCATE 29, 20: COLOR RED: PRINT USING "##.##"; Value.Vec.y;
LOCATE 30, 8: COLOR YELLOW: PRINT USING "###.####"; Value.Deg;
LOCATE 33, 21: COLOR GREEN: PRINT USING "###.##"; Value.x2; ' NORMALIZED VECTOR
LOCATE 33, 30: PRINT USING "###.##"; Value.x1;
LOCATE 33, 40: PRINT USING "####.##"; x2_x1;
LOCATE 34, 21: COLOR RED: PRINT USING "###.##"; Value.y2;
LOCATE 34, 30: PRINT USING "###.##"; Value.y1;
LOCATE 34, 40: PRINT USING "####.##"; y2_y1;
LOCATE 35, 29: COLOR GREEN: PRINT USING "######"; x2_x1squared;
LOCATE 35, 38: COLOR RED: PRINT USING "######"; y2_y1squared;
LOCATE 35, 48: COLOR YELLOW: PRINT USING "###.##"; hypot;
LOCATE 36, 20: COLOR GREEN: PRINT USING "####.#"; x2_x1;
LOCATE 36, 29: COLOR YELLOW: PRINT USING "###.##"; hypot;
IF hypot = 0 THEN ' same coordinates entered?
LOCATE 36, 40: COLOR GREEN: PRINT USING "##.###"; 0; ' yes, display 0 to avoid /0 error
LOCATE 37, 40: COLOR RED: PRINT USING "##.###"; 0;
ELSE
LOCATE 36, 40: COLOR GREEN: PRINT USING "##.###"; x2_x1 / hypot;
LOCATE 37, 40: COLOR RED: PRINT USING "##.###"; y2_y1 / hypot;
END IF
LOCATE 37, 20: COLOR RED: PRINT USING "####.#"; y2_y1;
LOCATE 37, 29: COLOR YELLOW: PRINT USING "###.##"; hypot;
LOCATE 24, 83: COLOR YELLOW: PRINT USING "###.##"; Value.Deg; ' DEGREE TO RADIAN
LOCATE 25, 83: PRINT USING "#.######"; Value.Rad;
LOCATE 28, 91: PRINT USING "#.######"; Value.Rad; ' RADIAN TO VECTOR
LOCATE 29, 91: PRINT USING "#.######"; Value.Rad;
LOCATE 30, 74: COLOR GREEN: PRINT USING "##.###"; Value.Vec.x;
LOCATE 30, 88: COLOR RED: PRINT USING "##.###"; Value.Vec.y;
LOCATE 34, 81: COLOR YELLOW: PRINT USING "###.##"; Value.Deg; ' DEGREE TO VECTOR
LOCATE 36, 82: PRINT USING "###.##"; Value.Deg;
LOCATE 37, 77: COLOR GREEN: PRINT USING "##.###"; Value.Vec.x;
LOCATE 37, 91: COLOR RED: PRINT USING "##.###"; Value.Vec.y;
COLOR WHITE, BLACK ' white text on black background
END SUB
'----------------------------------------------------------------------------------------------------------------
SUB ShowRadianScreen ()
'** Display and interactive with the radian screen display
SHARED Value AS VALUES ' calculated display values
SHARED RadianScreen AS LONG ' static radian screen image
SHARED CurrentScreen AS INTEGER ' current active screen
SHARED InputDegree AS INTEGER ' interactive degree input
SHARED InputRadian AS INTEGER ' interactive radian input
SHARED InputVector AS INTEGER ' interactive vector input
SHARED ButtonDown AS INTEGER ' left mouse button status
DIM Idegree AS SINGLE ' interactive degree input value
DIM Iradian AS SINGLE ' interactive radian input value
DIM Ivector AS STRING * 10 ' interactive vector input string
DIM Ivec AS XYPAIR ' vector pair entered by user
DIM ZeroZero AS XYPAIR ' 0,0 coordinate (center of circle)
DIM PlotVector AS XYPAIR ' vectors used to plot right triangle
DIM Message AS STRING ' message to user
DIM Intro AS INTEGER ' intro mode status
DIM Comma AS INTEGER ' comma location within vector input field
DIM Vector AS XYPAIR ' vector coordinates
DIM Radian AS SINGLE ' radian value
DIM Degree AS SINGLE ' degree value
DIM OneDg AS SINGLE ' one radian degree
DIM MsgTimer AS INTEGER ' 5 second count down message timer
OneDg = .01745329 ' one radian degree
Intro = TRUE ' enable intro mode
DO ' begin main loop
_LIMIT 60 ' restrict to 60 frames per second
GLICLEAR ' restore background image (library)
_PUTIMAGE , RadianScreen ' restore static radian screen
WHILE _MOUSEINPUT: WEND ' get latest mouse updates
IF NOT _MOUSEBUTTON(1) THEN ButtonDown = FALSE ' was mouse button released?
IF _MOUSEBUTTON(1) AND NOT ButtonDown THEN ' mouse click and previously released?
IF _MOUSEX > 30 AND _MOUSEX < 152 AND _MOUSEY > 190 AND _MOUSEY < 225 THEN ' yes, within button?
CurrentScreen = 1 - CurrentScreen ' switch screens
ButtonDown = TRUE ' remember mouse button down
END IF
END IF
COLOR YELLOW ' yellow text
SELECT CASE GLICURRENT ' which input is user on? (library)
CASE InputDegree ' degree
LOCATE 11, 4: PRINT "0 - 360 for Degree"; ' display degree limit help
CASE InputRadian ' radian
LOCATE 11, 3: PRINT "0 - 6.28 for Radian"; ' display radian limit help
CASE InputVector ' vector
LOCATE 11, 5: PRINT CHR$(241); "X, "; CHR$(241); "Y for vector"; ' display vector format help
END SELECT
COLOR WHITE ' white text
IF GLIENTERED(InputDegree) THEN ' ENTER pressed on Degree? (library)
Message = "" ' yes, reset error message
Idegree = VAL(GLIOUTPUT$(InputDegree)) ' get value of degree input (library)
IF Idegree < 0 OR Idegree > 360 THEN ' degree within limits?
SOUND 880, 1 ' no, warning beep
Message = " DEGREE MUST BE 0 THROUGH 360 " ' set error message
MsgTimer = 360 ' 5 second count down timer
ELSE ' yes, degree within limits
Intro = FALSE ' leave intro mode
Degree = Idegree ' set degree
Radian = Degree2Radian(Idegree) ' calculate radian from degree
Radian2Vector Radian, Vector ' calculate vector from radian
END IF
GLICLOSE 0, TRUE ' remove interactive inputs (library)
MakeGLInputs 0 ' recreate interactive inputs (library)
GLIFORCE InputDegree ' force cursor to degree (library)
ELSEIF GLIENTERED(InputRadian) THEN ' ENTER pressed on Radian? (libaray)
Message = "" ' yes, reset error message
Iradian = VAL(GLIOUTPUT$(InputRadian)) ' get value of radian input (library)
IF Iradian < 0 OR Iradian > PI2 THEN ' radian within limits?
SOUND 880, 1 ' no, warning beep
Message = " RADIAN MUST BE 0 THROUGH 6.2831852 " ' set error message
MsgTimer = 360 ' 5 second count down timer
ELSE ' yes, radian within limits
Intro = FALSE ' leave intro mode
Radian = Iradian ' set radian
Degree = Radian2Degree(Radian) ' calculate degree from radian
Radian2Vector Radian, Vector ' calculate vector from radian
END IF
GLICLOSE 0, TRUE ' remove interactive inputs (library)
MakeGLInputs 0 ' recreate interactive inputs (library)
GLIFORCE InputRadian ' force cursor to radian (library)
ELSEIF GLIENTERED(InputVector) THEN ' ENTER pressed on Vector? (library)
Message = "" ' yes, reset error message
Ivector = GLIOUTPUT$(InputVector) ' get vector string (library)
Comma = INSTR(Ivector, ",") ' get comma placement from string
IF Comma = 0 THEN ' was a comma found?
SOUND 880, 1 ' no, warning beep
Message = " VECTOR MUST BE TWO VALUES SEPARATED BY A COMMA " ' set error message
MsgTimer = 360 ' 5 second count down timer
ELSE ' yes, a comma was found
Intro = FALSE ' leave intro mode
Ivec.x = VAL(LEFT$(Ivector, Comma - 1)) ' get value of X vector
Ivec.y = VAL(MID$(Ivector, Comma + 1, LEN(Ivector))) ' get value of Y vector
P2PVector ZeroZero, Ivec, Vector ' calculate normalized vector
Radian = Vector2Radian(Vector) ' calculate radian from vector
Degree = Radian2Degree(Radian) ' calculate radian from degree
END IF
GLICLOSE 0, TRUE ' remove interactive inputs (library)
MakeGLInputs 0 ' recreate interactive inputs (library)
GLIFORCE InputVector ' force cursor to Vector (library)
END IF
IF Intro THEN ' intro mode enabled?
Radian = Radian + OneDg ' yes, increment radian by one degree
IF Radian > PI2 THEN Radian = 0 ' reset radian value if needed
Degree = Radian2Degree(Radian) ' calculate degree from radian
Radian2Vector Radian, Vector ' calculate vector from radian
END IF
IF _HYPOT(Vector.x, Vector.y) = 0 THEN ' 0,0 entered for vector?
Radian = 0 ' yes, naughty naughty
Degree = 0 ' set both to 0
END IF
Value.Vec.x = Vector.x ' record display values
Value.Vec.y = Vector.y
Value.Rad = Radian
Value.Deg = Degree
Value.x1 = 0
Value.y1 = 0
Value.x2 = Vector.x * 10
Value.y2 = Vector.y * 10
UpdateScreenValues ' display values to screen
PlotVector.x = 399 + Vector.x * 225 ' adjust vectors to circle perimeter
PlotVector.y = 246 + Vector.y * 225
LINE (PlotVector.x, PlotVector.y)-(399, 246), YELLOW ' draw hypotenuse these 3 lines draw
LINE -(PlotVector.x, 246), GREEN ' draw run the right triangle
LINE -(PlotVector.x, PlotVector.y), RED ' draw rise
IF LEN(Message) THEN ' does an error message exist?
COLOR YELLOW, DARKRED ' yes, yellow text dark red background
LOCATE 18, 51 - (LEN(Message) / 2) ' center text
PRINT Message; ' print error message
COLOR WHITE, BLACK ' white text on black background
Intro = TRUE ' enable intro mode
MsgTimer = MsgTimer - 1 ' decrement count down timer
IF MsgTimer = 0 THEN Message = "" ' timer finished, remove message
END IF
GLIUPDATE ' update interactive inputs (library)
_DISPLAY ' update screen with changes
LOOP UNTIL CurrentScreen = 1 OR _KEYDOWN(27) ' leave when screen shanges or ESC
GLICLOSE 0, TRUE ' close interactive inputs (library)
END SUB ' another long night of coding 8)
'----------------------------------------------------------------------------------------------------------------
SUB MakeGLInputs (S AS INTEGER)
'** Creates interactive inputs for Degree, Radian, ,Vector, Point 1, and Point 2
'S - current active screen (INPUT)
SHARED InputDegree AS INTEGER ' interactive degree input
SHARED InputRadian AS INTEGER ' interactive radian input
SHARED InputVector AS INTEGER ' interactive vector input
SHARED InputPoint1 AS INTEGER ' interactive point 1 input
SHARED InputPoint2 AS INTEGER ' interactive point 2 input
IF S = 0 THEN ' radian screen active?
COLOR YELLOW ' yes
InputDegree = GLIINPUT(16, 32, GLINUMERIC + GLISYMBOLS, "Degree: ", TRUE) ' create interactive
InputRadian = GLIINPUT(16, 48, GLINUMERIC + GLISYMBOLS, "Radian: ", TRUE) ' inputs (library)
InputVector = GLIINPUT(16, 64, GLINUMERIC + GLIDASH + GLISYMBOLS, "Vector: ", TRUE)
ELSE ' no, vector screen
COLOR CYAN ' create interactive
InputPoint1 = GLIINPUT(16, 32, GLINUMERIC + GLISYMBOLS, "X,Y (from): ", TRUE) ' inputs (library)
COLOR MAGENTA
InputPoint2 = GLIINPUT(16, 48, GLINUMERIC + GLISYMBOLS, "X,Y ( to ): ", TRUE)
END IF
COLOR WHITE ' white text
END SUB
'----------------------------------------------------------------------------------------------------------------
SUB DrawScreens ()
'** Draws the static screens
SHARED Vector AS XYPAIR ' vector coordinates
SHARED RadianScreen AS LONG ' static radian screen image
SHARED VectorScreen AS LONG ' static vector screen image
SHARED CoordGrid AS LONG ' coordinate grid image
SHARED CoordGridCopy AS LONG ' copy of coordinate grid image
DIM Rad AS SINGLE ' radian counter
DIM Api AS STRING * 1 ' ASCII pi symbol
DIM Adg AS STRING * 1 ' ASCII degree symbol
DIM Asq AS STRING * 1 ' ASCII squared symbol
RadianScreen = _NEWIMAGE(800, 600, 32) ' create static radian screen image
VectorScreen = _NEWIMAGE(800, 600, 32) ' create static vector screen image
CoordGrid = _NEWIMAGE(360, 360, 32) ' create coordinate grid image
_DEST RadianScreen ' switch to radian screen
CLS ' remove transparency
Api = CHR$(227) ' ASCII Pi symbol
Adg = CHR$(248) ' ASCII degree symbol
Asq = CHR$(253) ' ASCII squared exponent symbol
CLS ' clear screen
COLOR GREEN, DARKGRAY ' green text on dark gray background
LOCATE 2, 76: PRINT " RESULT "; ' print formula headings
LOCATE 27, 79: PRINT " RADIAN TO VECTOR ";
LOCATE 32, 79: PRINT " DEGREE TO VECTOR ";
LOCATE 22, 79: PRINT " DEGREE TO RADIAN ";
LOCATE 22, 3: PRINT " RADIAN TO DEGREE ";
LOCATE 27, 3: PRINT " VECTOR TO DEGREE ";
LOCATE 32, 3: PRINT " NORMALIZED VECTOR ";
COLOR WHITE, BLACK ' white text on black background
LOCATE 7, 79: PRINT "Vector has been";
LOCATE 8, 79: PRINT "normalized -1 to 1.";
LOCATE 6, 3: PRINT "Use arrow keys or TAB to"; ' print directions
LOCATE 7, 3: PRINT "move between the input";
LOCATE 8, 3: PRINT "fields. Press ENTER on";
LOCATE 9, 3: PRINT "selection. ESC to exit"
COLOR YELLOW
LOCATE 3, 77: PRINT "Degree:"; ' print result fields
LOCATE 4, 77: PRINT "Radian:";
LOCATE 5, 77: PRINT "Vector:";
'RADIAN TO DEGREE print formula fields
LOCATE 23, 2: COLOR YELLOW: PRINT "Deg";: COLOR WHITE: PRINT " = ";: COLOR YELLOW: PRINT "Rad";: COLOR WHITE
PRINT " * 180 / PI";
LOCATE 24, 2: COLOR YELLOW: PRINT "Deg";: COLOR WHITE: PRINT " = ";: COLOR YELLOW: PRINT "########";
COLOR WHITE: PRINT " * 57.29578";
LOCATE 25, 2: COLOR YELLOW: PRINT "Deg";: COLOR WHITE: PRINT " = ";: COLOR YELLOW: PRINT "########";
'VECTOR TO DEGREE
LOCATE 28, 2: COLOR YELLOW: PRINT "Deg";: COLOR WHITE: PRINT " = ATAN2(";: COLOR GREEN: PRINT "Vx";
COLOR WHITE: PRINT ", ";: COLOR RED: PRINT "Vy";: COLOR WHITE: PRINT ") * 180 / PI";
LOCATE 29, 2: COLOR YELLOW: PRINT "Deg";: COLOR WHITE: PRINT " = ATAN2(";: COLOR GREEN: PRINT "#####";
COLOR WHITE: PRINT ",";: COLOR RED: PRINT "#####";: COLOR WHITE: PRINT ") * 57.29578";
LOCATE 30, 2: COLOR YELLOW: PRINT "Deg";: COLOR WHITE: PRINT " = ";: COLOR YELLOW: PRINT "########";
'NORMALIZED VECTOR
LOCATE 33, 2: COLOR GREEN: PRINT "Vx";: COLOR WHITE: PRINT " = (";: COLOR GREEN: PRINT "x2";: COLOR WHITE
PRINT " - ";: COLOR GREEN: PRINT "x1";: COLOR WHITE: PRINT ") = (";: COLOR GREEN: PRINT "######";
COLOR WHITE: PRINT " - ";: COLOR GREEN: PRINT "######";: COLOR WHITE: PRINT ") = ";: COLOR GREEN
PRINT "######";
LOCATE 34, 2: COLOR RED: PRINT "Vy";: COLOR WHITE: PRINT " = (";: COLOR RED: PRINT "y2";: COLOR WHITE
PRINT " - ";: COLOR RED: PRINT "y1";: COLOR WHITE: PRINT ") = (";: COLOR RED: PRINT "######";: COLOR WHITE
PRINT " - ";: COLOR RED: PRINT "##.###";: COLOR WHITE: PRINT ") = ";: COLOR RED: PRINT "######";
LOCATE 35, 2: COLOR YELLOW: PRINT "Len";: COLOR WHITE: PRINT " = SQR(";: COLOR GREEN: PRINT "Vx"; Asq;
COLOR WHITE: PRINT " + ";: COLOR RED: PRINT "Vy"; Asq;: COLOR WHITE: PRINT ") = SQR(";: COLOR GREEN
PRINT "######";: COLOR WHITE: PRINT " + ";: COLOR RED: PRINT "######";: COLOR WHITE: PRINT ") = ";
COLOR YELLOW: PRINT "######";
LOCATE 36, 2: COLOR GREEN: PRINT "Vx";: COLOR WHITE: PRINT " = ";: COLOR GREEN: PRINT "Vx";: COLOR WHITE
PRINT " / ";: COLOR YELLOW: PRINT "Len";: COLOR WHITE: PRINT " = ";: COLOR GREEN: PRINT "######";
COLOR WHITE: PRINT " / ";: COLOR YELLOW: PRINT "######";: COLOR WHITE: PRINT " = ";: COLOR GREEN
PRINT "######";
LOCATE 37, 2: COLOR RED: PRINT "Vy";: COLOR WHITE: PRINT " = ";: COLOR RED: PRINT "Vy";: COLOR WHITE
PRINT " / ";: COLOR YELLOW: PRINT "Len";: COLOR WHITE: PRINT " = ";: COLOR RED: PRINT "######";
COLOR WHITE: PRINT " / ";: COLOR YELLOW: PRINT "######";: COLOR WHITE: PRINT " = ";: COLOR RED
PRINT "######";
'DEGREE TO RADIAN
LOCATE 23, 77: COLOR YELLOW: PRINT "Rad";: COLOR WHITE: PRINT " = ";: COLOR YELLOW: PRINT "Deg";
COLOR WHITE: PRINT " * PI / 180";
LOCATE 24, 77: COLOR YELLOW: PRINT "Rad";: COLOR WHITE: PRINT " = ";: COLOR YELLOW: PRINT "######";
COLOR WHITE: PRINT " * .0174532";
LOCATE 25, 77: COLOR YELLOW: PRINT "Rad";: COLOR WHITE: PRINT " = ";: COLOR YELLOW: PRINT "########";
'RADIAN TO VECTOR
LOCATE 28, 69: COLOR GREEN: PRINT "Vx";: COLOR WHITE: PRINT " = SIN(";: COLOR YELLOW: PRINT "Rad";
COLOR WHITE: PRINT ") = SIN(";: COLOR YELLOW: PRINT "########";: COLOR WHITE: PRINT ")";
LOCATE 29, 69: COLOR RED: PRINT "Vy";: COLOR WHITE: PRINT " = -COS(";: COLOR YELLOW: PRINT "Rad";
COLOR WHITE: PRINT ") = -COS(";: COLOR YELLOW: PRINT "########";: COLOR WHITE: PRINT ")";
LOCATE 30, 69: COLOR GREEN: PRINT "Vx";: COLOR WHITE: PRINT " = ";: COLOR GREEN: PRINT "######";
COLOR WHITE: PRINT " , ";: COLOR RED: PRINT "Vy";: COLOR WHITE: PRINT " = ";: COLOR RED: PRINT "######";
'DEGREE TO VECTOR
LOCATE 33, 72: COLOR GREEN: PRINT "Vx";: COLOR WHITE: PRINT " = SIN(";: COLOR YELLOW: PRINT "Deg";
COLOR WHITE: PRINT " * PI / 180)";
LOCATE 34, 72: COLOR GREEN: PRINT "Vx";: COLOR WHITE: PRINT " = SIN(";: COLOR YELLOW: PRINT "######";
COLOR WHITE: PRINT " * .0174532)";
LOCATE 35, 72: COLOR RED: PRINT "Vy";: COLOR WHITE: PRINT " = -COS(";: COLOR YELLOW: PRINT "Deg";
COLOR WHITE: PRINT " * PI / 180)";
LOCATE 36, 72: COLOR RED: PRINT "Vy";: COLOR WHITE: PRINT " = -COS(";: COLOR YELLOW: PRINT "######";
COLOR WHITE: PRINT " * .0174532)";
LOCATE 37, 72: COLOR GREEN: PRINT "Vx";: COLOR WHITE: PRINT " = ";: COLOR GREEN: PRINT "######";
COLOR WHITE: PRINT " , ";: COLOR RED: PRINT "Vy";: COLOR WHITE: PRINT " = ";: COLOR RED: PRINT "######";
COLOR WHITE, RED ' white text on red background
LOCATE 13, 5: PRINT " Click here to "; ' mouse button text
LOCATE 14, 5: PRINT " switch pages. ";
LINE (31, 191)-(151, 224), WHITE, B ' mouse button outline
VectorScreen = _COPYIMAGE(RadianScreen) ' copy everything to vector screen
COLOR GREEN, DARKGRAY ' green text on dark gray background
LOCATE 2, 2: PRINT " ENTER A VALUE BELOW "; ' print heading
COLOR WHITE, BLACK
LOCATE 10, 79: PRINT "radius of circle = 10" ' let user know radius of circle
LOCATE 1, 48: PRINT "0"; Api; " rad"; ' print text around circle
LOCATE 31, 49: PRINT Api; " rad";
LOCATE 16, 80: PRINT ".5"; Api; " rad";
LOCATE 16, 14: PRINT "1.5"; Api; " rad";
LOCATE 3, 50: PRINT "0"; Adg;
LOCATE 29, 49: PRINT "180"; Adg;
LOCATE 16, 75: PRINT "90"; Adg;
LOCATE 16, 24: PRINT "270"; Adg;
CIRCLE (399, 246), 225, DARKGRAY ' draw main circle
FOR Rad = 0 TO PI2 STEP .08726645 ' cycle through radian 5 degrees at a time
Radian2Vector Rad, Vector ' get normalized vector at radian
Vector.x = 399 + Vector.x * 225 ' adjust vectors for perimeter of circle
Vector.y = 246 + Vector.y * 225
PSET (Vector.x, Vector.y), WHITE ' place tick mark around circle
NEXT Rad
_DEST VectorScreen ' switch to vector screen
COLOR GREEN, DARKGRAY ' green text on dark gray background
LOCATE 2, 2: PRINT " ENTER VALUES BELOW "; ' print heading
COLOR WHITE, BLACK
LOCATE 1, 51: PRINT "0"; ' print coordinates around box
LOCATE 25, 50: PRINT "359";
LOCATE 13, 27: PRINT "0";
LOCATE 13, 75: PRINT "359";
LOCATE 1, 29: PRINT CHR$(25); "(0,0)";
LOCATE 25, 65: PRINT "(359,359)"; CHR$(24);
LOCATE 16, 3: PRINT "You must press ENTER on"; ' print input field directions
LOCATE 17, 3: PRINT "both inputs to activate.";
LINE (224, 19)-(586, 381), WHITE, B ' draw box outline
_DEST CoordGrid ' switch to coordinate grid image
CLS ' remove transparency
FOR Rad = 0 TO 359 STEP 10 ' cycles in steps of 10
LINE (Rad, 0)-(Rad, 359), DARKERGRAY ' draw vertical grid lines
LINE (0, Rad)-(359, Rad), DARKERGRAY ' draw horizontal grid lines
NEXT Rad
CoordGridCopy = _COPYIMAGE(CoordGrid) ' save clean copy of coordinate grid image
_DEST 0 ' switch back to main screen
END SUB ' phew, that was a lot of work!
'----------------------------------------------------------------------------------------------------------------
SUB P2PVector (P1 AS XYPAIR, P2 AS XYPAIR, V AS XYPAIR)
'** NOTE: V passed by reference is altered
'** Point to Point Vector Calculator
'** Returns the x,y normalized vectors from P1 to P2
' P1.x, P1.y = FROM coordinate (INPUT )
' P2.x, P2.y = TO coordinate (INPUT )
' V.x, V.y = normalized vectors to P2 (OUTPUT)
DIM D AS SINGLE ' distance between points
V.x = P2.x - P1.x ' horizontal distance ( side A )
V.y = P2.y - P1.y ' vertical distance ( side B )
D = _HYPOT(V.x, V.y) ' direct distance (hypotenuse)
IF D = 0 THEN EXIT SUB ' can't divide by 0
V.x = V.x / D ' normalized x vector ( -1 to 1 )
V.y = V.y / D ' normalized y vector ( -1 to 1 )
END SUB
'----------------------------------------------------------------------------------------------------------------
FUNCTION Vector2degree (V AS XYPAIR)
'** Vector to Degree Calculator
'** Converts the supplied normalized vector to a degree with 0 degrees facing up
'V.x, V.y - normalized vector (INPUT)
'57.29578 = 180 / PI
DIM Degrees AS SINGLE ' the returned degree
Degrees = _ATAN2(V.y, V.x) * 57.29578 ' get degree from vector (-180 to 180)
IF Degrees < 0 THEN Degrees = 360 + Degrees ' convert to 360
Degrees = Degrees + 90 ' set 0 degrees as up
IF Degrees > 360 THEN Degrees = Degrees - 360 ' adjust if necessary
Vector2degree = Degrees ' return degree (0 to 359.99..)
END FUNCTION
'----------------------------------------------------------------------------------------------------------------
SUB Degree2Vector (D AS SINGLE, V AS XYPAIR)
'** NOTE: V passed by reference is altered
'** Degree to Vector Calculator
'** Converts the supplied degree to a normalized vector
'D - degree (INPUT )
'V.x, V.y - normalized vector (OUTPUT)
'.017453292 = PI / 180
V.x = SIN(D * .017453292) ' return x vector
V.y = -COS(D * .017453292) ' return y vector
END SUB
'----------------------------------------------------------------------------------------------------------------
FUNCTION Vector2Radian (V AS XYPAIR)
'** Vector to Radian Calculator
'** Converts the supplied vector to a radian (0 to 2*PI)
' V.x, V.y - the supplied vector (INPUT)
Vector2Radian = Degree2Radian(Vector2degree(V)) ' return radian (0 to 2*PI)
END FUNCTION
'----------------------------------------------------------------------------------------------------------------
SUB Radian2Vector (R AS SINGLE, V AS XYPAIR)
'** NOTE: V passed by reference is altered
'** Radian to Vector Calculator
'** Converts the supplied radian to a normalized vector
' R - supplied radian (INPUT )
' V.x, V.y - the returned normalized vector (OUTPUT)
' 6.2831852 = 2 * PI
Degree2Vector Radian2Degree(R), V ' return normalized vector
END SUB
'----------------------------------------------------------------------------------------------------------------
FUNCTION Radian2Degree (R AS SINGLE)
'** Radian to Degree Calculator
'** Converts the supplied radian to degrees
' R - the supplied radian (INPUT)
' returns R * 180 / PI using the QB64 _R2D() function
' 6.2831852 = 2 * PI
Radian2Degree = _R2D(R) ' return degree (0 to 359.99..)
END FUNCTION
'----------------------------------------------------------------------------------------------------------------
FUNCTION Degree2Radian (D AS SINGLE)
'** Degree to Radian Calculator
'** Converts the supplied degree to radian
' D - the supplied degree (INPUT)
' returns A * PI / 180 using QB64 _D2R() function
Degree2Radian = _D2R(D) ' return radian (0 to 2*PI)
END FUNCTION
'----------------------------------------------------------------------------------------------------------------
'Graphics Line Input Library by Terry Ritchie
'Creates interactive LINE INPUT statements
'$INCLUDE:'glinput_noerror.bi'
'----------------------------------------------------------------------------------------------------------------
'I thought this was going to be a one day project ... here we are four days later. :)