└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # Math Snippets 2 | > Math snippets with graphic programming in mind. 3 | 4 | This is work in progress. 5 | **To-do:** 6 | - [ ] Convert all snippets to JS (Some are Action Script) 7 | - [ ] Add live code examples 8 | - [ ] Add simple desciptions 9 | 10 | ## Contents 11 | - [Snippets](https://github.com/terkelg/math/blob/master/README.md#snippets) 12 | - [Radias & Degrees](https://github.com/terkelg/math#radians--degrees) 13 | - [Calculate side lengths](https://github.com/terkelg/math#calculate-side-lengths) 14 | - [Rotate a 2D point](https://github.com/terkelg/math#rotate-a-2d-point) 15 | - [Linear distance bwetween 2 points](https://github.com/terkelg/math#linear-distance-2-points) 16 | - [Linear distance between 2 vectors](https://github.com/terkelg/math#linear-distance-between-2-vectors) 17 | - [Length of a vector (Magnitude)](https://github.com/terkelg/math#length-of-a-vector) 18 | - [Add and substract vectors](https://github.com/terkelg/math#add-and-substract-vectors) 19 | - [Normalize vector](https://github.com/terkelg/math#normalize-vector) 20 | - [Dot product vectors](https://github.com/terkelg/math#dot-product-vectors) 21 | - [Finding angle between 2 points](https://github.com/terkelg/math#finding-angle-between-2-points) 22 | - [Finding angle between 2 vectors](https://github.com/terkelg/math#finding-angle-between-2-vectors) 23 | - [Cross Product](https://github.com/terkelg/math#cross-product) 24 | - [Rotate to the mouse (or any point)](https://github.com/terkelg/math#rotate-to-the-mouse-or-any-point) 25 | - [Create waves](https://github.com/terkelg/math#create-waves) 26 | - [Hex to decimal](https://github.com/terkelg/math#hex-to-decimal) 27 | - [Decimal to hex](https://github.com/terkelg/math#decimal-to-hex) 28 | - [Combine component colors](https://github.com/terkelg/math#combine-component-colors) 29 | - [Extract component colors](https://github.com/terkelg/math#extract-component-colors) 30 | - [Draw a curve through a point](https://github.com/terkelg/math#draw-a-curve-through-a-point) 31 | - [Convert angular velocity to x, y velocity](https://github.com/terkelg/math#convert-angular-velocity-to-x-y-velocity) 32 | - [Convert angular acceleration or any other force to x and y](https://github.com/terkelg/math#convert-angular-acceleration-or-any-other-force-to-x-and-y) 33 | - [Add acceleration to velocity](https://github.com/terkelg/math#add-acceleration-to-velocity) 34 | - [Add velocity to position](https://github.com/terkelg/math#add-velocity-to-position) 35 | - [Testing for out of bound](https://github.com/terkelg/math#testing-for-out-of-bound) 36 | - [Apply friction (correct way)](https://github.com/terkelg/math#apply-friction-correct-way) 37 | - [Apply friction (the easy way)](https://github.com/terkelg/math#apply-friction-the-easy-way) 38 | - [Simple easing, long form](https://github.com/terkelg/math#simple-easing-long-form) 39 | - [Simple easing, abbreviated form](https://github.com/terkelg/math#simple-easing-abbreviated-form) 40 | - [Simple easing, short form](https://github.com/terkelg/math#simple-easing-short-form) 41 | - [Simple spring, long form](https://github.com/terkelg/math#simple-spring-long-form) 42 | - [Simple spring, abbreviated form](https://github.com/terkelg/math#simple-spring-abbreviated-form) 43 | - [Simple spring, short form](https://github.com/terkelg/math#simple-spring-short-form) 44 | - [Offset spring](https://github.com/terkelg/math#offset-spring) 45 | - [Distance-based collision detection](https://github.com/terkelg/math#distance-based-collision-detection) 46 | - [Multiple-objects collision detection](https://github.com/terkelg/math#multiple-objects-collision-detection) 47 | - [Coordinate rotation](https://github.com/terkelg/math#coordinate-rotation) 48 | - [Reverse coordiante rotation](https://github.com/terkelg/math#reverse-coordiante-rotation) 49 | - [Conservation of momentum in ActionScript (with a shortcut)](https://github.com/terkelg/math#conservation-of-momentum-in-actionscript-with-a-shortcut) 50 | - [Gravity implementation](https://github.com/terkelg/math#gravity-implementation) 51 | - [Resources](https://github.com/terkelg/math#resources) 52 | 53 | 54 | ## Snippets 55 | 56 | ### Radians & Degrees 57 | 58 | ``` 59 | radians = degrees * Math.PI / 180; 60 | degrees = radians * 180 / Math.PI; 61 | ``` 62 | 63 | ```js 64 | // JavaScript 65 | var angleInDegrees = 45; 66 | var radians = angleInDegrees * Math.PI / 180; 67 | var backToDegrees = radians * 180 / Math.PI; 68 | ``` 69 | 70 | ### Calculate side lengths 71 | #### SOHCAHTOA 72 | 73 | ###### Calculate basic trigonometric functions 74 | ``` 75 | Sine of an angle = opposite / hypotenuse 76 | Cosine of an angle = adjacent / hypotenuse 77 | Tangent of angle = opposite / adjacent 78 | ``` 79 | 80 | ```js 81 | // Javascript 82 | var hyp = 100; 83 | var angleDegrees = 45; 84 | var angleRadians = angleDegrees * Math.PI / 180; 85 | 86 | var opposite = Math.sin( angleRadians ) * hyp; 87 | var adjacent = Math.cos( angleRadians ) * hyp; 88 | var tangent = opposite / adjacent; 89 | ``` 90 | 91 | ### Rotate a 2D point 92 | ```js 93 | var vec2 = {x: 2, y: 3}; 94 | var rotatedVector = rotate2D(vec2, angle); 95 | 96 | function rotate2D(vector, angle) 97 | { 98 | var theta = angle * Math.PI / 180; // radians 99 | var matrix = [ Math.cos(theta), Math.sin(theta), 100 | -Math.sin(theta), Math.cos(theta) 101 | ]; 102 | 103 | return { 104 | x: matrix[0] * vector.x + matrix[1] * vector.y, 105 | y: matrix[2] * vector.x + matrix[3] * vector.y 106 | }; 107 | } 108 | 109 | ``` 110 | 111 | ### Linear distance between 2 points 112 | ``` 113 | dx = x2 - x1; 114 | dy = y2 - y1; 115 | dist = Math.sqrt(dx*dx + dy*dy); 116 | ``` 117 | 118 | ```js 119 | // JavaScript 120 | var x1 = 3; 121 | var x2 = 5; 122 | var distance = x2 — x1; 123 | ``` 124 | 125 | ### Linear distance between 2 vectors 126 | #### a² + b² = c² 127 | 128 | ```js 129 | // Javascript 130 | var v1 = {x: 4, y: -9}; 131 | var v2 = {x: 5, y: 15}; 132 | 133 | var distance = Math.sqrt( Math.pow((v2.x — v1.x), 2) + Math.pow((v2.y — v1.y), 2) ); 134 | ``` 135 | 136 | ### Length of a vector 137 | #### Magnitude 138 | 139 | ```js 140 | // Javascript 141 | // 2D -> hypotenuse 142 | var v = {x: 4, y:-9}; 143 | var length = Math.sqrt( (Math.pow(v.x, 2) + Math.pow(v.y, 2)) ); 144 | 145 | // 3D 146 | var v = {x: 4, y:-9, z: 0.5}; 147 | var length = Math.sqrt( (Math.pow(v.x, 2) + Math.pow(v.y, 2) + Math.pow(v.z, 2) )); 148 | ``` 149 | 150 | ### Add and substract vectors 151 | 152 | ```js 153 | var v1 = {x: 2, y: 3}; 154 | var v2 = {x: 2, y: -2}; 155 | var addedVec = {x: v1.x + v2.x, y: v1.y + v2.y}; 156 | var subVec = {x: v1.x - v2.x, y: v1.y - v2.y}; 157 | ``` 158 | 159 | ### Normalize vector 160 | 161 | ```js 162 | // Javascript 163 | // 2D 164 | var v = {x: 4, y:-9}; 165 | var length = Math.sqrt( (Math.pow(v.x, 2) + Math.pow(v.y,2)) ); 166 | var n = {x: v.x / length, y: v.y / length}; 167 | 168 | // 3D 169 | var v = {x: 4, y:-9, z: 3}; 170 | var length = Math.sqrt( Math.pow(v.x, 2) + Math.pow(v.y,2) + Math.pow(v.z,2) ); 171 | var n = {x: v.x / length, y: v.y / length, z: v.z / length}; 172 | ``` 173 | 174 | ### Dot product vectors 175 | 176 | ```js 177 | // Javascript 178 | var v1 = {x: 4, y: 5, z: 9}; 179 | var v2 = {x: 5, y: 9, z: -5}; 180 | var dot = (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z); 181 | ``` 182 | 183 | ### Finding angle between 2 points 184 | 185 | ```js 186 | //Javascript 187 | var x = -3; 188 | var y = -2; 189 | var radians = Math.atan2(y, x); 190 | var degrees = radians * 180 / Math.PI; 191 | ``` 192 | 193 | ### Finding angle between 2 vectors 194 | 195 | ```js 196 | // Javascript 197 | var v1 = {x: 4, y: 5, z: 9}; 198 | var v2 = {x: 5, y: 9, z: -5}; 199 | var dot = (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z); 200 | 201 | var lengthv1 = length(v1); // see length 202 | var lengthv2 = length(v2); // see length 203 | 204 | var radians = Math.acos(dot / (lengthv1 * lengthv2)); 205 | var angle = radians * 180 / Math.PI; 206 | ``` 207 | 208 | ### Cross Product 209 | 210 | ```js 211 | // Javascript 212 | var v1 = {x: 1, y: 2, z: 3}; 213 | var v2 = {x: 3, y: 2, z: 1}; 214 | var cross = { 215 | x: v1.y*v2.z - v1.z*v2.y, 216 | y: v1.z*v2.x - v1.x*v2.z, 217 | z: v1.x*v2.y - v1.y*v2.x 218 | }; 219 | ``` 220 | 221 | ### Rotate to the mouse (or any point) 222 | ```js 223 | var dx = mouseX - spriteX; 224 | var dy = mouseY - spriteY; 225 | sprite.rotation = Math.atan2(dy, dx) * 180 / Math.PI; 226 | ``` 227 | 228 | ### Create waves 229 | ```js 230 | // value can be properties like x, y, alpha, rotation etc. 231 | public function onEnterFrame(event:Event) { 232 | value = center + Math.sin(angle) * range; 233 | angle += speed; 234 | } 235 | ``` 236 | 237 | ### Hex to decimal 238 | ``` 239 | trace(hexValue); 240 | ``` 241 | 242 | ### Decimal to hex 243 | ``` 244 | trace(decimalValue.toString(16)); 245 | ``` 246 | 247 | ### Combine component colors 248 | ``` 249 | color24 = red << 16 | green << 8 | blue; 250 | color32 = alpha << 24 | red << 16 | green << 8 | blue; 251 | ``` 252 | 253 | ### Extract component colors 254 | ``` 255 | red = color24 >> 16; 256 | green = color24 >> 8 & 0xFF; 257 | blue = color24 & 0xFF; 258 | 259 | alpha = color32 >> 24; 260 | red = color24 >> 16 & 0xFF; 261 | green = color24 >> 8 & 0xFF; 262 | blue = color24 & 0xFF; 263 | ``` 264 | 265 | ### Draw a curve through a point 266 | ``` 267 | //xt, yt is the point to draw through 268 | // x0, y0, x2, y2 is the end points 269 | x1 = xt * 2 - (x0 - x2) / 2; 270 | y1 = yt * 2 - (y0 - y2) / 2; 271 | moveTo(x0, y0); 272 | curveTo(x1, y1, x2, y2); 273 | ``` 274 | 275 | ### Convert angular velocity to x, y velocity 276 | ``` 277 | vx = Math.cos(angle) * speed; 278 | vy = Math.sin(angle) * speed; 279 | ``` 280 | 281 | ### Convert angular acceleration or any other force to x and y 282 | ``` 283 | ax = Math.cos(angle) * force; 284 | ay = Math.sin(angle) * force; 285 | ``` 286 | 287 | ### Add acceleration to velocity 288 | ``` 289 | vx += ax; 290 | vy += ay; 291 | ``` 292 | 293 | ### Add velocity to position 294 | ``` 295 | sprite.x += vx; 296 | sprite.y += vy; 297 | ``` 298 | 299 | ### Testing for out of bound 300 | ``` 301 | if(sprite.x - sprite.width / 2 > right) || 302 | sprite.x - sprite.width / 2 < left || 303 | sprite.y - sprite.height / 2 > bottom || 304 | sprite.y - sprite.height / 2 < top) 305 | { 306 | //remove or reposition sprite 307 | } 308 | ``` 309 | 310 | ### Apply friction (correct way) 311 | ``` 312 | speed = Math.sqrt(vx*vx + vy*vy); 313 | angle = Math.atan2(vy, vx); 314 | if(speed > friction) 315 | { 316 | speed -= friction; 317 | } else { 318 | speed = 0; 319 | } 320 | vx = Math.cos(angle) * speed; 321 | vy = Math.sin(angle) * speed; 322 | ``` 323 | 324 | ### Apply friction (the easy way) 325 | ``` 326 | vx *= friction; 327 | vy *= friction; 328 | ``` 329 | 330 | ### Simple easing, long form 331 | ``` 332 | var dx = targetX - sprite.x; 333 | var dy = targetY - sprite.y; 334 | vx = dx * easing; 335 | vy = dy * easing; 336 | sprite.x += vx; 337 | sprite.y += vy; 338 | ``` 339 | 340 | ### Simple easing, abbreviated form 341 | ``` 342 | vx = (targetX - sprite.x) * easing; 343 | vy = (targetY - sprite.y) * easing; 344 | sprite.x += vx; 345 | sprite.y += vy; 346 | ``` 347 | 348 | ### Simple easing, short form 349 | ``` 350 | sprite.x += (targetX - sprite.x) * easing; 351 | sprite.y += (targetY - sprite.y) * easing; 352 | ``` 353 | 354 | ### Simple spring, long form 355 | ``` 356 | var ax = (targetX - sprite.x) * spring; 357 | var ay = (targetY - sprite.y) * spring; 358 | vx += ax; 359 | vy += ay; 360 | vx *= friction; 361 | vy *= friction; 362 | sprite.x += vx; 363 | sprite.y += vy; 364 | ``` 365 | 366 | ### Simple spring, abbreviated form 367 | ``` 368 | vx = (targetX - sprite.x) * spring; 369 | vy = (targetY - sprite.y) * spring; 370 | vx *= friction; 371 | vy *= friction; 372 | sprite.x += vx; 373 | sprite.y += vy; 374 | ``` 375 | 376 | ### Simple spring, short form 377 | ``` 378 | vx = (targetX - sprite.x) * spring; 379 | vy = (targetY - sprite.y) * spring; 380 | sprite.x += (vx *= friction); 381 | sprite.y += (vy *= friction); 382 | ``` 383 | 384 | ### Offset spring 385 | ``` 386 | var dx = sprite.x - fixedX; 387 | var dy = sprite.y - fixedY; 388 | var angle = Math.atan2(dy, dx); 389 | var targetX = fixedX + Math.cos(angle) * springLength; 390 | var targetY = fixedY + Math.sin(angle) * springLength; 391 | // Spring to targetX and targetY; 392 | ``` 393 | 394 | ### Distance-based collision detection 395 | ``` 396 | // Starting with spriteA and spriteB 397 | // If using a plain sprite, or obejct without a radius property 398 | // you can use with and height divided by 2 399 | 400 | var dx = spriteB.x - spriteA.x; 401 | var dy = spriteB.y - spriteA.y; 402 | var dist = Math.sqrt(dx*dx + dy*dy); 403 | if(dist < spriteA.radius + spriteB.radius) 404 | { 405 | // handle collision 406 | } 407 | ``` 408 | 409 | ### Multiple-objects collision detection 410 | ``` 411 | var numObjects = 10; 412 | for (var i = 0; i < numObjects; i++) 413 | { 414 | var objectA = objects[i]; 415 | for (var j = i+1; j < numObjects; j++) 416 | { 417 | var objectB = objects[j]; 418 | // perform collision detection 419 | // between objectA and objectB 420 | } 421 | } 422 | ``` 423 | 424 | ### Coordinate rotation 425 | ``` 426 | x1 = Math.cos(angle) * x - Math.sin(angle) * y; 427 | y1 = Math.cos(angle) * y + Math.sin(angle) * x; 428 | ``` 429 | 430 | ### Reverse coordiante rotation 431 | ``` 432 | x1 = Math.cos(angle) * x + Math.sin(angle) * y; 433 | y1 = Math.cos(angle) * y - Math.sin(angle) * x; 434 | ``` 435 | 436 | ### Conservation of momentum in ActionScript (with a shortcut) 437 | ```js 438 | var vxTotal = vx0 - vx1; 439 | vx0 = ((ball0.mass - ball1.mass) * vx0 + 2 * ball1.mass * vx1) / (ball0.mass + ball1.mass); 440 | vx1 = vxTotal + vx0; 441 | ``` 442 | 443 | ### Gravity implementation 444 | ```js 445 | function gravitate(partA, partB) { 446 | var dx = partB.x - partA.x; 447 | var dy = partB.y - partA.y; 448 | var distSQ = dx*dx + dy*dy; 449 | var dist = Math.sqrt(distSQ); 450 | var force = partA.mass * partB.mass / distSQ; 451 | var ax = force * dx / dist; 452 | var ay = force * dy / dist; 453 | partA.vx += ax / partA.mass; 454 | partA.vy += ay / partA.mass; 455 | partB.vx += ax / partB.mass; 456 | partB.vy += ay / partB.mass; 457 | } 458 | ``` 459 | 460 | 461 | # Resources 462 | - [Coding Math](https://www.youtube.com/channel/UCF6F8LdCSWlRwQm_hfA2bcQ) ([Github](https://github.com/bit101/codingmath)) 463 | - [Generative Art by Matt Pearson](https://www.manning.com/books/generative-art) 464 | - [Math as code](https://github.com/Jam3/math-as-code) 465 | - [BetterExplained.com](http://betterexplained.com/) 466 | - [Essence of linear algebra](https://www.youtube.com/watch?v=kjBOesZCoqc) 467 | --------------------------------------------------------------------------------