Advertisement
Guest User

ray

a guest
May 24th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.78 KB | None | 0 0
  1. #include <math.h>
  2. #include "objects.h"
  3. #include "ray.h"
  4.  
  5. /*
  6. Metoda znajdujaca przeciecie promienia swiatla (raywp) z kula.
  7. Zwraca zero dla braku przeciecia lub 1 gdy istnieje przeciecie
  8. Wyliczona wartosc "t" zwracana jest przez argument!
  9. */
  10.  
  11. int Sphere::FindInter(const Ray &ray1, double &t)
  12. {
  13. double a, b, c; // wsp. rownania
  14. double delta;
  15. double t1, t2; // pierwiastki
  16. Vector temp = ray1.Point() - pos; // wektor pomocniczy
  17. Vector dir = ray1.Direction(); // wektor kierunkowy
  18.  
  19. //a = dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2];
  20. a = Dot(dir, dir);
  21. b = 2 * Dot(dir, temp);
  22. c = Dot(temp, temp) - rr; // parametry rownania kwadratowego
  23.  
  24. delta = b * b - 4.0 * a * c; // rozwiazujemy rownanie kwadratowe by znalezc przeciecie
  25.  
  26. if (delta < 0)
  27. return 0; // brak przeciec
  28. else
  29. {
  30. delta = sqrt(delta);
  31.  
  32. t1 = (-b - delta) / (2.0 * a); // obliczenie pierwiastkow...
  33. if (fabs(t1) < 0.01) t1 = -1.0; //... z zabezpieczeniem na zbyt male wartosci
  34.  
  35. t2 = (-b + delta) / (2.0 * a);
  36. if (fabs(t2) < 0.01) t2 = -1.0;
  37.  
  38. if (t1 < 0)
  39. if (t2 < t)
  40. if (t2 > 0)
  41. {
  42. t = t2;
  43. return 1; // znaleziono przeciecie
  44. }
  45. else
  46. return 0; // brak przeciec
  47. else
  48. return 0; // brak...
  49. else
  50. if (t2 < 0)
  51. if (t1 < t)
  52. if (t1 > 0)
  53. {
  54. t = t1;
  55. return 1; // przeciecie
  56. }
  57. else return 0; // brak
  58. else
  59. return 0; // brak
  60. else
  61. {
  62. t1 = t1 < t2 ? t1 : t2; // znajdz mniejszy
  63. if (t1 < t)
  64. {
  65. t = t1;
  66. return 1; // okay
  67. }
  68. else
  69. return 0; // brak
  70. }
  71. }
  72. /*
  73.  
  74. UWAGA!!!
  75. Celem metody jest
  76. a) obliczenie pierwiastkow (rownania przeciecia kuli z promieniem)
  77. b) sprawdzenie warunkow dla obliczonych pierwiastkow
  78. c) przekazanie informacji o znalezionym pierwiastku (o ile spelnia on warunki).
  79.  
  80. ad. a) Wszystkie obliczenia przeprowadzamy na zmiennych typu 'double'. Pierwiastek równania
  81. oznaczający przecięcie przyjmujemy za ujemny gdy jest mniejszy niz 0.001 (ze wzgl. na niedokladnosc
  82. obliczen).
  83. ad. b) Przekazana do funkcji wartosc parametru t opisuje najbliższe znalezione do tej pory
  84. przeciecie. _Dodatkowym_ warunkiem ktory musi byc spelniony przez pierwiastek jest aby jego
  85. wartosc byla mniejsza niz przekazana wartosc t.
  86. ad. c) Jezeli funkcja nie znajdzie przeciecia spelniajacego warunki, zwraca 0 i nie zmienia
  87. wartosci 't', jezeli natomiast znajdzie przeciecie, zwraca 1 i modyfikuje parametr 't'.
  88.  
  89. Informacje pomocnicze:
  90.  
  91. Punkt startowy (= położenie kamery) oraz wektor kierunkowy
  92. zwracają odpowiednie metody wywołane na rzecz obiektu promienia (Ray)
  93.  
  94. Vector - klasa reprezentujaca wektor; dostęp do składowych przez operator
  95. nawiasów kwadratowych: w[0], w[1], w[2]
  96. Vector Normalize(const Vector &w) - funkcja zwracajaca jako rezultat wektor znormalizowany
  97.  
  98. */
  99.  
  100.  
  101. return 0;
  102. }
  103.  
  104.  
  105. /*
  106. Metoda znajduje wektor normalny do kuli w danym jej punkcie
  107. */
  108.  
  109. Vector Sphere::FindNormal(const Vector &v)
  110. {
  111. return Normalize(v - pos);
  112. }
  113.  
  114.  
  115. /*
  116. Metoda znajdujaca przeciecie dla walca
  117. */
  118.  
  119. int Cylinder::FindInter(const Ray &l, double &t)
  120. {
  121. double a, b, c; // wsp. rownania
  122. double delta;
  123. double t1, t2; // pierwiastki
  124. Vector temp = l.Point() - point; // wektor pomocniczy
  125. Vector dir = l.Direction(); // wektor kierunkowy
  126.  
  127. a = Dot(dir, dir * axis);
  128. b = 2 * Dot(temp, dir * axis);
  129. c = Dot(temp, temp * axis) - 1; // parametry rownania kwadratowego
  130.  
  131. delta = b * b - 4.0 * a * c; // rozwiazujemy rownanie kwadratowe by znalezc przeciecie
  132.  
  133. if (delta < 0)
  134. return 0; // brak przeciec
  135. else
  136. {
  137. delta = sqrt(delta);
  138.  
  139. t1 = (-b - delta) / (2.0 * a); // obliczenie pierwiastkow...
  140. if (fabs(t1) < 0.01) t1 = -1.0; //... z zabezpieczeniem na zbyt male wartosci
  141.  
  142. t2 = (-b + delta) / (2.0 * a);
  143. if (fabs(t2) < 0.01) t2 = -1.0;
  144.  
  145. if (t1 < 0)
  146. if (t2 < t)
  147. if (t2 > 0)
  148. {
  149. t = t2;
  150. return 1; // znaleziono przeciecie
  151. }
  152. else
  153. return 0; // brak przeciec
  154. else
  155. return 0; // brak...
  156. else
  157. if (t2 < 0)
  158. if (t1 < t)
  159. if (t1 > 0)
  160. {
  161. t = t1;
  162. return 1; // przeciecie
  163. }
  164. else return 0; // brak
  165. else
  166. return 0; // brak
  167. else
  168. {
  169. t1 = t1 < t2 ? t1 : t2; // znajdz mniejszy
  170. if (t1 < t)
  171. {
  172. t = t1;
  173. return 1; // okay
  174. }
  175. else
  176. return 0; // brak
  177. }
  178. }
  179. }
  180.  
  181. /*
  182. Metoda znajdujaca normalna do walca
  183. */
  184.  
  185. Vector Cylinder::FindNormal(const Vector &a)
  186. {
  187. return Normalize((a - point) * axis);
  188. }
  189.  
  190. /*
  191. Metoda znajdujaca przeciecie dla stozka
  192. */
  193.  
  194. int Cone::FindInter(const Ray &l, double &t)
  195. {
  196. double a, b, c; // wspolczynniki rownania
  197. double delta; // delta rownania
  198. double t1, t2; // pierwiastki
  199. Vector temp = l.Point() - point; // wektor pomocniczy
  200. Vector dir = l.Direction(); // wektor kierunku
  201.  
  202. a = Dot(dir, dir * axis);
  203. b = 2 * Dot(temp, dir * axis);
  204. c = Dot(temp, temp * axis);
  205.  
  206. delta = b * b - 4.0 * a * c; // rozwiazanie rownania kawadratowego...
  207.  
  208. if (delta < 0)
  209. return 0; // brak przeciec
  210. else
  211. {
  212. delta = sqrt(delta);
  213.  
  214. t1 = (-b - delta) / (2.0 * a); // obliczenie pierwiastkow
  215. if (fabs(t1) < 0.01) t1 = -1.0; // z uwzglednieniem pewnej dokladnosci
  216.  
  217. t2 = (-b + delta) / (2.0 * a);
  218. if (fabs(t2) < 0.01) t2 = -1.0;
  219.  
  220. if (t1 < 0)
  221. if (t2 < t)
  222. if (t2 > 0)
  223. {
  224. t = t2;
  225. return 1; // jest przeciecie
  226. }
  227. else
  228. return 0;
  229. else
  230. return 0; // brak
  231. else
  232. if (t2 < 0)
  233. if (t1 < t)
  234. if (t1 > 0)
  235. {
  236. t = t1;
  237. return 1; // przeciecie
  238. }
  239. else
  240. return 0; // brak
  241. else
  242. return 0; // brak
  243. else
  244. {
  245. t1 = t1 < t2 ? t1 : t2; // znajdujemy mniejszy
  246. if (t1 < t)
  247. {
  248. t = t1;
  249. return 1; // przeciecie
  250. }
  251. else
  252. return 0; // brak przeciecia
  253. }
  254. }
  255. }
  256.  
  257.  
  258. /*
  259. Metoda znajdujaca normalna do stozka
  260. */
  261.  
  262. Vector Cone::FindNormal(const Vector &a)
  263. {
  264. return Normalize((a - point) * axis);
  265. }
  266.  
  267.  
  268. /*
  269. Metoda znajdujaca przeciecie z plaszczyzna
  270. - o wiele prostsza niz dla kuli, walca czy stozka
  271. */
  272.  
  273. int Plane::FindInter(const Ray &ray_cp, double &t)
  274. {
  275. double a, b, c; // wsp. rownania
  276. double delta;
  277. double t1; // pierwiastki
  278. Vector temp = ray_cp.Point(); // wektor pomocniczy
  279. Vector dir = ray_cp.Direction(); // wektor kierunkowy
  280.  
  281. a = normal[0];
  282. b = normal[1];
  283. c = normal[2]; // parametry rownania kwadratowego
  284.  
  285. //delta = b * b - 4.0 * a * c; // rozwiazujemy rownanie kwadratowe by znalezc przeciecie
  286. if (t1<0.001)
  287. return 0;
  288. if (t1<t) {
  289. t = t1;
  290. return 1;
  291. }
  292. return 0;
  293.  
  294.  
  295. // Uwaga: parametry A, B, C plaszczyzny to po prostu skladowe jej wektora normalnego
  296.  
  297. return 1;
  298. }
  299.  
  300. /*
  301. Metoda znajdujaca normalna do plaszczyzny
  302. */
  303.  
  304. Vector Plane::FindNormal(const Vector &a)
  305. {
  306.  
  307. return Normalize(normal);
  308. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement