1 module daque.math.geometry; 2 3 import std.math; 4 5 void geometryTest() 6 { 7 import std.stdio; 8 writeln("daque geometry correctly linked"); 9 } 10 11 /++ 12 Mathematical dot product 13 +/ 14 R dot(R)(R[] v, R[] w) 15 in 16 { 17 assert(v.length == w.length, "Dot product can only be applied between to vectors of the same dimension"); 18 } 19 out 20 { 21 22 } 23 do 24 { 25 import std.array; 26 import std.algorithm; 27 28 R[] products; 29 products.length = v.length; 30 products[] = v[] * w[]; 31 return products.array.sum; 32 } 33 34 /++ 35 Mathematical distance between to points 36 +/ 37 real distance(R)(R[] v, R[] w) 38 in 39 { 40 assert(v.length == w.length, "distance can only be calculated between same-dimensional vectors"); 41 } 42 out 43 { 44 } 45 do 46 { 47 R[] diff; 48 diff.length = v.length; 49 diff[] = w[] - v[]; 50 return magnitude(diff); 51 } 52 53 /++ 54 Mathematical cross product 55 +/ 56 R[] cross(R)(R[] v, R[] w) 57 in 58 { 59 assert(v.length == 3 && w.length == 3, "Cross product can only be applied between 3d vectors"); 60 } 61 out (result) 62 { 63 R[] resultDup = result.dup; 64 assert(approxEqual(dot(resultDup, v), 0.0) && approxEqual(dot(resultDup, w), 0.0), "Cross product was not orthogonal to it's operands"); 65 } 66 do 67 { 68 R[] result; 69 result.length = 3; 70 for(uint i; i < 3; i++) 71 { 72 int j = (i + 1) % 3; 73 int k = (j + 1) % 3; 74 result[i] = v[j] * w[k] - v[k] * w[j]; 75 } 76 return result; 77 } 78 79 R magnitudeSquared(R)(R[] v) 80 out(result) 81 { 82 assert(result >= 0); 83 } 84 do 85 { 86 return dot(v, v); 87 } 88 89 real magnitude(R)(R[] v) 90 { 91 return sqrt(cast(real)magnitudeSquared(v)); 92 } 93 94 R[] normalize(R)(R[] v) 95 in 96 { 97 assert(magnitudeSquared(v) != 0, "Cannot normalize a zero vector"); 98 } 99 out(result) 100 { 101 assert(approxEqual(magnitudeSquared(result.dup), 1), "Normalized vector wasn't unitary"); 102 } 103 do 104 { 105 R[] normalized; 106 normalized.length = v.length; 107 normalized[] = v[] / magnitude(v); 108 return normalized; 109 } 110 111 unittest 112 { 113 assert(distance([0.0, 0.0], [0.5, 0.5]) != 0.0); 114 }