Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

dobryj den, popytalas otkryt prikreplionnyj fail ctoby posmotret kak rabotaet, no mne ego ne pokazyvaet vydajet osibku. Pochemu?
Очень интересно! ии сайт крутой жалко что умирает(
У Вас число превысит максимальное число int. Можно использовать в Вашем случае uint, но лучше все переписать на double.
Добавление к программе строки glutReshapeFunc(changeSize); приводит к тому, что треугольник перестаёт совсем отрисовываться.
Выдаёт ошибку glut32.dll не найден! При том, что он лежит в System32! Всё решил) Нужно отправить не в System32, а в System.

Счетчики и рейтинг

Рейтинг@Mail.ru Яндекс.Метрика

Кватернионы были придуманы Роуэном Уильямом Гамильтоном как альтернатива матричным вращениям. Вращение при помощи кватернионов сводится к умножению чисел, что очень просто в программной реализации.

Алгоритм:
Входные данные:
1) угол θ на который производится вращение.
2) координаты x, y, z вращаемой точки.
3) координаты i, j, k направляющего единичного вектора, вокруг которого происходит вращение.
На выходе алгоритм выдает кватернион, содержащий координаты точки, обращенной вокруг заданного вектора ПО часовой стрелке его направления.

Процедура:
1) присвоить q <- (cos(θ/2), i*sin(θ/2), j*sin(θ/2), k*sin(θ/2)), где i,j,k - координаты единичного вектора, вокруг которого вращаем координату.
2) присвоить p <- (0, x, y, z), где x,y,z - координаты вращаемой точки.
3) присвоить p <- q*p
4) присвоить p <- p*q^-1
Кватернион p теперь имеет координаты (0, x', y', z'), где x',y',z' - новые координаты.

Хочу напомнить что умножение кватернионов не коммутативно, т.е. a*b != b*a

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

package net.ilyi;
 
public class Quaternion {
    public double r, i, j, k;
 
    public Quaternion(double r, double i, double j, double k) {
        this.r = r;
        this.i = i;
        this.j = j;
        this.k = k;
    }
 
    public double mag() {
        return Math.sqrt(r*r + i*i + j*j + k*k);
    }
 
    public Quaternion inverse() {
        double mag = this.mag();
        return new Quaternion(r/mag, -i/mag, -j/mag, -k/mag);
    }
 
    public Quaternion unit() {
        double mag = this.mag();
        return new Quaternion(r, i/mag, j/mag, k/mag);
    }
 
    public Quaternion mul(Quaternion q) {
        double r = this.r*q.r - this.i*q.i - this.j*q.j - this.k*q.k;
        double i = this.r*q.i + this.i*q.r + this.j*q.k - this.k*q.j;
        double j = this.r*q.j - this.i*q.k + this.j*q.r + this.k*q.i;
        double k = this.r*q.k + this.i*q.j - this.j*q.i + this.k*q.r;
        return new Quaternion(r, i, j, k);
    }
}

А вот код, который реализует картинку статьи, без использования матричных вращений:

double phi = Math.PI/180.0*angle;
double i = 0.0;
double j = 1.0;
double k = 0.0;
double cosphi = Math.cos(phi/2.0);
double sinphi = Math.sin(phi/2.0);
Quaternion q = new Quaternion(cosphi, i*sinphi, j*sinphi, k*sinphi).unit();
Quaternion p;
 
// triangle
glTranslatef(0.0f, 0.0f, -2.0f);
glBegin(GL_TRIANGLES);
 
glColor3f(1.0f, 0.0f, 0.0f);
p = new Quaternion(0.0, -0.5, -0.5, 0.0);
p = q.mul(p.mul(q.inverse()));
glVertex3f((float)p.i, (float)p.j, (float)p.k);
 
glColor3f(0.0f, 1.0f, 0.0f);
p = new Quaternion(0.0, 0.5, -0.5, 0.0);
p = q.mul(p.mul(q.inverse()));
glVertex3f((float)p.i, (float)p.j, (float)p.k);
 
glColor3f(0.0f, 0.0f, 1.0f);
p = new Quaternion(0.0, 0.5, 0.5, 0.0);
p = q.mul(p.mul(q.inverse()));
glVertex3f((float)p.i, (float)p.j, (float)p.k);
 
glEnd();
 
angle += 0.1f * delta;