Author Topic: Vectors and Trigonometry  (Read 5164 times)

0 Members and 1 Guest are viewing this topic.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Vectors and Trigonometry
« on: October 19, 2019, 09:42:50 am »
Hello all,

I recently arranged and "linearized" everything I think a qb graphics programmer or amateur mathematician should know about vectors and trigonometry. The attached document is very skeletal but contains the entire truth and doesn't jump around. There is no mention of calculus until the very end - it's really up to your wits and patience to get through this thing. If you're a visual person I suggest drawing notes as you read along. To improve public consumption, I'm considering augmenting the PDF attached with practice problems, maybe even videos.

This is mainly for you, Petr. Have fun.

NOTE: The version attached here is locked in time. For the newest version (starting with next update maybe a day after this post), click the web link under my avatar and look for Vectors and Trigonometry (don't get lost).
« Last Edit: October 19, 2019, 10:16:51 am by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Vectors and Trigonometry
« Reply #1 on: October 19, 2019, 10:32:27 am »
Thanks!

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Vectors and Trigonometry
« Reply #2 on: October 19, 2019, 10:46:43 am »
Cool STxAxTIC! Almost 80% of this PDF have been taught to me in the school now. Calculus, Limits, etc is to be taught.
On vectors, there are some brilliant video by 3Blue1Brown with visualisation. Everyone should check this out -

if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Vectors and Trigonometry
« Reply #3 on: October 19, 2019, 02:18:19 pm »
Thank you, STxAxTIC. I'll look at it right away.

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: Vectors and Trigonometry
« Reply #4 on: October 20, 2019, 07:37:48 am »
@STxAxTIC thank you :)

@Ashish nice video :)

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Vectors and Trigonometry
« Reply #5 on: October 20, 2019, 08:22:25 am »
Ok, STxAxTIC. Here is my first output. It is very upgraded function (in my 3D programs named as JK!), this use vectors definitions, it is for 2D.

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 800, 256)
  2.  
  3.     CLS
  4.     CIRCLE (400, 400), 200
  5.     Mx = _MOUSEX
  6.     My = _MOUSEY
  7.  
  8.     LINE (400, 400)-(400, 600), 14 'first, static vector
  9.     LINE (400, 400)-(_MOUSEX, _MOUSEY), 14 'second vector
  10.     LOCATE 1, 1: PRINT "Angle between vectors is:"; _R2D(GetAngleVec2D(400, 400, 400, 600, _MOUSEX, _MOUSEY))
  11.     _DISPLAY
  12.     _LIMIT 20
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22. FUNCTION GetAngleVec2D (x1, y1, x2, y2, x3, y3) 'x1, y1 = start point for both 2D vectors, x2, y2 is first vector end point, x3, y3 is second vector end point
  23.     'calculate vector lenghts:
  24.     Lenght1 = SQR((x2 - x1) ^ 2 + (y2 - y1) ^ 2)
  25.     Lenght2 = SQR((x3 - x1) ^ 2 + (y3 - y1) ^ 2)
  26.  
  27.     'calculate scalar product:
  28.     xx2 = x2 - x1: yy2 = y2 - y1 'this is here, because vector begin is not in 0,0
  29.     xx3 = x3 - x1: yy3 = y3 - y1
  30.  
  31.     S = xx2 * xx3 + yy2 * yy3 'this is Scalar product
  32.  
  33.     GetAngleVec2D = _ACOS(S / (Lenght1 * Lenght2))
  34.  

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Vectors and Trigonometry
« Reply #6 on: October 20, 2019, 09:14:00 am »
Thanks everyone for having a look at this! My goal is for people to spend more cumulative time reading this work than the time it took me to write it. This kind of writing doesn't spread and make money like the way a fantasy novel does... amen Steve? Haha anyway...

One thing I want to point out - specifically when doing graphics in QB64 - is the horrendously confusing set of screen coordinates. Mathematicians get used to the origin being in the middle of space, and the "up" and "right" directions carry you away in a positive direction (with down and left going negative). We like Cartesian systems.

QB64 is all f*cked up. The origin (0,0) is at the top-left corner of the screen, and moving down is considered increasing your distance from there. Just terrible. In vector language, this would mean the screen basis vectors are:

x_hat = <1,0>
y_hat = <0,-1>

The minus sign captures the backwards Y-motion. This is not enough though, because to do everything right, you need to propagate that minus sign into *everything*. Trig will look half-wrong because SIN() will open in the wrong direction. The right hand rule will be exactly wrong... its just a total mess. This is why its so hard for people to get right, hands down. (Especially trying to *use* QB64 to teach this. Just the wrong move to learn trigonometry on a backwards coordinate system.)

I suggest doing all of the calculations in regular Cartesian space and then converting to screen coordinates at the very end. For instance, on an 800*600 screen, do all calculations in the interval (-400,400) to (-300,300). Then, when it finally comes time to plot, just convert each X and Y:

x = x0 + 400
y = -y0 + 300

There you gain the minus sign back without ever having to mess around or reinvent the fundamentals.
« Last Edit: October 20, 2019, 09:25:00 am by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Vectors and Trigonometry
« Reply #7 on: October 20, 2019, 09:22:58 am »
@Petr:

Nice start - I want to point out that the angular interval between the vectors spans the entire 0-360 degree domain. When I increase the angle to 178,179,180 - I expect the angle to keep increasing from 181 all the way to 360. In your program, it counts back down to zero from 179.
You're not done when it works, you're done when it's right.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Vectors and Trigonometry
« Reply #8 on: October 20, 2019, 09:37:35 am »
This captures the point about screen coordinates vs Cartesian (just a super simple trig demo). Click (and/or drag) to move the origin.

Code: QB64: [Select]
  1.  
  2. ' Origin in Cartesian coordinates. (Changes when mouse is clicked.)
  3. OriginX = -100
  4. OriginY = -100
  5.  
  6. ' Point of interest in Cartesian coordinates. (Changes while mouse moves.)
  7. IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN
  8.     GOSUB unconvert
  9.     OriginX = x
  10.     OriginY = y
  11.     ThePointX = 100
  12.     ThePointY = 100
  13.  
  14. ' Main loop.
  15.         x = _MOUSEX
  16.         y = _MOUSEY
  17.         IF x > 0 AND x < 640 AND y > 0 AND y < 480 THEN
  18.  
  19.             GOSUB unconvert
  20.             ThePointX = x
  21.             ThePointY = y
  22.  
  23.             IF _MOUSEBUTTON(1) THEN
  24.                 x = _MOUSEX
  25.                 y = _MOUSEY
  26.                 GOSUB unconvert
  27.                 OriginX = x
  28.                 OriginY = y
  29.             END IF
  30.  
  31.         END IF
  32.     LOOP
  33.     GOSUB DrawEverything
  34.  
  35.  
  36.  
  37. DrawEverything:
  38. ' Make Cartesian grid.
  39. FOR x = OriginX TO 640 STEP 10
  40.     LINE (x, 0)-(x, 480), 8
  41. FOR x = OriginX TO 0 STEP -10
  42.     LINE (x, 0)-(x, 480), 8
  43. FOR y = OriginY TO 480 STEP 10
  44.     LINE (0, -y + 240)-(640, -y + 240), 8
  45. FOR y = OriginY TO -240 STEP -10
  46.     LINE (0, -y + 240)-(640, -y + 240), 8
  47. x = OriginX
  48. y = OriginY
  49. GOSUB convert
  50. LINE (0, y)-(640, y), 7
  51. LINE (x, 0)-(x, 480), 7
  52. _PRINTSTRING (640 - 8 * 6, y), "X-axis"
  53. _PRINTSTRING (x, 0), "Y-axis"
  54. _PRINTSTRING (x, y), "Origin"
  55. ' Draw the circle on which the position vector lives.
  56. Radius = SQR((ThePointX - OriginX) ^ 2 + (ThePointY - OriginY) ^ 2)
  57. x = OriginX
  58. y = OriginY
  59. GOSUB convert
  60. CIRCLE (x, y), Radius, 7
  61. ' Draw the vertical component.
  62. x = OriginX
  63. y = OriginY
  64. GOSUB convert
  65. x1 = x
  66. y1 = y
  67. x = ThePointX
  68. y = OriginY
  69. GOSUB convert
  70. x2 = x
  71. y2 = y
  72. LINE (x1, y1)-(x2, y2), 9
  73. LINE (x1, y1 + 1)-(x2, y2 + 1), 9
  74. LINE (x1, y1 - 1)-(x2, y2 - 1), 9
  75. ' Draw the horizontal component.
  76. x = ThePointX
  77. y = OriginY
  78. GOSUB convert
  79. x1 = x
  80. y1 = y
  81. x = ThePointX
  82. y = ThePointY
  83. GOSUB convert
  84. x2 = x
  85. y2 = y
  86. LINE (x1, y1)-(x2, y2), 4
  87. LINE (x1 - 1, y1)-(x2 - 1, y2), 4
  88. LINE (x1 + 1, y1)-(x2 + 1, y2), 4
  89. ' Draw position vector (aka the Hypotenuse).
  90. x = OriginX
  91. y = OriginY
  92. GOSUB convert
  93. x1 = x
  94. y1 = y
  95. x = ThePointX
  96. y = ThePointY
  97. GOSUB convert
  98. x2 = x
  99. y2 = y
  100. LINE (x1, y1)-(x2, y2), 10
  101. LINE (x1 + 1, y1)-(x2 + 1, y2), 10
  102. LINE (x1, y1 + 1)-(x2, y2 + 1), 10
  103. ' Write text.
  104. LOCATE 1, 60: PRINT "-------Origin-------"
  105. LOCATE 2, 60: PRINT "Cartesian/Polar/Qb64:"
  106. LOCATE 3, 61: PRINT "X=0   , Y=0"
  107. LOCATE 4, 61: PRINT "R=0   , Ang=undef"
  108. LOCATE 5, 61: PRINT "x="; OriginX + 320; ", "; "y="; -OriginY + 240
  109. LOCATE 7, 60: PRINT "-------Cursor-------"
  110. LOCATE 8, 60: PRINT "Cartesian/Polar/Qb64:"
  111. LOCATE 9, 61: PRINT "X="; ThePointX - OriginX; ", "; "Y="; ThePointY - OriginY
  112. ' Deal with radius calculation.
  113. Radius = SQR((ThePointX - OriginX) ^ 2 + (ThePointY - OriginY) ^ 2)
  114. IF Radius < .0001 THEN Radius = .0001
  115. LOCATE 10, 61: PRINT "R="; INT(Radius); ", "; "Ang="; TheAngle
  116. ' Deal with the anlge calculation.
  117. xdiff = ThePointX - OriginX
  118. ydiff = ThePointY - OriginY
  119. IF xdiff > 0 AND ydiff > 0 THEN ' First quadrant
  120.     TheAngle = INT((180 / 3.14159) * ATN(ydiff / xdiff))
  121. IF xdiff < 0 AND ydiff > 0 THEN ' Second quadrant
  122.     TheAngle = 180 + INT((180 / 3.14159) * ATN(ydiff / xdiff))
  123. IF xdiff < 0 AND ydiff < 0 THEN ' Third quadrant
  124.     TheAngle = 180 + INT((180 / 3.14159) * ATN(ydiff / xdiff))
  125. IF xdiff > 0 AND ydiff < 0 THEN ' Fourth quadrant
  126.     TheAngle = 360 + INT((180 / 3.14159) * ATN(ydiff / xdiff))
  127. IF SQR(ydiff ^ 2) < .0001 THEN ydiff = .0001
  128. IF SQR(xdiff ^ 2) < .0001 THEN xdiff = .0001
  129. LOCATE 11, 61: PRINT "x="; ThePointX + 320; ", "; "y="; -ThePointY + 240
  130. LOCATE 13, 60: PRINT "--------Trig--------"
  131. LOCATE 14, 61: PRINT "sin(Ang)=";: COLOR 4: PRINT "Opp";: COLOR 7: PRINT "/";: COLOR 10: PRINT "Hyp";: COLOR 7
  132. LOCATE 15, 61: PRINT "        ="; USING "##.###"; ydiff / Radius
  133. LOCATE 16, 61: PRINT "cos(Ang)=";: COLOR 9: PRINT "Adj";: COLOR 7: PRINT "/";: COLOR 10: PRINT "Hyp";: COLOR 7
  134. LOCATE 17, 61: PRINT "        ="; USING "##.###"; xdiff / Radius
  135. LOCATE 18, 61: PRINT "tan(Ang)=";: COLOR 4: PRINT "Opp";: COLOR 7: PRINT "/";: COLOR 9: PRINT "Adj";: COLOR 7
  136. f = ydiff / xdiff
  137. IF f < 9999.99 AND f > -9999.99 THEN
  138.     LOCATE 19, 61: PRINT "        ="; USING "####.###"; f
  139.  
  140. convert:
  141. ' Converts Cartesian coordinates to QB64 coordinates.
  142. x0 = x: y0 = y
  143. x = x0 + 320
  144. y = -y0 + 240
  145.  
  146. unconvert:
  147. ' Converts QB64 coordinates to Cartesian coordinates.
  148. x0 = x: y0 = y
  149. x = x0 - 320
  150. y = -y0 + 240
  151.  
  152.  
  153.  
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Vectors and Trigonometry
« Reply #9 on: October 21, 2019, 01:08:38 am »
Started the "grunt work" of translating notes into code, Vector Math.bas:
Code: QB64: [Select]
  1. _TITLE "Vector Math" ' B+ started 2019-10-20
  2. ' Based on notes provided to QB64 forum by William F Barnes, on 2019-10-19
  3. ' https://www.qb64.org/forum/index.php?topic=1782.0
  4. ' A vector's dimension is the number of components it has.
  5. ' Here is code for processing 2 and 3 dimension vectors.
  6.  
  7. TYPE xyType
  8.     x AS SINGLE
  9.     y AS SINGLE
  10.  
  11. TYPE xyzType
  12.     x AS SINGLE
  13.     y AS SINGLE
  14.     z AS SINGLE
  15.  
  16. ' notation 0 w/arrowHat  (no way of telling if 2, 3 or more dimensions)
  17. DIM SHARED v2zero AS xyType, v3zero AS xyzType
  18. v2zero.x = 0: v2zero.y = 0
  19. v3zero.x = 0: v3zero.y = 0: v3zero.z = 0
  20.  
  21. 'Basis Vectors, isolate components e sub x Dot V w/arrowHat = V sub x
  22. DIM SHARED v2e(1 TO 2) AS xyType, v3e(1 TO 3) AS xyzType
  23. v2e(1).x = 1: v2e(1).y = 0
  24. v2e(2).x = 0: v2e(2).y = 1
  25. v3e(1).x = 1: v3e(1).y = 0: v3e(1).z = 0
  26. v3e(2).x = 0: v3e(2).y = 1: v3e(2).z = 0
  27. v3e(3).x = 0: v3e(3).y = 0: v3e(3).z = 1
  28.  
  29.  
  30. '==================================================================================== test area
  31.  
  32. 'define a test vector
  33. DIM Test AS xyzType, A AS xyzType, B AS xyzType, Inv AS xyzType, sing AS SINGLE
  34. A.x = 1: A.y = 2: A.z = 3
  35. B.x = -10: B.y = -20: B.z = -30
  36. PRINT "A w/arrowHat = " + v3$(A)
  37. PRINT "B w/arrowHat = " + v3$(B)
  38. v3Add A, B, Test
  39. PRINT "A + B = " + v3$(Test)
  40. v3Subtr A, B, Test
  41. PRINT "A - B = " + v3(Test)
  42. v3Scale 10, A, Test
  43. PRINT "10A = " + v3$(Test)
  44. v3Inverse A, Inv
  45. PRINT "A Inverse = " + v3$(Inv)
  46. v3Add A, Inv, Test
  47. PRINT "Check Inverse: A v3Add Inv = " + v3$(Test)
  48. PRINT "A's magnitude is "; v3Magnitude(A)
  49. v3Unit A, Test
  50. PRINT "A's unit vector is "; v3$(Test)
  51. 'isolate y component of test
  52. Test.x = 10: Test.y = -101.11: Test.z = 22.37
  53. DIM yComponent
  54. PRINT "Test = " + v3$(Test)
  55. yComponent = v3DotProduct(v3e(2), Test)
  56. PRINT "Test isolate component y = v3DotProduct(v3e(2), Test) = " + ts$(yComponent) 'yeah it worked!"
  57. setV3 1, 0, 0, A
  58. setV3 0, 1, 0, B
  59. v3CrossProduct A, B, Test
  60. PRINT "A = " + v3$(A)
  61. PRINT "B = " + v3$(B)
  62. PRINT "A Cross B = " + v3$(Test) ' = [0, 0, 1] ?
  63.  
  64.  
  65. '================================================= subs and fuctions
  66. SUB setV3 (x, y, z, setMe AS xyzType)
  67.     setMe.x = x: setMe.y = y: setMe.z = z
  68.  
  69. FUNCTION v3$ (showMeInnards AS xyzType)
  70.     v3$ = "[" + ts$(showMeInnards.x) + ", " + ts$(showMeInnards.y) + ", " + ts$(showMeInnards.z) + "]"
  71.  
  72. FUNCTION ts$ (number)
  73.     ts$ = _TRIM$(STR$(number))
  74.  
  75. 'notation UppercaseLetter w/arrowhat + uppercase Letter w/arrowHat
  76. SUB v2Add (A AS xyType, B AS xyType, Sum AS xyType)
  77.     Sum.x = A.x + B.x
  78.     Sum.y = A.y + B.y
  79. SUB v3Add (A AS xyzType, B AS xyzType, Sum AS xyzType)
  80.     Sum.x = A.x + B.x
  81.     Sum.y = A.y + B.y
  82.     Sum.z = A.z + B.z
  83.  
  84. 'notation UppercaseLetter w/arrowHat - UppercaseLetter w/arrowHat
  85. SUB v2Subtr (A AS xyType, B AS xyType, Sum AS xyType)
  86.     Sum.x = A.x - B.x
  87.     Sum.y = A.y - B.y
  88. SUB v3Subtr (A AS xyzType, B AS xyzType, Sum AS xyzType)
  89.     Sum.x = A.x - B.x
  90.     Sum.y = A.y - B.y
  91.     Sum.z = A.z - B.z
  92.  
  93. 'notation lowercaseletter (for a number next to (times)) UppercaseLetter w/arrowHat
  94. SUB v2Scale (mult AS SINGLE, A AS xyType, Scale AS xyType) 'parallels
  95.     Scale.x = mult * A.x
  96.     Scale.y = mult * A.y
  97. SUB v3Scale (mult AS SINGLE, A AS xyzType, Scale AS xyzType) 'parallels
  98.     Scale.x = mult * A.x
  99.     Scale.y = mult * A.y
  100.     Scale.z = mult * A.z
  101.  
  102. 'notation the inverse of A w/arrowHat is -A w/arrowHat
  103. SUB v2Inverse (A AS xyType, Inverse AS xyType) ' A + InverseOfA = 0
  104.     Inverse.x = -A.x
  105.     Inverse.y = -A.y
  106. SUB v3Inverse (A AS xyzType, Inverse AS xyzType) ' A + InverseOfA = 0
  107.     Inverse.x = -A.x
  108.     Inverse.y = -A.y
  109.     Inverse.z = -A.z
  110.  
  111. 'notation: A w/arrowHat Dot B w/arrowHat v2 Dot Product is a number, v3 Dot Product is a vector
  112. FUNCTION v2DotProduct (A AS xyType, B AS xyType) 'shadow or projection  if A Dot B = 0 then A , B are perpendicular
  113.     v2DotProduct = A.x * B.x + A.y * B.y
  114. FUNCTION v3DotProduct (A AS xyzType, B AS xyzType) 'shadow or projection  if A Dot B = 0 then A , B are perpendicular
  115.     v3DotProduct = A.x * B.x + A.y * B.y + A.z * B.z
  116.  
  117. 'notation absolute value bars about A w/arrowHat OR just an UppercaseLetter (with no hat), its just a number
  118. FUNCTION v2Magnitude (A AS xyType) 'hypotenuse of right triangle
  119.     v2Magnitude = SQR(v2DotProduct(A, A))
  120. FUNCTION v3Magnitude (A AS xyzType) 'hypotenuse of cube
  121.     v3Magnitude = SQR(v3DotProduct(A, A))
  122.  
  123. 'notation: A w/arrowHat X B w/arrowHat, X is a Cross get it?
  124. FUNCTION v2CrossProduct (A AS xyType, B AS xyType) ' a vector perpendicular to both A and B, v2 is a magnitude
  125.     v2CrossProduct = A.x * B.y - A.y * B.x
  126. SUB v3CrossProduct (A AS xyzType, B AS xyzType, Cross AS xyzType) ' v3 cross product is a 3d vector perpendicular to A and B
  127.     'notice x has no x components, y no y componets, z no z components
  128.     Cross.x = A.y * B.z - A.z * B.y
  129.     Cross.y = A.z * B.x - A.x * B.z
  130.     Cross.z = A.x * B.y - A.y * B.x
  131.  
  132. 'notation: A w/caratHat = A w/arrowHat divided by A (UppercaseLetter) or scaled by 1/A magnitude (no hats)
  133. SUB v2Unit (A AS xyType, Unit AS xyType)
  134.     DIM m AS SINGLE
  135.     m = v2Magnitude(A)
  136.     v2Scale 1 / m, A, Unit
  137. SUB v3Unit (A AS xyzType, Unit AS xyzType)
  138.     DIM m AS SINGLE
  139.     m = v3Magnitude(A)
  140.     v3Scale 1 / m, A, Unit
  141.  
« Last Edit: October 21, 2019, 01:19:03 am by bplus »

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Vectors and Trigonometry
« Reply #10 on: October 21, 2019, 05:26:58 am »
STxAxTIC, a useful doument.  I had almost forgotten the method for cross product.  How easily things slip from memory (those grey cells holding that information have disappeared).

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Vectors and Trigonometry
« Reply #11 on: October 22, 2019, 10:48:30 pm »
@Querkey - Thanks for having a look!

I think my next step is to show how this apparatus actually applies to 3D graphics and engines and so on (as least as far as I've taken it across a bunch of scattered projects). Funny thing is, half the math-stuff that Sanctum and similar projects implement are made completely redundant by hardware via _GL, so all the serious coder has to worry about is getting the 3D illusion right. I'll ramble about clipping planes, backface occulting, and overlap prevention for the true nerds out there...

@Bplus - killin' the game man. If we polish off that set of tools and generalize them enough for doing linear algebra, they can hang with the best out there.
« Last Edit: October 22, 2019, 11:11:10 pm by STxAxTIC »
You're not done when it works, you're done when it's right.