Advertisement
Guest User

Untitled

a guest
Mar 30th, 2015
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.65 KB | None | 0 0
  1. // glfw_30.cpp : Defines the entry point for the console application.
  2. // http://www.glfw.org/docs/latest/quick.html
  3.  
  4. #include "stdafx.h"
  5.  
  6. #include "Object\Object.h"
  7. #include <iostream>
  8. #include <fstream>
  9. #include <cmath>
  10. #include <time.h>
  11. #include <algorithm>
  12.  
  13.  
  14.  
  15. std::vector<Point3f> spher;
  16.  
  17. #define PI 3.14159265359
  18. #define EPS 0.001
  19.  
  20. Point3f SphericalToXYZ(float phi, float psi, float radius){
  21. phi *= PI / 180;
  22. psi *= PI / 180;
  23.  
  24. return{ cos(phi)*cos(psi), sin(phi)*cos(psi), sin(psi) };
  25. }
  26.  
  27. Point3f XYZToSpherical(Point3f coord){
  28. if (coord.x == 0 && coord.y == 0){
  29. return{ 0, 90, 1 };
  30. }
  31. return{ (float)(acos(coord.x / sqrt(coord.x*coord.x + coord.y*coord.y))*(180 / PI)), (float)(asin(coord.z)*(180 / PI)), (float)1 };
  32. }
  33.  
  34. //Поиск расстояния от точки point до отрезка с координатами c1 c2
  35. float Distance_sqr2(Point3f point, Point3f c1, Point3f c2){
  36.  
  37. // Вектор из первого конца отрезка в точку point
  38. Point3f p1 = point - c1;
  39. Point3f p2 = point - c2;
  40. // Вектор из первого конца отрезка во второй
  41. Point3f v = c2 - c1;
  42.  
  43. //Вернуть минимальное из расстоний до концов отрезков, если проекция точки не падает на отрезок
  44. if (p1 * v <= 0 || p2 * (v * -1) <= 0){
  45. float dist = std::min(p1.norm(), p2.norm());
  46. return dist*dist;
  47. }
  48.  
  49. // Длинна вектора p
  50. float plong = p1.norm();
  51. //Нормированный вектор v
  52. Point3f ve = v / v.norm();
  53. // Длинна проекции p на v
  54. float proect = ve * p1;
  55.  
  56. // Расстояние считается по теореме Пифагора
  57. return plong*plong - proect*proect;
  58. }
  59.  
  60. // Проверяет, лежит ли точка на сфере слева от напрвленной дуги
  61. // point задаёт точку
  62. // с1, с2 - коорднаты направленной дуги (начало/конец)
  63. bool isRightSide(Point3f point, Point3f c1, Point3f c2){
  64. // Вектор нормали(направлен влево по отн. к дуге) к плоскости, заданной радиус-векторами c1, c2
  65. Point3f n = c1 ^ c2;
  66.  
  67. // Точка лежит справа по отношению к дуге если скалярное произведение n и point полоительное
  68. return point * n <= 0;
  69. }
  70.  
  71. double angleBetweenVectors(Point3f a, Point3f b){
  72. double res = (a * b) / (a.norm() * b.norm());
  73. if (res > 1) return acos(1);
  74. if (res < -1) return (-1);
  75. return acos(res);
  76. }
  77.  
  78. bool IsIntersect(Point3f d1, Point3f d2, Point3f p, Point3f m){
  79. Point3f V1 = d1 ^ d2;
  80. Point3f V2 = p ^ m;
  81. Point3f U1 = V1 / V1.norm();
  82. Point3f U2 = V2 / V2.norm();
  83. Point3f D = U1 ^ U2;
  84. Point3f S = D / D.norm();
  85. Point3f S1 = S;
  86. Point3f S2 = S * (-1);
  87.  
  88. double a_d1_d2 = angleBetweenVectors(d1, d2);
  89. double a_d1_s1 = angleBetweenVectors(d1, S1);
  90. double a_s1_d2 = angleBetweenVectors(S1, d2);
  91.  
  92. double a_p_m = angleBetweenVectors(p, m);
  93. double a_p_i = angleBetweenVectors(p, S1);
  94. double a_i_m = angleBetweenVectors(S1, m);
  95.  
  96. if (abs(a_d1_d2 - (a_d1_s1 + a_s1_d2)) <= EPS && (abs(a_p_m - (a_p_i + a_i_m))) <= EPS){
  97. return 1;
  98. }
  99.  
  100.  
  101. a_d1_d2 = angleBetweenVectors(d1, d2);
  102. a_d1_s1 = angleBetweenVectors(d1, S2);
  103. a_s1_d2 = angleBetweenVectors(S2, d2);
  104.  
  105. a_p_m = angleBetweenVectors(p, m);
  106. a_p_i = angleBetweenVectors(p, S2);
  107. a_i_m = angleBetweenVectors(S2, m);
  108.  
  109. if (abs(a_d1_d2 - (a_d1_s1 + a_s1_d2)) <= EPS && (abs(a_p_m - (a_p_i + a_i_m))) <= EPS){
  110. return 1;
  111. }
  112. else {
  113. return 0;
  114. }
  115. }
  116.  
  117. bool IsIntersect2(Point3f d1, Point3f d2, Point3f p, Point3f m){
  118. Point3f N = p^m;
  119. Point3f S = d2 - d1;
  120. GLdouble t = -(N * d1) / (N * S);
  121. Point3f I = (S * t) + d1;
  122. I = I / I.norm();
  123.  
  124. if (t > 1 || t < 0) return 0;
  125.  
  126. double a_d1_d2 = angleBetweenVectors(d1, d2);
  127. double a_d1_s1 = angleBetweenVectors(d1, I);
  128. double a_s1_d2 = angleBetweenVectors(I, d2);
  129.  
  130. double a_p_m = angleBetweenVectors(p, m);
  131. double a_p_i = angleBetweenVectors(p, I);
  132. double a_i_m = angleBetweenVectors(I, m);
  133.  
  134. if (abs(a_d1_d2 - (a_d1_s1 + a_s1_d2)) <= EPS && (abs(a_p_m - (a_p_i + a_i_m))) <= EPS){
  135. return 1;
  136. }
  137. else {
  138. return 0;
  139. }
  140.  
  141. }
  142. __inline Point3f middlePoint(Point3f c1, Point3f c2){
  143. Point3f c = (c1 + c2) / 2;
  144. return c / c.norm();
  145. }
  146.  
  147. __inline Point3f factorPoint(Point3f c1, Point3f c2, float factor){
  148. Point3f c = (c2 - c1)*factor + c1;
  149. return c / c.norm();
  150. }
  151.  
  152. Point3f isInCurcuit(Point3f point, std::vector<Point3f> circuit){
  153.  
  154. float minDist = 100000000, dist;
  155. int ind = 0, eqNum = 0;
  156.  
  157. for (int i = 0; i < circuit.size(); i++){
  158. dist = Distance_sqr2(point, circuit[i], circuit[(i + 1) % circuit.size()]);
  159. if (dist == minDist && i == (ind + 1) % circuit.size()) eqNum = 1;
  160. if (dist == minDist && ind == (i + 1) % circuit.size()){
  161. eqNum = 1;
  162. ind = i;
  163. }
  164. if (dist < minDist){
  165. minDist = dist;
  166. ind = i;
  167. eqNum = 0;
  168. }
  169. }
  170. if (eqNum){
  171. //Point3f c1 = spher[ind];
  172. //Point3f c2 = spher[(ind + 1) % circuit.size()];
  173. //Point3f c3 = spher[(ind + 2) % circuit.size()];
  174. Point3f d1 = circuit[ind];
  175. Point3f d2 = circuit[(ind + 1) % circuit.size()];
  176. Point3f d3 = circuit[(ind + 2) % circuit.size()];
  177.  
  178. long double angle = angleBetweenVectors(d1 - d2, d3 - d2);
  179. if (angle > PI*0.99 && 1 == 0){
  180. bool ans = isRightSide(point, d1, d2);
  181. Point3f color;
  182. ans ? color = { 0, 1, 0 } : color = { 1, 0, 0 };
  183. return color;
  184. }
  185. //factor *= factor * factor * factor;
  186.  
  187. Point3f p1 = factorPoint(d2, d1, 0.00001);
  188. Point3f p2 = factorPoint(d2, d3, 0.00001);
  189.  
  190. Point3f dXYZ = middlePoint(p1, p2);
  191. Point3f d = XYZToSpherical(dXYZ);
  192.  
  193.  
  194. bool d_in_C = isRightSide(dXYZ, d1, d2);
  195.  
  196.  
  197. bool is1 = IsIntersect(d1, d2, point, dXYZ);
  198. bool is2 = IsIntersect(d2, d3, point, dXYZ);
  199.  
  200. Point3f dogXYZ = middlePoint(p1, dXYZ);
  201. bool is3 = IsIntersect(d1, d2, point, dogXYZ);
  202. bool is4 = IsIntersect(d2, d3, point, dogXYZ);
  203.  
  204. bool ans = ((is1 || is2) && (is3 || is4)) ^ d_in_C;
  205. // if (point.z < 0 && !ans) printf("%d %d\n", )
  206. //return { 0, 0, 1 }; //ans;
  207. Point3f col;
  208. !ans ? col = { 0, 0, 1 } : col = { 1, 1, 0 };
  209. return col;
  210. }
  211.  
  212. bool ans = isRightSide(point, circuit[ind], circuit[(ind + 1) % circuit.size()]);
  213. Point3f color;
  214. ans ? color = { 0, 1, 0 } : color = {1, 0, 0};
  215. return color;
  216. }
  217.  
  218. #define SCREEN_WIDTH 800
  219. #define SCREEN_HEIGHT 600
  220.  
  221. double windowWidth = SCREEN_WIDTH;
  222. double windowHeight = SCREEN_HEIGHT;
  223.  
  224.  
  225. bool pressed = false;
  226. bool handled = false;
  227. double curPressX, curPressY;
  228. double rotX, rotY;
  229. bool roll = false;
  230.  
  231. GLdouble A, B, C, D;
  232. Object *obj;
  233.  
  234.  
  235. static void cursor_callback(GLFWwindow* window, double x, double y)
  236. {
  237. if (pressed && !handled){
  238. handled = true;
  239. curPressX = x;
  240. curPressY = y;
  241. rotX = obj->getRotation().x;
  242. rotY = obj->getRotation().y;
  243. }
  244.  
  245. if (pressed){
  246. double dy = (x - curPressX) / 5;
  247. double dx = (y - curPressY) / 5;
  248.  
  249. obj->setRotation(rotX + dx, rotY + dy, obj->getRotation().z);
  250. }
  251.  
  252. }
  253.  
  254. static void mouse_callback(GLFWwindow* window, int button, int action, int mods)
  255. {
  256. if (button == GLFW_MOUSE_BUTTON_RIGHT)
  257. {
  258. if (action == GLFW_PRESS) obj->setSkeleton(!obj->getSkeleton());
  259. }
  260.  
  261. if (button == GLFW_MOUSE_BUTTON_LEFT)
  262. {
  263. if (action == GLFW_PRESS){
  264. pressed = true;
  265. handled = false;
  266. }
  267. if (action == GLFW_RELEASE){
  268. pressed = false;
  269. }
  270. }
  271. }
  272.  
  273. static void resize_callback(GLFWwindow* window, int width, int height)
  274. {
  275. windowWidth = width;
  276. windowHeight = height;
  277.  
  278. glViewport(0, 0, width, height);
  279. glMatrixMode(GL_PROJECTION);
  280. glLoadIdentity();
  281. glOrtho(0.0, (GLdouble)width, 0.0, (GLdouble)height, -1, 1);
  282.  
  283. glMatrixMode(GL_MODELVIEW);
  284. glLoadIdentity();
  285.  
  286. A = width / 4.0;
  287. B = 0.0;
  288. C = D = height / 2.0;
  289.  
  290. printf("Reshape occured\n");
  291. }
  292.  
  293. static void keyboard_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
  294. {
  295. if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
  296. glfwSetWindowShouldClose(window, GL_TRUE);
  297.  
  298. if (key == GLFW_KEY_D && action == GLFW_REPEAT) obj->move(0.1, 0, 0);
  299. if (key == GLFW_KEY_A && action == GLFW_REPEAT) obj->move(-0.1, 0, 0);
  300.  
  301. if (key == GLFW_KEY_Q && action == GLFW_REPEAT) obj->move(0, 0.1, 0);
  302. if (key == GLFW_KEY_E && action == GLFW_REPEAT) obj->move(0, -0.1, 0);
  303.  
  304. if (key == GLFW_KEY_S && action == GLFW_REPEAT) obj->move(0, 0, 0.1);
  305. if (key == GLFW_KEY_W && action == GLFW_REPEAT) obj->move(0, 0, -0.1);
  306.  
  307. if (key == GLFW_KEY_X && action == GLFW_PRESS) obj->scale(1.1);
  308. if (key == GLFW_KEY_Z && action == GLFW_PRESS) obj->scale(1 / 1.1);
  309.  
  310. if (key == GLFW_KEY_R && action == GLFW_PRESS) roll = !roll;
  311.  
  312. for (int i = 0; i <= 6; i++) if (key == GLFW_KEY_0 + i && action == GLFW_PRESS) obj->setProjectionType(i);
  313.  
  314. }
  315.  
  316. static void error_callback(int error, const char* description)
  317. {
  318. fputs(description, stderr);
  319. }
  320.  
  321. Color3f PointSphereColor(Point3f p, std::vector<Point3f> circuit){
  322. Color3f c;
  323. //(isInCurcuit(p, circuit)) ? c = { 0, 1, 0 } : c = { 1, 0, 0 };
  324. Point3f pt = isInCurcuit(p, circuit);
  325. c = {pt.x, pt.y, pt.z};
  326. return c;
  327. }
  328.  
  329. Object *CreateSphere(std::vector<Point3f> circuit, double step){
  330. Object *obj = new Object();
  331.  
  332. std::vector<Point3f> dots, base;
  333. for (double psi = -90; psi <= 90; psi += step) {
  334. Point3f p = SphericalToXYZ(0, psi, 1);
  335. dots.push_back(p);
  336. base.push_back(p);
  337. }
  338.  
  339. for (double phi = step; phi <360; phi += step){
  340. double psi = -90;
  341. for (int j = 0; j < dots.size() - 1; j++){
  342. //double psi = ((double)j / (double)dots.size()) * 180 - 90;
  343. Point3f d1 = SphericalToXYZ(phi, psi, 1);
  344. Point3f d2 = SphericalToXYZ(phi, psi + step, 1);
  345.  
  346. Polygon pol;
  347. pol.pol.clear();
  348. pol.pol.push_back({ PointSphereColor(d1, circuit), d1 });
  349. if (PointSphereColor(d1, circuit).g && psi > 0 && phi == 45) printf("%f %f\n", phi, psi);
  350. pol.pol.push_back({ PointSphereColor(d2, circuit), d2 });
  351. pol.pol.push_back({ PointSphereColor(dots[j + 1], circuit), dots[j + 1] });
  352. pol.pol.push_back({ PointSphereColor(dots[j], circuit), dots[j] });
  353. obj->addPolygon(pol);
  354. dots[j] = d1;
  355. psi += step;
  356. }
  357. }
  358. for (int j = 0; j < dots.size() - 1; j++){
  359. Polygon pol;
  360. pol.pol.clear();
  361. pol.pol.push_back({ PointSphereColor(base[j], circuit), base[j] });
  362. pol.pol.push_back({ PointSphereColor(base[j + 1], circuit), base[j + 1] });
  363. pol.pol.push_back({ PointSphereColor(dots[j + 1], circuit), dots[j + 1] });
  364. pol.pol.push_back({ PointSphereColor(dots[j], circuit), dots[j] });
  365.  
  366. obj->addPolygon(pol);
  367. }
  368.  
  369. return obj;
  370. }
  371.  
  372. void ClearStage(void)
  373. {
  374. glClearColor(0, 0, 0, 1.0);
  375. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  376. glEnable(GL_DEPTH_TEST);
  377. }
  378.  
  379. int main(int argc, _TCHAR* argv[])
  380. {
  381. if (!glfwInit())
  382. {
  383. printf("glfwInit failed\n");
  384. return -1;
  385. }
  386.  
  387.  
  388. glfwSetErrorCallback(error_callback);
  389.  
  390. GLFWwindow* window;
  391. window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Test app", NULL, NULL);
  392. if (window == NULL)
  393. {
  394. printf("glfwOpenWindow failed.\n");
  395. glfwTerminate();
  396. return -2;
  397. }
  398.  
  399. int attrib;
  400. attrib = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
  401. attrib = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
  402. attrib = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE);
  403.  
  404. glfwMakeContextCurrent(window);
  405.  
  406. glfwSetKeyCallback(window, keyboard_callback);
  407. glfwSetFramebufferSizeCallback(window, resize_callback);
  408. glfwSetMouseButtonCallback(window, mouse_callback);
  409. glfwSetCursorPosCallback(window, cursor_callback);
  410.  
  411. resize_callback(window, SCREEN_WIDTH, SCREEN_HEIGHT);
  412.  
  413. std::ifstream fin("test.txt");
  414.  
  415. int n;
  416. fin >> n;
  417. std::vector<Point3f> points(n);
  418.  
  419. std::cout << "Angles:\n";
  420. float phi, psi;
  421. for (int i = 0; i < n; i++){
  422. //Считывание направляющих углов
  423. fin >> phi >> psi;
  424. //Сохранение в вектор преобразованных координат x y z
  425. points[i] = SphericalToXYZ(phi, psi, 1);
  426. spher.push_back({ phi, psi, 1 });
  427. }
  428.  
  429.  
  430. //obj = CreateConus(40, 1, 2, 1, 0.5, 1);
  431. //printf("!%d!\n", IsIntersect({ 1, 0, 0 }, { 0, 1, 0 }, { 1 / (float)sqrt(2), (float)0, 1 / (float)sqrt(2) }, { 1 / (float)sqrt(2), 0, -1 / (float)sqrt(2) }));
  432.  
  433. printf("%d", isInCurcuit(SphericalToXYZ(45, -19, 0.1), points));
  434.  
  435. obj = CreateSphere(points, 1);
  436. obj->setSkeleton(true);
  437. obj->setCoords(0, 0, -6);
  438. while (!glfwWindowShouldClose(window))
  439. {
  440. ClearStage();
  441. obj->draw(45.0, double(windowWidth) / windowHeight, 0.1, 100.0, points);
  442. glfwSwapBuffers(window);
  443.  
  444. //glfwPollEvents();
  445. glfwWaitEvents();
  446. }
  447. glfwDestroyWindow(window);
  448.  
  449. // clean up and exit
  450. glfwTerminate();
  451.  
  452. delete obj;
  453. return 0;
  454. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement