Author Topic: C++ 3D Rotation Help Needed.  (Read 570 times)

How does one rotate a point in 3D space without gimbal lock?

All I have encountered is to use Quaternions so here is what I have tried.

Code: [Select]
#include <iostream>
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define PI 3.14159265

double getTime() {
return glfwGetTime();
}
float lastTime = glfwGetTime();
float getDelta() {
float time = getTime();
float delta = (time - lastTime);
lastTime = getTime();
return delta;
}

struct vector3f{
float x,y,z;
};
struct quaternion{
float x,y,z,w;
};
float getqlength(quaternion q1) {
return sqrt(q1.x*q1.x+q1.y*q1.y+q1.z*q1.z+q1.w*q1.w);
}
quaternion normalizeq(quaternion q1) {
quaternion nq;

float q1length = getqlength(q1);

nq.x = q1.x / q1length;
nq.y = q1.y / q1length;
nq.z = q1.z / q1length;
nq.w = q1.w / q1length;

return nq;
}
quaternion conjugateq(quaternion q1) {
quaternion nq;
nq.x = -q1.x;
nq.y = -q1.y;
nq.z = -q1.z;
nq.w = q1.w;
return nq;
}
quaternion mulq(quaternion q1, quaternion q2) {
quaternion nq;
nq.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
nq.w = q1.x * q2.w + q1.w * q2.x + q1.y * q2.z - q1.z * q2.y;
nq.w = q1.y * q2.w + q1.w * q2.y + q1.z * q2.x - q1.x * q2.z;
nq.w = q1.z * q2.w + q1.w * q2.z + q1.x * q2.y - q1.y * q2.x;
return nq;
}
quaternion mulqv(quaternion q1, vector3f v) {
quaternion nq;
nq.w = -q1.x * v.x - q1.y * v.y - q1.z * v.z;
nq.w = q1.w * v.x + q1.y * v.z - q1.z * v.y;
nq.w = q1.w * v.y + q1.z * v.x - q1.x * v.z;
nq.w = q1.w * v.z + q1.x * v.y - q1.y * v.x;
return nq;
}
vector3f rotatev(vector3f v, vector3f axis, float angle) {
vector3f nv;

float sha = sin( (angle / 2)*(PI / 180));
float cha = cos( (angle / 2)*(PI / 180));


quaternion rotation;
rotation.x = axis.x * sha;
rotation.y = axis.y * sha;
rotation.z = axis.z * sha;
rotation.w = cha;
quaternion w = mulq(mulqv(rotation,v),conjugateq(rotation));

std::cout << w.x << "," << w.y << "," << w.z << " " << angle << " " << sha << " " << cha << "\n";

nv.x = w.x;
nv.y = w.y;
nv.z = w.z;
return nv;
}

vector3f p1;
vector3f p2;
vector3f pa;
float pang;

void init() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
p1.x = 0.0;
p1.y = 0.0;
p1.z = 0.0;
p2.x = 0.0;
p2.y = 0.2;
p2.z = 0.0;
pa.x = 0.0;
pa.y = 0.0;
pa.z = 1.0;
pang = 0;
}

void update(float delta) {
pang += 90 * delta;
if(pang > 360) {
pang -= 360;
}
p2 = rotatev(p2,pa,pang);
}

void render() {
glBegin(GL_POINTS);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(p1.x, p1.y, p1.z);
glVertex3f(p2.x, p2.y, p2.z);
glEnd();
}

static void error_callback(int error, const char* description) {
    fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}
int main(void) {
    GLFWwindow* window;
    glfwSetErrorCallback(error_callback);
    if (!glfwInit())
        exit(EXIT_FAILURE);
    window = glfwCreateWindow(640, 480, "", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }
    glfwMakeContextCurrent(window);
    glfwSetKeyCallback(window, key_callback);
init();
    while (!glfwWindowShouldClose(window))
    {
        float ratio;
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        ratio = width / (float) height;
        glViewport(0, 0, width, height);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();


update(getDelta());
render();

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();
    exit(EXIT_SUCCESS);
}
So to my understanding that should give me a window with two points, one rotating around the other.

But, all i'm getting is one dot and the location of another point at 4.61497e+033,1.26933e-038,3.76462e-039 apparently...

What have I done wrong and/or how do I manage 3D rotation?