### Author Topic: Vectors and Trigonometry  (Read 1056 times)

0 Members and 1 Guest are viewing this topic.

#### STxAxTIC ##### 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 »
TOXIC

#### bplus ##### Re: Vectors and Trigonometry
« Reply #1 on: October 19, 2019, 10:32:27 AM »
Thanks!

#### Ashish ##### 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

#### Petr ##### Re: Vectors and Trigonometry
« Reply #3 on: October 19, 2019, 02:18:19 PM »
Thank you, STxAxTIC. I'll look at it right away.

#### jack ##### Re: Vectors and Trigonometry
« Reply #4 on: October 20, 2019, 07:37:48 AM »
@STxAxTIC thank you :)

@Ashish nice video :)

#### Petr ##### 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.     CIRCLE (400, 400), 200
4.     Mx = _MOUSEX
5.     My = _MOUSEY
6.
7.     LINE (400, 400)-(400, 600), 14 'first, static vector
8.     LINE (400, 400)-(_MOUSEX, _MOUSEY), 14 'second vector
9.     LOCATE 1, 1: PRINT "Angle between vectors is:"; _R2D(GetAngleVec2D(400, 400, 400, 600, _MOUSEX, _MOUSEY))
10.     _LIMIT 20
11.
12.
13.
14.
15.
16.
17.
18.
19.
20. 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
21.     'calculate vector lenghts:
22.     Lenght1 = SQR((x2 - x1) ^ 2 + (y2 - y1) ^ 2)
23.     Lenght2 = SQR((x3 - x1) ^ 2 + (y3 - y1) ^ 2)
24.
25.     'calculate scalar product:
26.     xx2 = x2 - x1: yy2 = y2 - y1 'this is here, because vector begin is not in 0,0
27.     xx3 = x3 - x1: yy3 = y3 - y1
28.
29.     S = xx2 * xx3 + yy2 * yy3 'this is Scalar product
30.
31.     GetAngleVec2D = _ACOS(S / (Lenght1 * Lenght2))
32.

#### STxAxTIC ##### 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 »
TOXIC

#### STxAxTIC ##### 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.
TOXIC

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

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

#### Qwerkey ##### 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).

#### STxAxTIC ##### 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 »
TOXIC