На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! правила раздела Алгоритмы
1. Помните, что название темы должно хоть как-то отражать ее содержимое (не создавайте темы с заголовком ПОМОГИТЕ, HELP и т.д.). Злоупотребление заглавными буквами в заголовках тем ЗАПРЕЩЕНО.
2. При создании темы постарайтесь, как можно более точно описать проблему, а не ограничиваться общими понятиями и определениями.
3. Приводимые фрагменты исходного кода старайтесь выделять тегами code.../code
4. Помните, чем подробнее Вы опишете свою проблему, тем быстрее получите вразумительный совет
5. Запрещено поднимать неактуальные темы (ПРИМЕР: запрещено отвечать на вопрос из серии "срочно надо", заданный в 2003 году)
6. И не забывайте о кнопочках TRANSLIT и РУССКАЯ КЛАВИАТУРА, если не можете писать в русской раскладке :)
Модераторы: Akina, shadeofgray
Страницы: (5) 1 [2] 3 4 ... Последняя » все  ( Перейти к последнему сообщению )  
> как заставить закрутиться кубик
    2 wormball
    что то я не заметил что у тебя меньше кода wink.gif


    полностью программа с сорцами (управляется стрелками, +, -, правой кнопкой мыши)
    Сообщение отредактировано: MeG -
      утебя 52 килобайта, уменя 14 килобайт :P
      тебя наверное ввели в заблуждение остальные файлы, которые там есь. собственно исходников екшына четыре: action.pas, kol_mov.pas, _13h.pas и mouse.pas .
      зы. уменя там оказывается есь архив в чистом виде
      http://enzyme.nm.ru/prog/action.rar
      ззы. только ето немного более ранняя версия
      Сообщение отредактировано: wormball -

      Прикреплённый файлПрикреплённый файлaction.rar (35.95 Кбайт, скачиваний: 193)
        Блин ну вы даёте...Перемножать матрицы долго, Вот фукция поворота любой точки на плоскости вокруг данной на угол 4 пи/180. Применив такую фукцию к каждой точке куба спроектированой на одну из трёх плоскостей(те про одну из трех координат забываем), он повернётся мать его... Только надо обратить внимание на /*float Abs(float)*/.......
        void CKubikDlg::TurnVertex(int cx,int cy, float &x,float &y,int q)
        {
        float u,a,b,c;
        a=cx-x;b=cy-y;c=sqrt(a*a+b*;
        u = acos(Abs(a) / c) + q*(4*3.14/180) * b / Abs( * a / Abs(a) ;
        x=cx+c*cos(u)* a / (Abs(a) * (-1));
        y=cy+c*sin(u)* b / (Abs( * (-1));
        }
        сорец может дам попозжЕ.
          прямо скажем, не лучшее решение во избежание смайликов - удалить их к чёртовой бабушке в исходнике. лучше бы выключил галку со смайлами или писал бы всё в [code]
          более того, ты ошибаешься, что перемножать матрицы долго. там всего 9 умножений, как и у тебя, а у тебя ещё и синусы с корнями, что куда дольше.
            vect2 - это типа координаты вершины, а чё такое vect1? matr3-типа матрица поворота, лады. тогда
            как она заполняется, если надо повернуть на Альфа градусов по XY, по часовой стрелке?
              QUOTE (Serg-Zerg @ 15.11.03, 16:25)
              vect2 - это типа координаты вершины, а чё такое vect1? matr3-типа матрица поворота, лады. тогда
              как она заполняется, если надо повернуть на Альфа градусов по XY, по часовой стрелке?

              Тебе же MeG сорс выложил, там все есть. Осталось только copy-paste wink.gif. Матрица оборота строится или по шпаргалке (vide MeG's source) или оборачивая базовые версоры (что ты и сделал неявно). Перемножать матрицы недолго, зато в одной 4х4 матрице хранится инфа про обороты и перемещение ВСЕХ вершин, тебе остается только
              QUOTE
              vect2 = vect1 * matr3;
              каждую вершину.
              з.ы. тут vect1 - исходные координаты, vect2 - конечные координаты (после оборота-перемещения).
                QUOTE (Serg-Zerg @ 16.11.03, 00:25)
                vect2 - это типа координаты вершины, а чё такое vect1? matr3-типа матрица поворота, лады. тогда
                как она заполняется, если надо повернуть на Альфа градусов по XY, по часовой стрелке?

                Тут произошло разделение понятий. vect2 и vect1 нужно понимать как список вершин гарфического примитива. В моих сорцах вектор --- это направленный отрезок из начала координат в данную точку, а список координат содержится в соответствующем классе примитива.
                Если тебе нужно вращать параллелепипед:
                CODE
                // задаешь параллелепипед двумя вершинами главной диагонали, все стороны параллельны осям координат.
                CVector Avector(1, 1, 1); // левый нижний передний угол параллелепипеда
                CVector Bvector(3, 5, 7); // правый верхний задний угол параллелепипеда
                // в конструкторе получаешь координаты всех вершин примитива
                CParallelepiped Primitive(Avector, Bvector);
                CMatrix Rmatrix; // матрица без инициализации
                Rmatrix = RotateX(0.5); // получаем матрицу поворота вокруг оси X на 0,5 радиана

                Дальше нужно поворачивать примитив и отображать его
                CODE

                ByTimer(...)
                {
                Primitive.View(DC);
                Primitive *= Rmatrix;
                }

                CParallelepiped содержит в себе массив своих вершин
                CVector m_Vertex[8];
                и ребер
                int m_Segments[12][12]; // номера начальной и конечной вершин (векторов вершин)
                Функция Matrix RotateX (double);
                CODE
                Matrix RotateX (double Angle)
                {
                Matrix res(1);
                double Cosine = cos(Angle);
                double Sine = sin(Angle);
                res.x[1][1] = Cosine;
                res.x[2][1] = -Sine;
                res.x[1][2] = Sine;
                res.x[2][2] = Cosine;
                return res;
                }
                это глобальная функция, она не является членом какого-либо класса. Создает матрицу поворота вокруг начала координат. Внутри нее создается объект класса Matrix. Возвращает объект класса Matrix.
                В строчке Rmatrix = RotateX(0.5); используется оператрор присваивания по умолчанию, то есть матрица возвращаемая из RotateX() копируется один в один в матрицу Rmatrix.
                Для чего так сделано? Чтобы иметь однообразную запись для любых афинных преобразований.
                Rmatrix = RotateX(.) * RotateY(.) * Scale(.) * Translate(.); --- повернуть, повернуть, отмасштабировать, переместить. Таким образом можно получить любые преобразования объекта в пространстве.
                  2 Serg-Zerg
                  Вокруг чего ты собрался вращать?
                  Вокруг начала координат, вокруг одного из ребер примитива, вокруг геометрического центра примитива, вокруг оси коодинат, вокруг некоторой прямой?
                    Афинные преобразования в пространстве в общем виде

                    Про координаты.
                    Чтобы иметь возможность сделать любые преобразования примитива в трехмерном пространстве, необходимо использовать однородные координаты!
                    то есть A(x, y, z, 1) --- четыре кооринаты, четвертая координата имеет геометрический смысл масштаба. Хранить четвертую координату не нужно, достаточно во всех алгоритмах преобразования приводить ее к единице.
                    Соответственно матрицы преобразования тоже размера 4х4


                    Матрицы в общем виде
                    • Матрицы вращения в пространстве
                      Вокруг оси X на угол A
                    CODE

                    Rx = | 1     0     0     0 |
                         | 0   cosA  sinA    0 |
                         | 0  -sinA  cosA    0 |
                         | 0     0     0     1 |

                    Вокруг оси Y на угол A
                    CODE

                    Ry = | cosA 0   -sinA  0  |
                         |  0    1    0    0  |
                         | sinA  0 cosA    0  |
                         |  0    0    0    1  |

                    Вокруг оси Z на угол A
                    CODE

                    Rz = |  cosA  sinA 0    0  |
                        | -sinA cosA  0    0  |
                         |   0    0    1    0  |
                         |   0    0    0    1  |


                  • Матрица масштабирования
                    A --- вдоль оси X, B --- вдоль оси Y, C --- вдоль оси Z. A > 0, B > 0, C > 0.
                  • CODE

                    |D| = | A  0  0  0 |
                          | 0  B  0  0 |
                          | 0  0  C  0 |
                          | 0  0  0  1 |


                  • Матрицы отражения (зеркального)
                    относительно плоскости XY
                  • CODE

                    |Mz| = | 1  0  0  0 |
                            | 0  1  0  0 |
                           | 0  0 -1  0 |
                           | 0  0  0  1 |


                    относительно плоскости YZ
                    CODE

                    |Mx| = | -1 0  0  0 |
                           | 0  1  0  0 |
                           | 0  0  1  0 |
                           | 0  0  0  1 |


                    относительно плоскости XZ
                    CODE

                    |My| = | 1  0  0  0 |
                           | 0 -1  0  0 |
                           | 0  0  1  0 |
                           | 0  0  0  1 |

                  • Матрица переноса
                    a, b, c --- вектор переноса
                  • CODE

                    |T| = | 1  0  0  0 |
                          | 0  1  0  0 |
                          | 0  0  1  0 |
                          | a  b  c  1 |
                    Сообщение отредактировано: MeG -
                      Проекции
                      Что это такое?
                      Есть трехмерное пространство, в этом пространстве резмещены трехмерные объекты. Нужно каким-то образом показать эти трехмерные объекты на плоском экране. Для этого и существуют проекции.Видов проекций огромное количество.
                      Преимущественно применяется параллельное и центральное проектирование (у каждого из них есть несколько подвидов)

                      Помещаем в наше пространство плоскость --- экранную плоскость, на нее мы будем проектировать наши трехмерные объекты, и изображение на этой плоскости будем выводить на экан монитора.
                      Дальше нужно задать направление проектирования. Для этого помещаем в пространство камеру. Камера имеет положение в пространстве и направление взгляда (вектор).
                      Для того чтоб на экранной плоскости чтото было видно, необходимо: направить камеру на наши трехмерные объекты, и разместить экранную плоскость между камерой и объектами. Обычно, экранная плоскость перпендикулярна направлению взгляда камеры, это позволяет упростить расчеты.
                      Удобно экранную плоскость разместить в начале координат нашего пространства, на одной из координатных проскостей, например XY. Камеру разместить на оси Z и направить в начало координат O(0, 0, 0). Камера будет описываться двумя векторами: положение Position(0, 0, -100) и направление Direction(0, 0, 1). Все трехмерные объекты размещаем по другую сторону экранной плоскости, для всех точек объектов координата Z будет больше нуля.

                      Проектируем.
                      На входе у нас массив трехмерных координат объектов в пространстве. На выходе массив двухмерных координат на экранной плоскости.
                      Паралельное проектирование (то которое тебе не нравится, нарушается перспектива), тут, по сути, камера не нужна
                      Матрица проектирования на плоскость параллельную координатной плоскости XY
                      | 1 0 0 0 |
                      | 0 1 0 0 |
                      | 0 0 0 0 |
                      | 0 0 k 1 |
                      k --- это смещение экранной плоскости воль оси Z
                      Как это применить? Берем все координаты трехмерных объектов и перемножаем на эту матрицу проектирования, получаем множество точек у которых координата z равна нулю (x, y, 0). Просто выводим эти точки на экран по X и Y, изображение готово.

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


                      Центральное (перспективное) проектирование
                      Матрица перспективного проектирования на плоскость XY, (z = 0) Камера находится в точке (0, 0, c)
                      | 1 0 0 0 |
                      | 0 1 0 0 |
                      | 0 0 0 -1/c|
                      | 0 0 0 1 |

                      Матрица перспективного проектирования на плоскость XY, для камеры в любой точке (a, b, c)пространства
                      | 1 0 0 -1/a |
                      | 0 1 0 -1/b |
                      | 0 0 0 -1/c |
                      | 0 0 k 1 |
                      k --- это смещение экранной плоскости воль оси Z

                      Применять матрицы перспективного проектирования так же как и матрицы параллельного проектирования.

                      Для изменения вида проекции остаточно просто сменить одну матрицу на другую.
                      Сообщение отредактировано: MeG -
                        QUOTE (MeG @ 16.11.03, 07:42)
                        2 Serg-Zerg
                        Вокруг чего ты собрался вращать?
                        Вокруг начала координат, вокруг одного из ребер примитива, вокруг геометрического центра примитива, вокруг оси коодинат, вокруг некоторой прямой?

                        Мечтал вокруг геометрического центра, но думаю вокруг оси коодинат будет более чем достаточно.
                          Чтобы повернуть объект вокруг своего геометрического центра нужно:
                          - найти координаты этого геометрического центра
                          - переместить объект в начало координат
                          - повернуть объект на требуемый угол
                          - переместить объект на пержнее место
                          CODE
                          CVector center(x1, y1, z1); // вектор из начала координат в геометрический центр.
                          double angleX = 0.1;     // угол поворота вокруг оси X
                          double angleZ = -0.3;     // угол поворота вокруг оси Z

                          CKub primitive; // вращаемый объект

                          CMatrix transform; // матрица преобразований

                          transform = Translate(-center) * RotateX(angleX) * RotateZ(angleZ) * Translate(center);

                          primitive *= transform; // вращаем объект вокруг своего центра
                          Сообщение отредактировано: MeG -
                            QUOTE
                            Матрица проектирования на плоскость параллельную координатной плоскости XY
                            | 1 0 0 0 |
                            | 0 1 0 0 |
                            | 0 0 0 0 |
                            | 0 0 k 1 |
                            k --- это смещение экранной плоскости воль оси Z

                            а ещё курсовую по графике писал!! матрица проектирования переводит трёхмерный вектор в двумерный, стало быть она размера 3*2 и выглядит так (для плоскости ху):
                            1 0 0
                            0 1 0

                            QUOTE
                            Центральное (перспективное) проектирование
                            Матрица перспективного проектирования на плоскость XY, (z = 0) Камера находится в точке (0, 0, c)
                            | 1 0 0 0 |
                            | 0 1 0 0 |
                            | 0 0 0 -1/c|
                            | 0 0 0 1 |

                            Матрица перспективного проектирования на плоскость XY, для камеры в любой точке (a, b, c)пространства
                            | 1 0 0 -1/a |
                            | 0 1 0 -1/b |
                            | 0 0 0 -1/c |
                            | 0 0 k 1 |
                            k --- это смещение экранной плоскости воль оси Z

                            Применять матрицы перспективного проектирования так же как и матрицы параллельного проектирования.

                            Для изменения вида проекции остаточно просто сменить одну матрицу на другую.
                            враньё! при перспективе используется нелинейное преобразование - там вращают точку матрицей поворота и делят х и у на разность между z и точкой, в которой находится центр камеры, тоесь точкой (0, 0, -с).
                              Не горячитесь smile.gif Используются действительно четырехмерные вектора и матрицы 4х4, т.к, ими можно описать и повороты, и масштабирования, и, самое главное, перемещения объектов smile.gif. А вот как результаты операций интерпретируются (какие координаты вектора используются) -- ето уже другое дело smile.gif
                              Сообщение отредактировано: Visitor -
                                всёравно перспективу матрицей не опишешь!!
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.0738 ]   [ 14 queries used ]   [ Generated: 24.10.26, 06:44 GMT ]