Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // glfw_30.cpp : Defines the entry point for the console application.
- // http://www.glfw.org/docs/latest/quick.html
- #include "stdafx.h"
- #include "Object\Object.h"
- #include <iostream>
- #include <fstream>
- #include <cmath>
- #include <time.h>
- #include <algorithm>
- std::vector<Point3f> spher;
- #define PI 3.14159265359
- #define EPS 0.001
- Point3f SphericalToXYZ(float phi, float psi, float radius){
- phi *= PI / 180;
- psi *= PI / 180;
- return{ cos(phi)*cos(psi), sin(phi)*cos(psi), sin(psi) };
- }
- Point3f XYZToSpherical(Point3f coord){
- if (coord.x == 0 && coord.y == 0){
- return{ 0, 90, 1 };
- }
- return{ (float)(acos(coord.x / sqrt(coord.x*coord.x + coord.y*coord.y))*(180 / PI)), (float)(asin(coord.z)*(180 / PI)), (float)1 };
- }
- //Поиск расстояния от точки point до отрезка с координатами c1 c2
- float Distance_sqr2(Point3f point, Point3f c1, Point3f c2){
- // Вектор из первого конца отрезка в точку point
- Point3f p1 = point - c1;
- Point3f p2 = point - c2;
- // Вектор из первого конца отрезка во второй
- Point3f v = c2 - c1;
- //Вернуть минимальное из расстоний до концов отрезков, если проекция точки не падает на отрезок
- if (p1 * v <= 0 || p2 * (v * -1) <= 0){
- float dist = std::min(p1.norm(), p2.norm());
- return dist*dist;
- }
- // Длинна вектора p
- float plong = p1.norm();
- //Нормированный вектор v
- Point3f ve = v / v.norm();
- // Длинна проекции p на v
- float proect = ve * p1;
- // Расстояние считается по теореме Пифагора
- return plong*plong - proect*proect;
- }
- // Проверяет, лежит ли точка на сфере слева от напрвленной дуги
- // point задаёт точку
- // с1, с2 - коорднаты направленной дуги (начало/конец)
- bool isRightSide(Point3f point, Point3f c1, Point3f c2){
- // Вектор нормали(направлен влево по отн. к дуге) к плоскости, заданной радиус-векторами c1, c2
- Point3f n = c1 ^ c2;
- // Точка лежит справа по отношению к дуге если скалярное произведение n и point полоительное
- return point * n <= 0;
- }
- double angleBetweenVectors(Point3f a, Point3f b){
- double res = (a * b) / (a.norm() * b.norm());
- if (res > 1) return acos(1);
- if (res < -1) return (-1);
- return acos(res);
- }
- bool IsIntersect(Point3f d1, Point3f d2, Point3f p, Point3f m){
- Point3f V1 = d1 ^ d2;
- Point3f V2 = p ^ m;
- Point3f U1 = V1 / V1.norm();
- Point3f U2 = V2 / V2.norm();
- Point3f D = U1 ^ U2;
- Point3f S = D / D.norm();
- Point3f S1 = S;
- Point3f S2 = S * (-1);
- double a_d1_d2 = angleBetweenVectors(d1, d2);
- double a_d1_s1 = angleBetweenVectors(d1, S1);
- double a_s1_d2 = angleBetweenVectors(S1, d2);
- double a_p_m = angleBetweenVectors(p, m);
- double a_p_i = angleBetweenVectors(p, S1);
- double a_i_m = angleBetweenVectors(S1, m);
- if (abs(a_d1_d2 - (a_d1_s1 + a_s1_d2)) <= EPS && (abs(a_p_m - (a_p_i + a_i_m))) <= EPS){
- return 1;
- }
- a_d1_d2 = angleBetweenVectors(d1, d2);
- a_d1_s1 = angleBetweenVectors(d1, S2);
- a_s1_d2 = angleBetweenVectors(S2, d2);
- a_p_m = angleBetweenVectors(p, m);
- a_p_i = angleBetweenVectors(p, S2);
- a_i_m = angleBetweenVectors(S2, m);
- if (abs(a_d1_d2 - (a_d1_s1 + a_s1_d2)) <= EPS && (abs(a_p_m - (a_p_i + a_i_m))) <= EPS){
- return 1;
- }
- else {
- return 0;
- }
- }
- bool IsIntersect2(Point3f d1, Point3f d2, Point3f p, Point3f m){
- Point3f N = p^m;
- Point3f S = d2 - d1;
- GLdouble t = -(N * d1) / (N * S);
- Point3f I = (S * t) + d1;
- I = I / I.norm();
- if (t > 1 || t < 0) return 0;
- double a_d1_d2 = angleBetweenVectors(d1, d2);
- double a_d1_s1 = angleBetweenVectors(d1, I);
- double a_s1_d2 = angleBetweenVectors(I, d2);
- double a_p_m = angleBetweenVectors(p, m);
- double a_p_i = angleBetweenVectors(p, I);
- double a_i_m = angleBetweenVectors(I, m);
- if (abs(a_d1_d2 - (a_d1_s1 + a_s1_d2)) <= EPS && (abs(a_p_m - (a_p_i + a_i_m))) <= EPS){
- return 1;
- }
- else {
- return 0;
- }
- }
- __inline Point3f middlePoint(Point3f c1, Point3f c2){
- Point3f c = (c1 + c2) / 2;
- return c / c.norm();
- }
- __inline Point3f factorPoint(Point3f c1, Point3f c2, float factor){
- Point3f c = (c2 - c1)*factor + c1;
- return c / c.norm();
- }
- Point3f isInCurcuit(Point3f point, std::vector<Point3f> circuit){
- float minDist = 100000000, dist;
- int ind = 0, eqNum = 0;
- for (int i = 0; i < circuit.size(); i++){
- dist = Distance_sqr2(point, circuit[i], circuit[(i + 1) % circuit.size()]);
- if (dist == minDist && i == (ind + 1) % circuit.size()) eqNum = 1;
- if (dist == minDist && ind == (i + 1) % circuit.size()){
- eqNum = 1;
- ind = i;
- }
- if (dist < minDist){
- minDist = dist;
- ind = i;
- eqNum = 0;
- }
- }
- if (eqNum){
- //Point3f c1 = spher[ind];
- //Point3f c2 = spher[(ind + 1) % circuit.size()];
- //Point3f c3 = spher[(ind + 2) % circuit.size()];
- Point3f d1 = circuit[ind];
- Point3f d2 = circuit[(ind + 1) % circuit.size()];
- Point3f d3 = circuit[(ind + 2) % circuit.size()];
- long double angle = angleBetweenVectors(d1 - d2, d3 - d2);
- if (angle > PI*0.99 && 1 == 0){
- bool ans = isRightSide(point, d1, d2);
- Point3f color;
- ans ? color = { 0, 1, 0 } : color = { 1, 0, 0 };
- return color;
- }
- //factor *= factor * factor * factor;
- Point3f p1 = factorPoint(d2, d1, 0.00001);
- Point3f p2 = factorPoint(d2, d3, 0.00001);
- Point3f dXYZ = middlePoint(p1, p2);
- Point3f d = XYZToSpherical(dXYZ);
- bool d_in_C = isRightSide(dXYZ, d1, d2);
- bool is1 = IsIntersect(d1, d2, point, dXYZ);
- bool is2 = IsIntersect(d2, d3, point, dXYZ);
- Point3f dogXYZ = middlePoint(p1, dXYZ);
- bool is3 = IsIntersect(d1, d2, point, dogXYZ);
- bool is4 = IsIntersect(d2, d3, point, dogXYZ);
- bool ans = ((is1 || is2) && (is3 || is4)) ^ d_in_C;
- // if (point.z < 0 && !ans) printf("%d %d\n", )
- //return { 0, 0, 1 }; //ans;
- Point3f col;
- !ans ? col = { 0, 0, 1 } : col = { 1, 1, 0 };
- return col;
- }
- bool ans = isRightSide(point, circuit[ind], circuit[(ind + 1) % circuit.size()]);
- Point3f color;
- ans ? color = { 0, 1, 0 } : color = {1, 0, 0};
- return color;
- }
- #define SCREEN_WIDTH 800
- #define SCREEN_HEIGHT 600
- double windowWidth = SCREEN_WIDTH;
- double windowHeight = SCREEN_HEIGHT;
- bool pressed = false;
- bool handled = false;
- double curPressX, curPressY;
- double rotX, rotY;
- bool roll = false;
- GLdouble A, B, C, D;
- Object *obj;
- static void cursor_callback(GLFWwindow* window, double x, double y)
- {
- if (pressed && !handled){
- handled = true;
- curPressX = x;
- curPressY = y;
- rotX = obj->getRotation().x;
- rotY = obj->getRotation().y;
- }
- if (pressed){
- double dy = (x - curPressX) / 5;
- double dx = (y - curPressY) / 5;
- obj->setRotation(rotX + dx, rotY + dy, obj->getRotation().z);
- }
- }
- static void mouse_callback(GLFWwindow* window, int button, int action, int mods)
- {
- if (button == GLFW_MOUSE_BUTTON_RIGHT)
- {
- if (action == GLFW_PRESS) obj->setSkeleton(!obj->getSkeleton());
- }
- if (button == GLFW_MOUSE_BUTTON_LEFT)
- {
- if (action == GLFW_PRESS){
- pressed = true;
- handled = false;
- }
- if (action == GLFW_RELEASE){
- pressed = false;
- }
- }
- }
- static void resize_callback(GLFWwindow* window, int width, int height)
- {
- windowWidth = width;
- windowHeight = height;
- glViewport(0, 0, width, height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0.0, (GLdouble)width, 0.0, (GLdouble)height, -1, 1);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- A = width / 4.0;
- B = 0.0;
- C = D = height / 2.0;
- printf("Reshape occured\n");
- }
- static void keyboard_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
- {
- if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
- glfwSetWindowShouldClose(window, GL_TRUE);
- if (key == GLFW_KEY_D && action == GLFW_REPEAT) obj->move(0.1, 0, 0);
- if (key == GLFW_KEY_A && action == GLFW_REPEAT) obj->move(-0.1, 0, 0);
- if (key == GLFW_KEY_Q && action == GLFW_REPEAT) obj->move(0, 0.1, 0);
- if (key == GLFW_KEY_E && action == GLFW_REPEAT) obj->move(0, -0.1, 0);
- if (key == GLFW_KEY_S && action == GLFW_REPEAT) obj->move(0, 0, 0.1);
- if (key == GLFW_KEY_W && action == GLFW_REPEAT) obj->move(0, 0, -0.1);
- if (key == GLFW_KEY_X && action == GLFW_PRESS) obj->scale(1.1);
- if (key == GLFW_KEY_Z && action == GLFW_PRESS) obj->scale(1 / 1.1);
- if (key == GLFW_KEY_R && action == GLFW_PRESS) roll = !roll;
- for (int i = 0; i <= 6; i++) if (key == GLFW_KEY_0 + i && action == GLFW_PRESS) obj->setProjectionType(i);
- }
- static void error_callback(int error, const char* description)
- {
- fputs(description, stderr);
- }
- Color3f PointSphereColor(Point3f p, std::vector<Point3f> circuit){
- Color3f c;
- //(isInCurcuit(p, circuit)) ? c = { 0, 1, 0 } : c = { 1, 0, 0 };
- Point3f pt = isInCurcuit(p, circuit);
- c = {pt.x, pt.y, pt.z};
- return c;
- }
- Object *CreateSphere(std::vector<Point3f> circuit, double step){
- Object *obj = new Object();
- std::vector<Point3f> dots, base;
- for (double psi = -90; psi <= 90; psi += step) {
- Point3f p = SphericalToXYZ(0, psi, 1);
- dots.push_back(p);
- base.push_back(p);
- }
- for (double phi = step; phi <360; phi += step){
- double psi = -90;
- for (int j = 0; j < dots.size() - 1; j++){
- //double psi = ((double)j / (double)dots.size()) * 180 - 90;
- Point3f d1 = SphericalToXYZ(phi, psi, 1);
- Point3f d2 = SphericalToXYZ(phi, psi + step, 1);
- Polygon pol;
- pol.pol.clear();
- pol.pol.push_back({ PointSphereColor(d1, circuit), d1 });
- if (PointSphereColor(d1, circuit).g && psi > 0 && phi == 45) printf("%f %f\n", phi, psi);
- pol.pol.push_back({ PointSphereColor(d2, circuit), d2 });
- pol.pol.push_back({ PointSphereColor(dots[j + 1], circuit), dots[j + 1] });
- pol.pol.push_back({ PointSphereColor(dots[j], circuit), dots[j] });
- obj->addPolygon(pol);
- dots[j] = d1;
- psi += step;
- }
- }
- for (int j = 0; j < dots.size() - 1; j++){
- Polygon pol;
- pol.pol.clear();
- pol.pol.push_back({ PointSphereColor(base[j], circuit), base[j] });
- pol.pol.push_back({ PointSphereColor(base[j + 1], circuit), base[j + 1] });
- pol.pol.push_back({ PointSphereColor(dots[j + 1], circuit), dots[j + 1] });
- pol.pol.push_back({ PointSphereColor(dots[j], circuit), dots[j] });
- obj->addPolygon(pol);
- }
- return obj;
- }
- void ClearStage(void)
- {
- glClearColor(0, 0, 0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glEnable(GL_DEPTH_TEST);
- }
- int main(int argc, _TCHAR* argv[])
- {
- if (!glfwInit())
- {
- printf("glfwInit failed\n");
- return -1;
- }
- glfwSetErrorCallback(error_callback);
- GLFWwindow* window;
- window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Test app", NULL, NULL);
- if (window == NULL)
- {
- printf("glfwOpenWindow failed.\n");
- glfwTerminate();
- return -2;
- }
- int attrib;
- attrib = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
- attrib = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
- attrib = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE);
- glfwMakeContextCurrent(window);
- glfwSetKeyCallback(window, keyboard_callback);
- glfwSetFramebufferSizeCallback(window, resize_callback);
- glfwSetMouseButtonCallback(window, mouse_callback);
- glfwSetCursorPosCallback(window, cursor_callback);
- resize_callback(window, SCREEN_WIDTH, SCREEN_HEIGHT);
- std::ifstream fin("test.txt");
- int n;
- fin >> n;
- std::vector<Point3f> points(n);
- std::cout << "Angles:\n";
- float phi, psi;
- for (int i = 0; i < n; i++){
- //Считывание направляющих углов
- fin >> phi >> psi;
- //Сохранение в вектор преобразованных координат x y z
- points[i] = SphericalToXYZ(phi, psi, 1);
- spher.push_back({ phi, psi, 1 });
- }
- //obj = CreateConus(40, 1, 2, 1, 0.5, 1);
- //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) }));
- printf("%d", isInCurcuit(SphericalToXYZ(45, -19, 0.1), points));
- obj = CreateSphere(points, 1);
- obj->setSkeleton(true);
- obj->setCoords(0, 0, -6);
- while (!glfwWindowShouldClose(window))
- {
- ClearStage();
- obj->draw(45.0, double(windowWidth) / windowHeight, 0.1, 100.0, points);
- glfwSwapBuffers(window);
- //glfwPollEvents();
- glfwWaitEvents();
- }
- glfwDestroyWindow(window);
- // clean up and exit
- glfwTerminate();
- delete obj;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement