Util.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Util.cpp
  2. #include "Util.h"
  3. #include <cmath>
  4. #include <cstdlib>
  5. #define PI 3.14159265
  6. using namespace std;
  7. Vec3 operator/(Vec3 v, double scalar)
  8. {
  9. return Vec3(v.x/scalar, v.y/scalar, v.z/scalar);
  10. }
  11. Vec3 operator+(Vec3 v1, Vec3 v2)
  12. {
  13. return Vec3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
  14. }
  15. bool operator==(Vec3 v1, Vec3 v2)
  16. {
  17. return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z;
  18. }
  19. double Magnitude(Vec3 v)
  20. {
  21. return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
  22. }
  23. Vec3 Normalize(Vec3 v)
  24. {
  25. return v/Magnitude(v);
  26. }
  27. Vec3 Perpendicular(Vec3 v)
  28. {
  29. int range = 100;
  30. v = Normalize(v);
  31. if (v.x == 0)
  32. return Vec3(1,0,0);
  33. if (v.y == 0)
  34. return Vec3(0,1,0);
  35. if (v.z == 0)
  36. return Vec3(0,0,1);
  37. Vec3 res(0,0,0);
  38. res.x = (double)(rand() % (2*range) - range)/range;
  39. res.y = (double)(rand() % (2*range) - range)/range;
  40. res.z = -(v.x*res.x + v.y*res.y)/v.z;
  41. return res;
  42. }
  43. double DotProd(Vec3 v1, Vec3 v2)
  44. {
  45. double res = 0.0;
  46. res += v1.x*v2.x;
  47. res += v1.y*v2.y;
  48. res += v1.z*v2.z;
  49. return res;
  50. }
  51. Vec3 CrossProd(Vec3 v1, Vec3 v2)
  52. {
  53. Vec3 res{0, 0, 0};
  54. res.x = v1.y*v2.z - v2.y*v1.z;
  55. res.y = -v1.x*v2.z + v2.x*v1.z;
  56. res.z = v1.x*v2.y - v2.x*v1.y;
  57. return res;
  58. }
  59. Matrix33 operator*(Matrix33 left, Matrix33 right)
  60. {
  61. Matrix33 res;
  62. res.mat[0][0] = left.mat[0][0]*right.mat[0][0] + left.mat[0][1]*right.mat[1][0] + left.mat[0][2]*right.mat[2][0];
  63. res.mat[0][1] = left.mat[0][0]*right.mat[0][1] + left.mat[0][1]*right.mat[1][1] + left.mat[0][2]*right.mat[2][1];
  64. res.mat[0][2] = left.mat[0][0]*right.mat[0][2] + left.mat[0][1]*right.mat[1][2] + left.mat[0][2]*right.mat[2][2];
  65. res.mat[1][0] = left.mat[1][0]*right.mat[0][0] + left.mat[1][1]*right.mat[1][0] + left.mat[1][2]*right.mat[2][0];
  66. res.mat[1][1] = left.mat[1][0]*right.mat[0][1] + left.mat[1][1]*right.mat[1][1] + left.mat[1][2]*right.mat[2][1];
  67. res.mat[1][2] = left.mat[1][0]*right.mat[0][2] + left.mat[1][1]*right.mat[1][2] + left.mat[1][2]*right.mat[2][2];
  68. res.mat[2][0] = left.mat[2][0]*right.mat[0][0] + left.mat[2][1]*right.mat[1][0] + left.mat[2][2]*right.mat[2][0];
  69. res.mat[2][1] = left.mat[2][0]*right.mat[0][1] + left.mat[2][1]*right.mat[1][1] + left.mat[2][2]*right.mat[2][1];
  70. res.mat[2][2] = left.mat[2][0]*right.mat[0][2] + left.mat[2][1]*right.mat[1][2] + left.mat[2][2]*right.mat[2][2];
  71. return res;
  72. }
  73. Matrix33 Transpose(Matrix33 in)
  74. {
  75. Matrix33 res;
  76. res.mat[0][0] = in.mat[0][0];
  77. res.mat[0][1] = in.mat[1][0];
  78. res.mat[0][2] = in.mat[2][0];
  79. res.mat[1][0] = in.mat[0][1];
  80. res.mat[1][1] = in.mat[1][1];
  81. res.mat[1][2] = in.mat[2][1];
  82. res.mat[2][0] = in.mat[0][2];
  83. res.mat[2][1] = in.mat[1][2];
  84. res.mat[2][2] = in.mat[2][2];
  85. return res;
  86. }
  87. Matrix33 Rodrigues(Vec3 v, double angle)
  88. {
  89. Matrix33 rot;
  90. rot.mat[0][0] = (1-cos(angle))*v.x*v.x + cos(angle);
  91. rot.mat[0][1] = (1-cos(angle))*v.x*v.y - sin(angle)*v.z;
  92. rot.mat[0][2] = (1-cos(angle))*v.x*v.z + sin(angle)*v.y;
  93. rot.mat[1][0] = (1-cos(angle))*v.y*v.x + sin(angle)*v.z;
  94. rot.mat[1][1] = (1-cos(angle))*v.y*v.y + cos(angle);
  95. rot.mat[1][2] = (1-cos(angle))*v.y*v.z - sin(angle)*v.x;
  96. rot.mat[2][0] = (1-cos(angle))*v.z*v.x - sin(angle)*v.y;
  97. rot.mat[2][1] = (1-cos(angle))*v.z*v.y + sin(angle)*v.x;
  98. rot.mat[2][2] = (1-cos(angle))*v.z*v.z + cos(angle);
  99. return rot;
  100. }
  101. Matrix33 RotationVecVec(Vec3 v1, Vec3 v2)
  102. {
  103. // This function finds the rotation from one vector to the other. The process
  104. // is the following:
  105. // a. Normalize vectors
  106. // b. Middle direction
  107. // c. Normalize middle vector
  108. // d. Use middle vector in Rodrigues' formula with rotation of pi
  109. v1 = Normalize(v1);
  110. v2 = Normalize(v2);
  111. Vec3 midVec(0,0,0);
  112. if (v1+v2 == Vec3(0,0,0)) // vectors are opposite
  113. midVec = Perpendicular(v1);
  114. else
  115. midVec = v1+v2;
  116. midVec = Normalize(midVec);
  117. // for pi rotation cos(pi) = -1, sin(pi) = 0
  118. Matrix33 rot = Rodrigues(midVec, PI);
  119. //rot.mat[0][0] = 2*midVec.x*midVec.x - 1;
  120. //rot.mat[0][1] = 2*midVec.x*midVec.y;
  121. //rot.mat[0][2] = 2*midVec.x*midVec.z;
  122. //rot.mat[1][0] = 2*midVec.y*midVec.x;
  123. //rot.mat[1][1] = 2*midVec.y*midVec.y - 1;
  124. //rot.mat[1][2] = 2*midVec.y*midVec.z;
  125. //rot.mat[2][0] = 2*midVec.z*midVec.x;
  126. //rot.mat[2][1] = 2*midVec.z*midVec.y;
  127. //rot.mat[2][2] = 2*midVec.z*midVec.z - 1;
  128. return rot;
  129. }
  130. Vec3 RotatePoint(Matrix33 rot, Vec3 v)
  131. {
  132. Vec3 res(0,0,0);
  133. res.x = rot.mat[0][0]*v.x + rot.mat[0][1]*v.y + rot.mat[0][2]*v.z;
  134. res.y = rot.mat[1][0]*v.x + rot.mat[1][1]*v.y + rot.mat[1][2]*v.z;
  135. res.z = rot.mat[2][0]*v.x + rot.mat[2][1]*v.y + rot.mat[2][2]*v.z;
  136. return res;
  137. }