Vector.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace bbiwarg.Utility
  7. {
  8. class Vector<T>
  9. {
  10. private T[] elements;
  11. public T x
  12. {
  13. get
  14. {
  15. return elements[0];
  16. }
  17. set
  18. {
  19. elements[0] = value;
  20. }
  21. }
  22. public T y
  23. {
  24. get
  25. {
  26. return elements[1];
  27. }
  28. set
  29. {
  30. elements[1] = value;
  31. }
  32. }
  33. public T z
  34. {
  35. get
  36. {
  37. return elements[2];
  38. }
  39. set
  40. {
  41. elements[2] = value;
  42. }
  43. }
  44. public Vector(int numberOfElements)
  45. {
  46. this.elements = new T[numberOfElements];
  47. }
  48. public Vector(T[] elements)
  49. {
  50. this.elements = elements;
  51. }
  52. public Vector(Vector<T> vector)
  53. {
  54. this.elements = new T[vector.length()];
  55. for (int i = 0; i < elements.Length; i++)
  56. {
  57. elements[i] = vector[i];
  58. }
  59. }
  60. public Vector<T> copy()
  61. {
  62. Vector<T> newVector = new Vector<T>(this);
  63. return newVector;
  64. }
  65. public T this[int index]
  66. {
  67. get
  68. {
  69. return elements[index];
  70. }
  71. set
  72. {
  73. elements[index] = value;
  74. }
  75. }
  76. public int length()
  77. {
  78. return elements.Length;
  79. }
  80. public void add(Vector<T> summand)
  81. {
  82. for (int i = 0; i < elements.Length; i++)
  83. {
  84. elements[i] = (dynamic)elements[i] + summand[i];
  85. }
  86. }
  87. public void subtract(Vector<T> subtrahend)
  88. {
  89. for (int i = 0; i < elements.Length; i++)
  90. {
  91. elements[i] = (dynamic)elements[i] - subtrahend[i];
  92. }
  93. }
  94. public void multiply(T scalar)
  95. {
  96. for (int i = 0; i < elements.Length; i++)
  97. {
  98. elements[i] = (dynamic)scalar * elements[i];
  99. }
  100. }
  101. public T norm()
  102. {
  103. return subNorm(elements.Length);
  104. }
  105. public T subNorm(int subLength)
  106. {
  107. T result = (dynamic)0;
  108. for (int i = 0; i < subLength; i++)
  109. {
  110. result += (dynamic)elements[i] * elements[i];
  111. }
  112. return (T)Math.Sqrt((dynamic)result);
  113. }
  114. public T distance(Vector<T> vector)
  115. {
  116. return (vector - this).norm();
  117. }
  118. public T sum()
  119. {
  120. T result = (dynamic)0;
  121. for (int i = 0; i < this.length(); i++)
  122. {
  123. result += (dynamic)elements[i];
  124. }
  125. return result;
  126. }
  127. public Vector<T> normalize()
  128. {
  129. T norm = this.norm();
  130. Vector<T> result = new Vector<T>(this);
  131. for (int i = 0; i < result.length(); i++)
  132. {
  133. result[i] = (result[i] / (dynamic)norm);
  134. }
  135. return result;
  136. }
  137. public T subDistance(Vector<T> vector, int subLength)
  138. {
  139. return (vector - this).subNorm(subLength);
  140. }
  141. private static void checkLength(Vector<T> vector1, Vector<T> vector2)
  142. {
  143. if (vector1.length() != vector2.length())
  144. throw new ArgumentException("The vectors must have the same length");
  145. }
  146. public static Vector<T> operator +(Vector<T> summand1, Vector<T> summand2)
  147. {
  148. checkLength(summand1, summand2);
  149. Vector<T> result = new Vector<T>(summand1);
  150. result.add(summand2);
  151. return result;
  152. }
  153. public static Vector<T> operator -(Vector<T> minuend, Vector<T> subtrahend)
  154. {
  155. checkLength(minuend, subtrahend);
  156. Vector<T> result = new Vector<T>(minuend);
  157. result.subtract(subtrahend);
  158. return result;
  159. }
  160. public static T operator *(Vector<T> vector1, Vector<T> vector2)
  161. {
  162. checkLength(vector1, vector2);
  163. T result = (dynamic)0;
  164. for (int i = 0; i < vector1.length(); i++)
  165. {
  166. result += (dynamic)vector1[i] * vector2[i];
  167. }
  168. return result;
  169. }
  170. public static bool operator ==(Vector<T> vector1, Vector<T> vector2)
  171. {
  172. checkLength(vector1, vector2);
  173. bool result = true;
  174. for (int i = 0; i < vector1.length(); i++)
  175. {
  176. if (vector1[i] != (dynamic)vector2[i])
  177. {
  178. result = false;
  179. break;
  180. }
  181. }
  182. return result;
  183. }
  184. public static bool operator !=(Vector<T> vector1, Vector<T> vector2)
  185. {
  186. return !(vector1 == vector2);
  187. }
  188. public static Vector<T> crossProduct(Vector<T> vector1, Vector<T> vector2)
  189. {
  190. if (vector1.length() != 3 || vector2.length() != 3)
  191. throw new ArgumentException("The vectors' length should be 3");
  192. Vector<T> result = new Vector<T>(vector1.length());
  193. result[0] = (dynamic)vector1.y * vector2.z - (dynamic)vector1.z * vector2.y;
  194. result[1] = (dynamic)vector1.z * vector2.x - (dynamic)vector1.x * vector2.z;
  195. result[2] = (dynamic)vector1.x * vector2.y - (dynamic)vector1.y * vector2.x;
  196. return result;
  197. }
  198. public static Vector<T> pointwiseMultiply(Vector<T> vector1, Vector<T> vector2)
  199. {
  200. checkLength(vector1, vector2);
  201. Vector<T> result = new Vector<T>(vector1);
  202. for (int i = 0; i < vector1.length(); i++)
  203. {
  204. result[i] = (dynamic)result[i] * vector2[i];
  205. }
  206. return result;
  207. }
  208. public static float distancePointPlane(Vector<T> point, Vector<T> planeA, Vector<T> planeB, Vector<T> planeC)
  209. {
  210. //TODO - Diese funktion funktioniert nur mit T = float,
  211. //die normalisierte Normale einer Ebene macht nur mit floats sinn (werte zwischen 0 und 1)
  212. if (point.length() != 3 || planeA.length() != 3 || planeB.length() != 3 || planeC.length() != 3)
  213. throw new ArgumentException("The vectors' length should be 3");
  214. Vector<T> ab = planeB - planeA;
  215. Vector<T> ac = planeC - planeA;
  216. Vector<T> normal = crossProduct(ab, ac).normalize();
  217. Vector<T> temp = point - planeA;
  218. temp = pointwiseMultiply(temp, normal);
  219. temp = pointwiseMultiply(temp, normal);
  220. T sum = temp.sum();
  221. temp = pointwiseMultiply(normal, normal);
  222. T sumR = temp.sum();
  223. if (sumR == (dynamic)0)
  224. throw new ArgumentException("the points do not clamp an Plane");
  225. float distance = (sum * (dynamic)(-1)) / sumR;
  226. if (distance < 0)
  227. distance *= (float)(-1);
  228. return distance;
  229. }
  230. }
  231. }