Dependents: TDP_main_BartFork TDP_main TDP_main TDP_main_fork
LPS.cpp@3:dd68ac680416, 2015-03-12 (annotated)
- Committer:
- Joseph_Penikis
- Date:
- Thu Mar 12 22:12:18 2015 +0000
- Revision:
- 3:dd68ac680416
- Parent:
- 2:21ca29888540
Implemented ISP control, not tested...;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Joseph_Penikis | 1:b71a1c39d263 | 1 | #include "LPS.h" |
Joseph_Penikis | 0:dda98f02d71e | 2 | |
Joseph_Penikis | 0:dda98f02d71e | 3 | // Defines the delay experienced between transmitting IR and Ultrasonic pulse |
Joseph_Penikis | 0:dda98f02d71e | 4 | #define PING_OFFSET 0 |
Joseph_Penikis | 3:dd68ac680416 | 5 | #define SPEED_OF_SOUND 330.f |
Joseph_Penikis | 0:dda98f02d71e | 6 | // Used to rectify the issue of measured spheres not intersecting, may not be needed, but available anyway |
Joseph_Penikis | 0:dda98f02d71e | 7 | #define SWELL_VALUE 0 |
Joseph_Penikis | 0:dda98f02d71e | 8 | |
Joseph_Penikis | 3:dd68ac680416 | 9 | // Defines for instructions on SPI link, instructions corrpsond to distances under ~20mm, way too close to ever be picked up... |
Joseph_Penikis | 3:dd68ac680416 | 10 | #define START_CAL 0xFF |
Joseph_Penikis | 3:dd68ac680416 | 11 | #define REQUEST_T1 0xFE |
Joseph_Penikis | 3:dd68ac680416 | 12 | #define REQUEST_T2 0xFD |
Joseph_Penikis | 3:dd68ac680416 | 13 | #define REQUEST_T3 0xFC |
Joseph_Penikis | 3:dd68ac680416 | 14 | #define NEXT_CAL_POINT 0xFB |
Joseph_Penikis | 3:dd68ac680416 | 15 | #define UPPER_BYTE 0x01 |
Joseph_Penikis | 3:dd68ac680416 | 16 | |
Joseph_Penikis | 3:dd68ac680416 | 17 | LPS::LPS(PinName MOSI, PinName MISO, PinName SCLK) : _spi(MOSI, MISO, SCLK) { |
Joseph_Penikis | 3:dd68ac680416 | 18 | // Set up SPI interface for AVR |
Joseph_Penikis | 3:dd68ac680416 | 19 | _spi.format(8,3); |
Joseph_Penikis | 3:dd68ac680416 | 20 | _spi.frequency(1000000); |
Joseph_Penikis | 3:dd68ac680416 | 21 | } |
Joseph_Penikis | 1:b71a1c39d263 | 22 | LPS::~LPS() {} |
Joseph_Penikis | 0:dda98f02d71e | 23 | |
Joseph_Penikis | 1:b71a1c39d263 | 24 | _3D_Vector LPS::getUnitX() { return unitX; } |
Joseph_Penikis | 1:b71a1c39d263 | 25 | _3D_Vector LPS::getUnitY() { return unitY; } |
Joseph_Penikis | 1:b71a1c39d263 | 26 | _3D_Vector LPS::getUnitZ() { return unitZ; } |
Joseph_Penikis | 1:b71a1c39d263 | 27 | float LPS::getd() { return d; } |
Joseph_Penikis | 1:b71a1c39d263 | 28 | float LPS::geti() { return i; } |
Joseph_Penikis | 1:b71a1c39d263 | 29 | float LPS::getj() { return j; } |
Joseph_Penikis | 0:dda98f02d71e | 30 | |
Joseph_Penikis | 1:b71a1c39d263 | 31 | void LPS::updateLocation() { |
Joseph_Penikis | 0:dda98f02d71e | 32 | updateDistances(); |
Joseph_Penikis | 0:dda98f02d71e | 33 | |
Joseph_Penikis | 0:dda98f02d71e | 34 | current_1.x = calcX(beacon_1_distance, beacon_2_distance, d); |
Joseph_Penikis | 0:dda98f02d71e | 35 | current_1.y = calcY(beacon_1_distance, beacon_3_distance, i, j, current_1.x); |
Joseph_Penikis | 0:dda98f02d71e | 36 | current_1.z = calcZ(beacon_1_distance, current_1.x, current_1.y); |
Joseph_Penikis | 0:dda98f02d71e | 37 | |
Joseph_Penikis | 0:dda98f02d71e | 38 | _3D_Vector scaledX = scaleVector(unitX, current_1.x); |
Joseph_Penikis | 0:dda98f02d71e | 39 | _3D_Vector scaledY = scaleVector(unitY, current_1.y); |
Joseph_Penikis | 0:dda98f02d71e | 40 | _3D_Vector scaledZ = scaleVector(unitZ, current_1.z); |
Joseph_Penikis | 0:dda98f02d71e | 41 | |
Joseph_Penikis | 0:dda98f02d71e | 42 | current_1.x = beacon_1_loc.x + scaledX.x + scaledY.x; |
Joseph_Penikis | 0:dda98f02d71e | 43 | current_1.y = beacon_1_loc.y + scaledX.y + scaledY.y; |
Joseph_Penikis | 0:dda98f02d71e | 44 | current_1.z = beacon_1_loc.z + scaledX.z + scaledY.z; |
Joseph_Penikis | 0:dda98f02d71e | 45 | |
Joseph_Penikis | 0:dda98f02d71e | 46 | current_2.x = current_1.x - scaledZ.x; |
Joseph_Penikis | 0:dda98f02d71e | 47 | current_2.y = current_1.y - scaledZ.y; |
Joseph_Penikis | 0:dda98f02d71e | 48 | current_2.z = current_1.z - scaledZ.z; |
Joseph_Penikis | 0:dda98f02d71e | 49 | |
Joseph_Penikis | 0:dda98f02d71e | 50 | current_1.x += scaledZ.x; |
Joseph_Penikis | 0:dda98f02d71e | 51 | current_1.y += scaledZ.y; |
Joseph_Penikis | 0:dda98f02d71e | 52 | current_1.z += scaledZ.z; |
Joseph_Penikis | 0:dda98f02d71e | 53 | |
Joseph_Penikis | 0:dda98f02d71e | 54 | // Set location closest to z=0 as location, (We are typically on the floor, but need to verify this solution works) |
Joseph_Penikis | 0:dda98f02d71e | 55 | // If current_2.z is smaller than current_1.z, swap them |
Joseph_Penikis | 0:dda98f02d71e | 56 | if (abs(current_1.z) > abs(current_2.z)) { |
Joseph_Penikis | 0:dda98f02d71e | 57 | _3D_Vector temp = current_1; |
Joseph_Penikis | 0:dda98f02d71e | 58 | current_1.x = current_2.x; |
Joseph_Penikis | 0:dda98f02d71e | 59 | current_1.y = current_2.y; |
Joseph_Penikis | 0:dda98f02d71e | 60 | current_1.z = current_2.z; |
Joseph_Penikis | 0:dda98f02d71e | 61 | |
Joseph_Penikis | 0:dda98f02d71e | 62 | current_2.x = temp.x; |
Joseph_Penikis | 0:dda98f02d71e | 63 | current_2.y = temp.y; |
Joseph_Penikis | 0:dda98f02d71e | 64 | current_2.z = temp.z; |
Joseph_Penikis | 0:dda98f02d71e | 65 | } |
Joseph_Penikis | 0:dda98f02d71e | 66 | |
Joseph_Penikis | 0:dda98f02d71e | 67 | // Both solutions are currently preserved incase of neccisity in future use |
Joseph_Penikis | 0:dda98f02d71e | 68 | } |
Joseph_Penikis | 0:dda98f02d71e | 69 | |
Joseph_Penikis | 1:b71a1c39d263 | 70 | void LPS::calibratePosition(float iCal, float dCal, float jCal) { |
Joseph_Penikis | 0:dda98f02d71e | 71 | updateCalibrationDistances(); |
Joseph_Penikis | 0:dda98f02d71e | 72 | |
Joseph_Penikis | 0:dda98f02d71e | 73 | // Calculate the coordinates of beacon 1 |
Joseph_Penikis | 0:dda98f02d71e | 74 | beacon_1_loc.x = calcX(beacon_2_loc.x, beacon_3_loc.x, dCal); |
Joseph_Penikis | 0:dda98f02d71e | 75 | beacon_1_loc.y = calcY(beacon_2_loc.x, beacon_1_distance, iCal, jCal, beacon_1_loc.x); |
Joseph_Penikis | 0:dda98f02d71e | 76 | beacon_1_loc.z = calcZ(beacon_2_loc.x, beacon_1_loc.x, beacon_1_loc.y); |
Joseph_Penikis | 0:dda98f02d71e | 77 | |
Joseph_Penikis | 0:dda98f02d71e | 78 | // Push the data to new locations while becon 2 is calculated |
Joseph_Penikis | 0:dda98f02d71e | 79 | beacon_3_loc.x = beacon_2_loc.y; // 2_t1 |
Joseph_Penikis | 0:dda98f02d71e | 80 | beacon_1_distance = beacon_2_loc.z; // 3_t1 |
Joseph_Penikis | 0:dda98f02d71e | 81 | |
Joseph_Penikis | 0:dda98f02d71e | 82 | beacon_2_loc.x = calcX(beacon_3_loc.x, beacon_3_loc.y, dCal); |
Joseph_Penikis | 0:dda98f02d71e | 83 | beacon_2_loc.y = calcY(beacon_3_loc.x, beacon_2_distance, iCal, jCal, beacon_2_loc.x); |
Joseph_Penikis | 0:dda98f02d71e | 84 | beacon_2_loc.z = calcZ(beacon_3_loc.x, beacon_2_loc.x, beacon_2_loc.y); |
Joseph_Penikis | 0:dda98f02d71e | 85 | |
Joseph_Penikis | 0:dda98f02d71e | 86 | // Again, push data stored in beacon_3_loc out to safe location |
Joseph_Penikis | 0:dda98f02d71e | 87 | beacon_2_distance = beacon_3_loc.z; // 3_t2 |
Joseph_Penikis | 0:dda98f02d71e | 88 | |
Joseph_Penikis | 0:dda98f02d71e | 89 | beacon_3_loc.x = calcX(beacon_1_distance, beacon_2_distance, dCal); |
Joseph_Penikis | 0:dda98f02d71e | 90 | beacon_3_loc.y = calcY(beacon_1_distance, beacon_3_distance, iCal, jCal, beacon_3_loc.x); |
Joseph_Penikis | 0:dda98f02d71e | 91 | beacon_3_loc.z = calcZ(beacon_1_distance, beacon_3_loc.x, beacon_3_loc.y); |
Joseph_Penikis | 0:dda98f02d71e | 92 | |
Joseph_Penikis | 0:dda98f02d71e | 93 | // All beacon locations should now have been acquired (Untested) |
Joseph_Penikis | 0:dda98f02d71e | 94 | |
Joseph_Penikis | 0:dda98f02d71e | 95 | // Is it possible to calculate air speed and calibrate? TO VERIFY |
Joseph_Penikis | 0:dda98f02d71e | 96 | |
Joseph_Penikis | 0:dda98f02d71e | 97 | // Now need to calculate unit vectors and translation values for i, j, and d |
Joseph_Penikis | 0:dda98f02d71e | 98 | // This is only required upon power on, and/or if beacons are moved |
Joseph_Penikis | 0:dda98f02d71e | 99 | calcUnitVectorsAndScalars(); |
Joseph_Penikis | 0:dda98f02d71e | 100 | // Calibration complete!!!!!!! |
Joseph_Penikis | 0:dda98f02d71e | 101 | } |
Joseph_Penikis | 0:dda98f02d71e | 102 | |
Joseph_Penikis | 3:dd68ac680416 | 103 | int LPS::fetchTimeOverSPI(int instr) { |
Joseph_Penikis | 3:dd68ac680416 | 104 | |
Joseph_Penikis | 3:dd68ac680416 | 105 | // Loop while avr has not prepared data, i.e. still returning an instruction not data. TODO: Make a fetch only if available option to save on processor time |
Joseph_Penikis | 3:dd68ac680416 | 106 | do { |
Joseph_Penikis | 3:dd68ac680416 | 107 | received_2 = _spi.write(instr + UPPER_BYTE); |
Joseph_Penikis | 3:dd68ac680416 | 108 | } while (received_2 & 0x80); |
Joseph_Penikis | 0:dda98f02d71e | 109 | |
Joseph_Penikis | 3:dd68ac680416 | 110 | // I have received some data back, the avr is setup to create an identical packet to check data is correct |
Joseph_Penikis | 3:dd68ac680416 | 111 | // Send this data back to AVR (Not really used here, but better than using defined instructions) |
Joseph_Penikis | 3:dd68ac680416 | 112 | do { |
Joseph_Penikis | 3:dd68ac680416 | 113 | // Each time this loop data_1 shifted to r_1, data_2 loaded into r_2, i.e. r_2 ALWAYS has the most recent value |
Joseph_Penikis | 3:dd68ac680416 | 114 | received_1 = received_2; |
Joseph_Penikis | 3:dd68ac680416 | 115 | received_2 = _spi.write(received_1); |
Joseph_Penikis | 3:dd68ac680416 | 116 | } while (received_1 != received_2); |
Joseph_Penikis | 3:dd68ac680416 | 117 | // Valid data got (UPPER BYTE) |
Joseph_Penikis | 0:dda98f02d71e | 118 | |
Joseph_Penikis | 3:dd68ac680416 | 119 | do { |
Joseph_Penikis | 3:dd68ac680416 | 120 | received_3 = _spi.write(instr); |
Joseph_Penikis | 3:dd68ac680416 | 121 | } while (received_3 == instr); |
Joseph_Penikis | 3:dd68ac680416 | 122 | do { |
Joseph_Penikis | 3:dd68ac680416 | 123 | // Each time this loop data_1 shifted to r_1, data_2 loaded into r_3, i.e. r_3 ALWAYS has the most recent value |
Joseph_Penikis | 3:dd68ac680416 | 124 | received_1 = received_3; |
Joseph_Penikis | 3:dd68ac680416 | 125 | received_3 = _spi.write(received_1); |
Joseph_Penikis | 3:dd68ac680416 | 126 | } while (received_1 != received_3); |
Joseph_Penikis | 3:dd68ac680416 | 127 | // Valid data got (LOWER BYTE) |
Joseph_Penikis | 3:dd68ac680416 | 128 | |
Joseph_Penikis | 3:dd68ac680416 | 129 | // Generate an integer from these and return |
Joseph_Penikis | 3:dd68ac680416 | 130 | return (received_2 << 8) + received_3; |
Joseph_Penikis | 0:dda98f02d71e | 131 | } |
Joseph_Penikis | 0:dda98f02d71e | 132 | |
Joseph_Penikis | 1:b71a1c39d263 | 133 | void LPS::updateDistances() { |
Joseph_Penikis | 3:dd68ac680416 | 134 | // This will be the "socket" for talking to the base station |
Joseph_Penikis | 3:dd68ac680416 | 135 | /* |
Joseph_Penikis | 3:dd68ac680416 | 136 | beacon_1_distance = (fetchTimeOverSPI(REQUEST_T1) - PING_OFFSET) * SPEED_OF_SOUND + SWELL_VALUE; |
Joseph_Penikis | 3:dd68ac680416 | 137 | beacon_2_distance = (fetchTimeOverSPI(REQUEST_T2) - PING_OFFSET) * SPEED_OF_SOUND + SWELL_VALUE; |
Joseph_Penikis | 3:dd68ac680416 | 138 | beacon_3_distance = (fetchTimeOverSPI(REQUEST_T3) - PING_OFFSET) * SPEED_OF_SOUND + SWELL_VALUE; |
Joseph_Penikis | 3:dd68ac680416 | 139 | */ |
Joseph_Penikis | 3:dd68ac680416 | 140 | |
Joseph_Penikis | 3:dd68ac680416 | 141 | // Just dummy values for testing purposes |
Joseph_Penikis | 3:dd68ac680416 | 142 | beacon_1_distance = 11.55f; |
Joseph_Penikis | 3:dd68ac680416 | 143 | beacon_2_distance = 21.095f; |
Joseph_Penikis | 3:dd68ac680416 | 144 | beacon_3_distance = 15.395f; |
Joseph_Penikis | 0:dda98f02d71e | 145 | } |
Joseph_Penikis | 0:dda98f02d71e | 146 | |
Joseph_Penikis | 1:b71a1c39d263 | 147 | void LPS::updateCalibrationDistances() { |
Joseph_Penikis | 3:dd68ac680416 | 148 | // Tell base station to enter calibration mode |
Joseph_Penikis | 3:dd68ac680416 | 149 | _spi.write(START_CAL); |
Joseph_Penikis | 3:dd68ac680416 | 150 | |
Joseph_Penikis | 0:dda98f02d71e | 151 | // Reuse existing function to constrain external accessor code |
Joseph_Penikis | 3:dd68ac680416 | 152 | updateDistances(); |
Joseph_Penikis | 0:dda98f02d71e | 153 | |
Joseph_Penikis | 0:dda98f02d71e | 154 | beacon_2_loc.x = 14.14213562f;//beacon_1_distance; // 1_t1 |
Joseph_Penikis | 0:dda98f02d71e | 155 | beacon_2_loc.y = 22.49444376f;//beacon_2_distance; // 1_t2 |
Joseph_Penikis | 0:dda98f02d71e | 156 | beacon_2_loc.z = 12.36931688f;//beacon_3_distance; // 1_t3 |
Joseph_Penikis | 0:dda98f02d71e | 157 | |
Joseph_Penikis | 3:dd68ac680416 | 158 | updateDistances(); |
Joseph_Penikis | 0:dda98f02d71e | 159 | |
Joseph_Penikis | 0:dda98f02d71e | 160 | beacon_3_loc.x = 14.45683229f;//beacon_1_distance; // 2_t1 |
Joseph_Penikis | 0:dda98f02d71e | 161 | beacon_3_loc.y = 21.47091055f;//beacon_2_distance; // 2_t2 |
Joseph_Penikis | 0:dda98f02d71e | 162 | beacon_3_loc.z = 12.24744871f;//beacon_3_distance; // 2_t3 |
Joseph_Penikis | 0:dda98f02d71e | 163 | |
Joseph_Penikis | 3:dd68ac680416 | 164 | updateDistances(); |
Joseph_Penikis | 0:dda98f02d71e | 165 | |
Joseph_Penikis | 0:dda98f02d71e | 166 | beacon_1_distance = 16.673332f; |
Joseph_Penikis | 0:dda98f02d71e | 167 | beacon_2_distance = 22.36067477f; |
Joseph_Penikis | 0:dda98f02d71e | 168 | beacon_3_distance = 10.81665383f; |
Joseph_Penikis | 0:dda98f02d71e | 169 | // Third set is stored in the original defined variables, freeing up beacon_1_loc for initial calculation |
Joseph_Penikis | 0:dda98f02d71e | 170 | } |
Joseph_Penikis | 0:dda98f02d71e | 171 | |
Joseph_Penikis | 2:21ca29888540 | 172 | float calcX(float t1, float t2, float d) { |
Joseph_Penikis | 0:dda98f02d71e | 173 | /* |
Joseph_Penikis | 0:dda98f02d71e | 174 | x = (t1^2 - t2^2 + d^2) / 2d |
Joseph_Penikis | 0:dda98f02d71e | 175 | */ |
Joseph_Penikis | 0:dda98f02d71e | 176 | return (t1 * t1 - t2 * t2 + d * d) / (2 * d); |
Joseph_Penikis | 0:dda98f02d71e | 177 | } |
Joseph_Penikis | 0:dda98f02d71e | 178 | |
Joseph_Penikis | 2:21ca29888540 | 179 | float calcY(float t1, float t3, float i, float j, float x) { |
Joseph_Penikis | 0:dda98f02d71e | 180 | /* |
Joseph_Penikis | 0:dda98f02d71e | 181 | y = (t1^2 - t3^2 +i^2 + j^2) / 2j - (i/j) * x |
Joseph_Penikis | 0:dda98f02d71e | 182 | */ |
Joseph_Penikis | 0:dda98f02d71e | 183 | return ((pow(t1, 2) - pow(t3, 2) + pow(i, 2) + pow(j, 2)) / (2 * j)) - (i / j) * x; |
Joseph_Penikis | 0:dda98f02d71e | 184 | } |
Joseph_Penikis | 0:dda98f02d71e | 185 | |
Joseph_Penikis | 2:21ca29888540 | 186 | float calcZ(float t1, float x, float y) { |
Joseph_Penikis | 0:dda98f02d71e | 187 | /* |
Joseph_Penikis | 0:dda98f02d71e | 188 | z = sqrt(t1^2 - x^2 - y^2) |
Joseph_Penikis | 0:dda98f02d71e | 189 | */ |
Joseph_Penikis | 0:dda98f02d71e | 190 | // Technically has two solutions both +/-, can I assume always positive? TODO: Handle inverse value if needed |
Joseph_Penikis | 0:dda98f02d71e | 191 | return sqrt(pow(t1, 2) - pow(x, 2) - pow(y, 2)); |
Joseph_Penikis | 0:dda98f02d71e | 192 | } |
Joseph_Penikis | 0:dda98f02d71e | 193 | |
Joseph_Penikis | 1:b71a1c39d263 | 194 | void LPS::calcUnitVectorsAndScalars() { |
Joseph_Penikis | 0:dda98f02d71e | 195 | // e_x = P2 - P1 / |P2 - P1| |
Joseph_Penikis | 0:dda98f02d71e | 196 | _3D_Vector v = subTwoVectors(beacon_2_loc, beacon_1_loc); |
Joseph_Penikis | 0:dda98f02d71e | 197 | |
Joseph_Penikis | 0:dda98f02d71e | 198 | unitX = unitVector(v); |
Joseph_Penikis | 0:dda98f02d71e | 199 | |
Joseph_Penikis | 0:dda98f02d71e | 200 | // i = e_x dot P3 - P1 |
Joseph_Penikis | 0:dda98f02d71e | 201 | v = subTwoVectors(beacon_3_loc, beacon_1_loc); |
Joseph_Penikis | 0:dda98f02d71e | 202 | |
Joseph_Penikis | 0:dda98f02d71e | 203 | i = dot_Product(unitX, v); |
Joseph_Penikis | 0:dda98f02d71e | 204 | |
Joseph_Penikis | 0:dda98f02d71e | 205 | // e_y = P3 - P1 - i.e_x / |P3 - P1 - i.e_x| |
Joseph_Penikis | 0:dda98f02d71e | 206 | v = subTwoVectors(v, scaleVector(unitX, i)); |
Joseph_Penikis | 0:dda98f02d71e | 207 | |
Joseph_Penikis | 0:dda98f02d71e | 208 | unitY = unitVector(v); |
Joseph_Penikis | 0:dda98f02d71e | 209 | |
Joseph_Penikis | 0:dda98f02d71e | 210 | // e_z = e_x cross e_y |
Joseph_Penikis | 0:dda98f02d71e | 211 | unitZ = cross_Product(unitX, unitY); |
Joseph_Penikis | 0:dda98f02d71e | 212 | |
Joseph_Penikis | 0:dda98f02d71e | 213 | // d = |P2 - P1| |
Joseph_Penikis | 0:dda98f02d71e | 214 | v = subTwoVectors(beacon_2_loc, beacon_1_loc); |
Joseph_Penikis | 0:dda98f02d71e | 215 | |
Joseph_Penikis | 0:dda98f02d71e | 216 | d = vectorMagnitude(v); |
Joseph_Penikis | 0:dda98f02d71e | 217 | |
Joseph_Penikis | 0:dda98f02d71e | 218 | // j = e_y dot P3 - P1 |
Joseph_Penikis | 0:dda98f02d71e | 219 | v = subTwoVectors(beacon_3_loc, beacon_1_loc); |
Joseph_Penikis | 0:dda98f02d71e | 220 | |
Joseph_Penikis | 0:dda98f02d71e | 221 | j = dot_Product(unitY, v); |
Joseph_Penikis | 0:dda98f02d71e | 222 | } |
Joseph_Penikis | 0:dda98f02d71e | 223 | |
Joseph_Penikis | 1:b71a1c39d263 | 224 | _3D_Vector LPS::getCurrentLocation() { return current_1; } |
Joseph_Penikis | 1:b71a1c39d263 | 225 | _3D_Vector LPS::getBeacon_1_Location() { return beacon_1_loc; } |
Joseph_Penikis | 1:b71a1c39d263 | 226 | _3D_Vector LPS::getBeacon_2_Location() { return beacon_2_loc; } |
Joseph_Penikis | 1:b71a1c39d263 | 227 | _3D_Vector LPS::getBeacon_3_Location() { return beacon_3_loc; } |
Joseph_Penikis | 0:dda98f02d71e | 228 | |
Joseph_Penikis | 0:dda98f02d71e | 229 | _3D_Vector addFourVectors(_3D_Vector a, _3D_Vector b, _3D_Vector c, _3D_Vector d) { |
Joseph_Penikis | 0:dda98f02d71e | 230 | _3D_Vector v; |
Joseph_Penikis | 0:dda98f02d71e | 231 | |
Joseph_Penikis | 0:dda98f02d71e | 232 | v.x = a.x + b.x + c.x + d.x; |
Joseph_Penikis | 0:dda98f02d71e | 233 | v.y = a.y + b.y + c.y + d.y; |
Joseph_Penikis | 0:dda98f02d71e | 234 | v.z = a.z + b.z + c.z + d.z; |
Joseph_Penikis | 0:dda98f02d71e | 235 | |
Joseph_Penikis | 0:dda98f02d71e | 236 | return v; |
Joseph_Penikis | 0:dda98f02d71e | 237 | } |
Joseph_Penikis | 0:dda98f02d71e | 238 | |
Joseph_Penikis | 0:dda98f02d71e | 239 | _3D_Vector scaleVector(_3D_Vector a, float scale) { |
Joseph_Penikis | 0:dda98f02d71e | 240 | a.x *= scale; |
Joseph_Penikis | 0:dda98f02d71e | 241 | a.y *= scale; |
Joseph_Penikis | 0:dda98f02d71e | 242 | a.z *= scale; |
Joseph_Penikis | 0:dda98f02d71e | 243 | |
Joseph_Penikis | 0:dda98f02d71e | 244 | return a; |
Joseph_Penikis | 0:dda98f02d71e | 245 | } |
Joseph_Penikis | 0:dda98f02d71e | 246 | |
Joseph_Penikis | 0:dda98f02d71e | 247 | _3D_Vector unitVector(_3D_Vector a) { |
Joseph_Penikis | 0:dda98f02d71e | 248 | _3D_Vector v; |
Joseph_Penikis | 0:dda98f02d71e | 249 | float size = sqrt(a.x * a.x + a.y * a.y + a.z * a.z); |
Joseph_Penikis | 0:dda98f02d71e | 250 | |
Joseph_Penikis | 0:dda98f02d71e | 251 | v.x = a.x / size; |
Joseph_Penikis | 0:dda98f02d71e | 252 | v.y = a.y / size; |
Joseph_Penikis | 0:dda98f02d71e | 253 | v.z = a.z / size; |
Joseph_Penikis | 0:dda98f02d71e | 254 | |
Joseph_Penikis | 0:dda98f02d71e | 255 | return v; |
Joseph_Penikis | 0:dda98f02d71e | 256 | } |
Joseph_Penikis | 0:dda98f02d71e | 257 | |
Joseph_Penikis | 0:dda98f02d71e | 258 | float dot_Product(_3D_Vector a, _3D_Vector b) { |
Joseph_Penikis | 0:dda98f02d71e | 259 | return a.x * b.x + a.y * b.y + a.z * b.z; |
Joseph_Penikis | 0:dda98f02d71e | 260 | } |
Joseph_Penikis | 0:dda98f02d71e | 261 | |
Joseph_Penikis | 0:dda98f02d71e | 262 | float vectorMagnitude(_3D_Vector a) { |
Joseph_Penikis | 0:dda98f02d71e | 263 | return sqrt(a.x * a.x + a.y * a.y + a.z * a.z); |
Joseph_Penikis | 0:dda98f02d71e | 264 | } |
Joseph_Penikis | 0:dda98f02d71e | 265 | |
Joseph_Penikis | 0:dda98f02d71e | 266 | _3D_Vector cross_Product(_3D_Vector a, _3D_Vector b) { |
Joseph_Penikis | 0:dda98f02d71e | 267 | _3D_Vector v; |
Joseph_Penikis | 0:dda98f02d71e | 268 | |
Joseph_Penikis | 0:dda98f02d71e | 269 | v.x = (a.y * b.z - a.z * b.y); |
Joseph_Penikis | 0:dda98f02d71e | 270 | v.y = (a.z * b.x - a.x * b.z); |
Joseph_Penikis | 0:dda98f02d71e | 271 | v.z = (a.x * b.y - a.y * b.x); |
Joseph_Penikis | 0:dda98f02d71e | 272 | |
Joseph_Penikis | 0:dda98f02d71e | 273 | return v; |
Joseph_Penikis | 0:dda98f02d71e | 274 | } |
Joseph_Penikis | 0:dda98f02d71e | 275 | |
Joseph_Penikis | 0:dda98f02d71e | 276 | _3D_Vector subTwoVectors(_3D_Vector a, _3D_Vector b) { |
Joseph_Penikis | 0:dda98f02d71e | 277 | _3D_Vector v; |
Joseph_Penikis | 0:dda98f02d71e | 278 | |
Joseph_Penikis | 0:dda98f02d71e | 279 | v.x = a.x - b.x; |
Joseph_Penikis | 0:dda98f02d71e | 280 | v.y = a.y - b.y; |
Joseph_Penikis | 0:dda98f02d71e | 281 | v.z = a.z - b.z; |
Joseph_Penikis | 0:dda98f02d71e | 282 | |
Joseph_Penikis | 0:dda98f02d71e | 283 | return v; |
Joseph_Penikis | 0:dda98f02d71e | 284 | } |