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

Вход на сайт

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

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

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

Рекурсия присутствует?
И где эти прикрепленные файлы?
Я код на C++ набрал сам. Строил кривую Безье, но "прилипал" к нулю. То есть я задаю точки далеко от нуля, а он строил из нуля, а потом только обходил предложенные точки. Потом я нашёл Ваш сайт и эту статью. Оказалось, что я забыл возвести t в...
просто я не так понял, здесь мы вращаем точки куба что вращает сам куб. Мне нужно вращать просто 3д объект , данный способ не подходит
Задавайте объект в мировых координатах. Вращайте его относительно мировой системы координат. А при отрисовке преобразуйте в экранные координаты. Посмотрите пример преобразования в экранные координаты.

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

Рейтинг@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;