Вращать gluCylinder () вокруг определенной оси? - PullRequest
1 голос
/ 26 сентября 2019

Я пишу функцию для рисования цилиндра с центром каждой базы в конкретной точке, используя команды конвейера OpenGL и функцию gluCylinder().

В качестве первой попытки я простопопытался нарисовать цилиндр, и в результате получился цилиндр с нижним основанием с центром в (0, 0, 0), а другое основание с центром в (0, 0, height), где height было передано в качестве аргумента функции.

Затем я попытался отцентрировать первую базу по первой выбранной точке, и все получилось как шарм.

Теперь я изо всех сил пытаюсь найти правильную позицию для второй точки:вычислил расстояние между двумя точками и сохранил расстояние вдоль каждой оси, чтобы получить разность векторов, поэтому все, что мне нужно сделать, это выполнить вращение так, чтобы в любом кадре ось цилиндра лежала на разности векторов двухточки.

Тем не менее, мне нужно найти координаты оси цилиндра и повернуть ее, и я не знаю, как это сделать.

Вот мойкод, надеясь, что это будет полезно:

void drawCylinder(float pHeight, std::vector<float> center1, std::vector<float> center2) {

    const GLfloat* projection = glm::value_ptr(glm::perspective(glm::radians(fov), (float)WIN_WIDTH / (float)WIN_HEIGHT, 0.1f, 100.0f));
    const GLfloat* view = glm::value_ptr(camera.GetViewMatrix());

    glm::vec3 diff = glm::vec3(center2[0] - center1[0], center2[1] - center1[1], center2[2] - center1[2]);
    float distance = sqrt(pow(center2[0] - center1[0], 2) + pow(center2[1] - center1[1], 2) + pow(center2[2] - center1[2], 2));

    glUseProgram(0);

    glPushMatrix();
    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(projection);

    glPushMatrix();
    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixf(view);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glColor3f(1.0f, 1.0f, 0.0f);
    glTranslated(center1[0] - 12.25f, (center1[1]) + 0.0f, (center1[2]) - 12.25f);
    // Here I should perform the rotation in order to draw the cylinder in the right position
    gluCylinder(quadric, 0.1f, 0.1f, pHeight, 32, 32);
    glPopMatrix();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

}

Я думал об обоих углах Эйлера и методах кватернионов, но я не могу понять, как использовать любой из них.Возможно, учитывая, что я использую метод команд конвейера OpenGL, углы Эйлера были бы лучше.Тем не менее, если у вас есть лучший способ сделать все это, я буду рад узнать что-то новое.

Как я могу определить это вращение?

1 Ответ

1 голос
/ 26 сентября 2019

Я рекомендую использовать математическую библиотеку, например OpenGL Matmatics (GLM) .

Библиотека glm - это библиотека шаблонов.Для следующих операций вы просто должны включить следующие файлы:

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

Рассчитать вектор от center2 до center1.И определите опорный вектор, например (0, 0, 1):

glm::vec3 ref  = lm::vec3(0.0f, 0.0f, 1.0f);
glm::vec3 diff = glm::vec3(center2[0] - center1[0],
                           center2[1] - center1[1],
                           center2[2] - center1[2]);

Вы хотите определить матрицу вращения, которая вращается от ref до diff.Рассчитать угол поворота - произведение Dot из 2 Единичные векторы возвращает косинус угла между двумя векторами (единичный вектор имеет длину 1, а вектор можно повернуть кединичный вектор на glm::normalize).Ось вращения может быть вычислена как Перекрестное произведение .Установите матрицу вращения, которая вращается вокруг оси на угол:

float     angle  = acos(glm::dot(ref, glm::normalize(diff)));
glm::vec3 axis   = glm::cross(b, a);
glm::mat4 rotmat = glm::rotate(glm::mat4(1.0f), angle, axis);

Используйте glMultMatrixf, чтобы умножить текущую матрицу на матрицу вращения.например:

glTranslated(center1[0] - 12.25f, (center1[1]) + 0.0f, (center1[2]) - 12.25f);

// multiply current matrix by the rotation matrix
glMultMatrixf(glm::value_ptr(rotmat))

gluCylinder(quadric, 0.1f, 0.1f, pHeight, 32, 32);
...