На главную Наши проекты:
Журнал   ·   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 ... Последняя » все  ( Перейти к последнему сообщению )  
> как заставить закрутиться кубик
    Народ вот кусок функции рисующий линию в 3хмерных координатах

    void CKubikDlg::draw3dline(int x1,int y1,int z1,int x2,int y2,int z2,int ch)
    {
    float kx1,kx2,ky1,ky2;
    kx1 = x1 + x1 * (z1 * 0.007);
    ky1 = y1 + y1 * (z1 * 0.007);
    kx2 = x2 + x2 * (z2 * 0.007);
    ky2 = y2 + y2 * (z2 * 0.007);
    line(kx1,ky1,kx2,ky2,ch);

    }
    А как заставить его крутиться програмно, причем не по ламерски как в тесте директ 3Д, а по нажатию клавишь? При чем вертеться он должен на трёх осях симетрии(куба)Типа как глобус.
    Да, чуть не забыл, должен быть эфект фокуса, это когда дальние грани куба меньше передних.
      Вращай точки куба. Создай матрицу оборота или кватернионы оборота. Для матриц: создай матрицы оборота вокруг всех осей и перемножь (помня, что порядок умножения играет роль).
      Что у тебя за ф-ия проекции какая-то странная.
      Обычно берется x1 = x*C/z, y1 = y*C/z, а константа C высчитывается в зависимости от угла видения и величины окна-экрана.
      Фокус.. толщину линии сделай зависимой от z..
      При нажатии определенной клавиши оборачивай куб на данный угол.
        Вопрос достаточно объемный чтобы ответить на него одним постом.

        Проще работать с векторами. Значит нужен соответствующий класс.
        Все преобразования с векторами удобно делать в матричной форме --- класс матрицы
        Классы всех примитивов: отрезок, параллелепипед, и тд.
        Класс пространства с экранной плоскостью и со свойствами перспективы (проецирования).
        В общем, тут вариантов может быть много.

        При таком подходе, повернуть примитив вокруг одной из своих осей достаточно просто. Нужно перемножить матрицу вершин на матрицу вращения.
        Примерно так
        CODE

        CVector one(1, 1, 1);
        CVector two(9, 9, 9);

        CKub sample_kub(one, two);
        CKub rotated_kub;

        CMatrix matrix();

        CSpace space;

        matrix.RotateZ(10);

        rotated_kub = sample_kub * matrix;

        space.view(rotated_kub);


        Необходимо правильно математически реализовать вектора, матрицы, перспективу и их свойства.

        Как вариант смотри ниже
          CODE
          // Объявление класса вектор
          // Vectors.hpp

          #ifndef __VECTORS__
          #define __VECTORS__

          #include <math.h>

          //========================================================================
          class Vector
          {
          public:
           double x,y,z;
           //Vector();
           inline Vector(){x = y = z = 0;}
           Vector(double v) {x = y = z = v;};  // конструктор с одним параметром
           Vector(const Vector& v){x = v.x; y = v.y; z = v.z;};  // конструктор копировани
           Vector(double vx, double vy, double vz){x = vx; y = vy; z = vz;};  // конструктор с установкой всех координат
           Vector& operator = (const Vector& v)  // оператор присваивания вектора вектору
                  {x = v.x; y = v.y; z = v.z; return *this;};
           Vector& operator = (double f) {x = y = z = f; return *this;};  // оператор присваивания одного числа всем координатам
           Vector operator - ()const;          // оператор инвертирования всех координат
           Vector& operator += (const Vector&); // оператор увеличения координат одного вектора на координаты другого вектора
           Vector& operator -= (const Vector&); // оператор уменьшения координат одного вектора из координат другого вектора
           Vector& operator *= (const Vector&); // оператор умножения координат одного вектра на координаты другого вектора
           Vector& operator *= (double); // оператор умножения координат вектора на число
           Vector& operator /= (double); // оператор деления координат вектора на число

           friend Vector operator + (const Vector&,const Vector&); // оператор сложения векторов
           friend Vector operator - (const Vector&,const Vector&); // оператор вычитания векторов
           friend Vector operator * (const Vector&,const Vector&); // оператор перемножения векторов
           friend Vector operator * (double,const Vector&); // оператор умножения числа на вектор
           friend Vector operator * (const Vector&,double); // оператор умножения вектора на число
           friend Vector operator / (const Vector&,double); // оператор деления вектора на число
           friend Vector operator / (const Vector&,const Vector&); // оператор деления векторов
           friend double operator & (const Vector& u,const Vector& v); // оператор скалярного произведени
           friend Vector operator ^ (const Vector&,const Vector&); // оператор векторного произведени
           double operator ! () {return (double) sqrt(x*x + y*y + z*z);}; // оператор вычисления длинны вектора
           double& operator [] (int n) {return *(&x + n);}; // оператор получения компонента вектора
           int  operator < (double v){return x < v && y < v && z < v;}; // оператор сравнения векторов
           int  operator > (double v){return x > v && y > v && z > v;}; // оператор сравнения векторов
           int  operator <= (double v){return x <= v && y <= v && z <= v;}; // оператор сравнения векторов
           int  operator >= (double v){return x >= v && y >= v && z >= v;}; // оператор сравнения векторов
          //   operator int() {return (int)x,(int)y;};
          };

          //========================================================================
            class Ray
             {
              public:
               Vector Org;
               Vector Dir;
               Ray () {};
               Ray (Vector& o,Vector& d) {Org = 0;Dir = d;};
              Vector Point (double t){return Org + Dir*t;};
             };

          //========================================================================
          // Конструктор по умолчанию

          //========================================================================
          // оператор инвертирования всех координат вектора
          inline Vector Vector::operator - ()const
          {
           return Vector(-x,-y,-z);
          }
          //========================================================================
          // оператор скалярного произведения векторов
          inline double operator & (const Vector& u,const Vector& v)
          {
           return u.x*v.x + u.y*v.y + u.z*v.z;
          }
          //========================================================================
          // оператор сложения векторов
          inline Vector operator + (const Vector& u,const Vector& v)
          {
           return Vector (u.x + v.x,u.y + v.y, u.z + v.z);
          }
          //========================================================================
          // оператор вычитания векторов
            inline Vector operator - (const Vector& u,const Vector& v)
             {
              return Vector (u.x - v.x,u.y - v.y, u.z - v.z);
             }
          //========================================================================
          // оператор перемножения векторов
            inline Vector operator * (const Vector& u,const Vector& v)
             {
              return Vector (u.x * v.x,u.y * v.y, u.z * v.z);
             }
          //========================================================================
          // оператор умножения вектора на число
            inline Vector operator * (const Vector& u,double f)
             {
              return Vector (u.x * f,u.y * f, u.z * f);
             }
          //========================================================================
          // оператор умножения числа на вектор
            inline Vector operator * (double f, const Vector& u)
             {
              return Vector (f * u.x, f * u.y, f * u.z);
             }
          //========================================================================
          // оператор деления вектора на число
            inline Vector operator / (const Vector& u, double f)
             {
              return Vector (u.x / f, u.y / f, u.z / f);
             }
          //========================================================================
          // оператор деления векторов
            inline Vector operator / (const Vector& u, const Vector& v)
             {
              return Vector (u.x / v.x, u.y / v.y, u.z / v.z);
             }
          //========================================================================
          // оператор увеличения координат одного вектора на координаты другого вектора
           inline Vector&  Vector:: operator += (const Vector& v)
            {
             x+= v.x;
             y+= v.y;
             z+= v.z;
              return *this;
            }
          //========================================================================
          // оператор уменьшения координат одного вектора из координаты другого вектора
           inline Vector&  Vector:: operator -= (const Vector& v)
            {
             x-= v.x;
             y-= v.y;
             z-= v.z;
              return *this;
            }
          //========================================================================
          // оператор умножения координат вектора на число
           inline Vector&  Vector:: operator *= (double v)
            {
             x*= v;
             y*= v;
             z*= v;
              return *this;
            }
          //========================================================================
          // оператор умножения координат одного вектра на координаты другого вектора
           inline Vector&  Vector::operator *= (const Vector& v)
            {
             x*= v.x;
             y*= v.y;
             z*= v.z;
              return *this;
            }
          //========================================================================
          // оператор деления координат вектора на число
           inline Vector&  Vector:: operator /= (double v)
            {
             x/= v;
             y/= v;
             z/= v;
              return *this;
            }

          //========================================================================
          inline Vector Normalize(Vector& v){return v/!v;};  // Нормализация вектора
          //========================================================================
          // получение равномерно распределенного случайного единичного вектора
          Vector RndVector();
          //========================================================================
          Vector& Clip (Vector&);                // отсечение вектора

          #endif
            CODE

            // Vectors.cpp

            #include <math.h>
            #include <stdlib.h>
            #include "Vectors.hpp"
            //========================================================================
            // оператор векторного произведени
            Vector operator ^ (const Vector& u,const Vector& v)
             {
              return Vector (u.y * v.z - u.z * v.y , u.z * v.x - u.x * v.z,
                 u.x * v.y - u.y * v.x);
             }
            //========================================================================
            // получение равномерно распределенного случайного единичного вектора
             Vector RndVector()
              {
                Vector v(rand() - 0.5*RAND_MAX,
                  rand() - 0.5*RAND_MAX,rand() - 0.5*RAND_MAX);
                return Normalize(v);
              }
            //========================================================================
            // отсечение вектора
             Vector& Clip (Vector& v)
              {
                if (v.x < 0.0) v.x = 0.0;
                 else
                  if (v.x > 1.0) v.x = 1.0;
                 if (v.y < 0.0) v.y = 0.0;
                  else
            if (v.y > 1.0) v.y = 1.0;
                 if (v.z < 0.0) v.z = 0.0;
                  else
            if (v.z > 1.0) v.z = 1.0;
                return v;
              }
            //========================================================================
            Сообщение отредактировано: MeG -
              CODE
              // Определение класса матриц преобразования векторов
              // MATRIX.HPP

              #ifndef __MATRIX__
              #define __MATRIX__

              #include "Vectors.hpp"

              class Matrix
              {
               public:
               double x[4][4];
               Matrix () {};
               Matrix (double); // конструктор диагональной матрицы
               Matrix& operator += (const Matrix&); // прибавить матрицу
               Matrix& operator -= (const Matrix&);  // вычесть матрицу
               Matrix& operator *= (const Matrix&);  // умножить матрицу на матрицу
               Matrix& operator *= (double);      // умножить матрицу на число
               Matrix& operator /= (double);      // разделить матирцу на число
               void Invert();
               void Transpose();                  // транспонировать матрицу
               friend Matrix operator + (const Matrix&,const Matrix&);// сложить матрицы
               friend Matrix operator - (const Matrix&,const Matrix&);// вычесть матрицы
               friend Matrix operator * (const Matrix&,double);  // умножить матрицу
               friend Matrix operator * (const Matrix&,const Matrix&);// перемножить матрицы
               friend Vector operator * (const Matrix&,const Vector&);// перемножить матрицу и вектор
              };
               Matrix Translate (const Vector&);    // передвинуть матрицу на вектор
               Matrix Scale (const Vector&);        // масштабировать матрицу
               Matrix RotateX (double);             // повернуть матрицу вокруг X
               Matrix RotateY (double);             // повернуть матрицу вокруг Y
               Matrix RotateZ (double);             // повернуть матрицу вокруг Z
               Matrix Rotate (const Vector& v,double);// повернуть матрицу вокруг вектора
               Matrix MirrorX ();
               Matrix MirrorY ();
               Matrix MirrorZ ();

              #endif
                CODE
                // Matrix.cpp

                #include <math.h>
                #include "Matrix.hpp"

                //========================================================================
                Matrix::Matrix(double v)// конструктор диагональной матрицы
                {
                 for (int i = 0; i < 4; i++)
                   for (int j = 0; j < 4; j++)
                     x[i][j]=(i==j)?v:0.0;
                 x[3][3]=1;
                }

                //========================================================================
                void Matrix::Invert()
                {
                 Matrix Out(1);
                 for (int i = 0; i < 4; i++)
                 {
                   double d = x[i][i];
                   if (d != 1.0)
                   {
                     for (int j = 0; j < 4; j++)
                     {
                       Out.x[i][j] /= d;
                       x[i][j] /= d;
                     }
                   }
                   for (int j = 0; j < 4; j++)
                   {
                     if (j != i)
                     {
                       if (x[j][i] != 0.0)
                       {
                         double mulby = x[j][i];
                         for (int k = 0; k < 4; k++)
                         {
                           x[j][k] -= mulby * x[i][k];
                           Out.x[j][k] -= mulby * Out.x[i][k];
                         }
                       }
                     }
                   }
                 }
                 *this = Out;
                }

                //========================================================================
                // транспонировать матрицу
                void Matrix::Transpose()
                {
                 double t;
                 for (int i = 0; i < 4; i++)
                   for (int j = i; j < 4; j++)
                     if (i != j)
                     {
                       t = x[i][j];
                       x[i][j]= x[j][i];
                       x[j][i]= t;
                     }
                }

                //========================================================================
                Matrix& Matrix::operator += (const Matrix& A)
                {
                 for (int i = 0; i < 4; i++)
                   for (int j = 0; j < 4; j++)
                     x[i][j]  += A.x[i][j];
                 return *this;
                }

                //========================================================================
                Matrix& Matrix::operator -= (const Matrix& A)
                {
                 for (int i = 0; i < 4; i++)
                   for (int j = 0; j < 4; j++)
                     x[i][j]  -= A.x[i][j];
                 return *this;
                }

                //========================================================================
                Matrix& Matrix::operator *= (double v)
                {
                 for (int i = 0; i < 4; i++)
                   for (int j = 0; j < 4; j++)
                     x[i][j]  *= v;
                 return *this;
                }

                //========================================================================
                Matrix& Matrix::operator *= (const Matrix& A)
                {
                 Matrix res = *this;
                 for (int i = 0; i < 4; i++)
                   for (int j = 0; j < 4; j++)
                   {
                     double sum = 0;
                     for (int k = 0; k < 4; k++)
                       sum += res.x[i][k] * A.x[k][j];
                     x[i][j]  = sum;
                   }
                 return *this;
                }

                //========================================================================
                Matrix  operator + (const Matrix& A,const Matrix& B)
                {
                 Matrix res;
                 for (int i = 0; i < 4; i++)
                   for (int j = 0; j < 4; j++)
                      res.x[i][j] = A.x[i][j] + B.x[i][j];
                 return res;
                }

                //========================================================================
                Matrix  operator - (const Matrix& A,const Matrix& B)
                {
                 Matrix res;
                 for (int i = 0; i < 4; i++)
                   for (int j = 0; j < 4; j++)
                     res.x[i][j] = A.x[i][j] - B.x[i][j];
                 return res;
                }

                //========================================================================
                Matrix  operator * (const Matrix& A,const Matrix& B)
                {
                 Matrix res;
                 for (int i = 0; i < 4; i++)
                   for (int j = 0; j < 4; j++)
                   {
                     double sum = 0;
                     for (int k = 0; k < 4; k++)
                       sum +=  A.x[i][k] * B.x[k][j];
                     res.x[i][j] = sum;
                   }
                 return res;
                }

                //========================================================================
                Matrix  operator * (const Matrix& A,double v)
                {
                 Matrix res;
                 for (int i = 0; i < 4; i++)
                   for (int j = 0; j < 4; j++)
                     res.x[i][j] = A.x[i][j] * v;
                return res;
                }

                //========================================================================
                Vector operator * (const Matrix& M,const Vector& v)
                {
                 Vector res;
                 res.x = v.x * M.x[0][0] + v.y * M.x[1][0] + v.z * M.x[2][0] + M.x[3][0];
                 res.y = v.x * M.x[0][1] + v.y * M.x[1][1] + v.z * M.x[2][1] + M.x[3][1];
                 res.z = v.x * M.x[0][2] + v.y * M.x[1][2] + v.z * M.x[2][2] + M.x[3][2];
                 double denom = v.x * M.x[0][3] + v.y * M.x[1][3] + v.z * M.x[2][3] + M.x[3][3];
                 if ( denom != 1.0)
                   res /= denom;
                 return res;
                }

                //========================================================================
                Matrix Translate (const Vector& Loc)
                {
                 Matrix res(1);
                 res.x[3][0] = Loc.x;
                 res.x[3][1] = Loc.y;
                 res.x[3][2] = Loc.z;
                 return res;
                }

                //========================================================================
                Matrix Scale (const Vector& v)
                {
                 Matrix res(1);
                 res.x[0][0] = v.x;
                 res.x[1][1] = v.y;
                 res.x[2][2] = v.z;
                 return res;
                }

                //========================================================================
                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 RotateY (double Angle)
                {
                 Matrix res(1);
                 double Cosine = cos(Angle);
                 double Sine = sin(Angle);
                 res.x[0][0] = Cosine;
                 res.x[2][0] = -Sine;
                 res.x[0][2] = Sine;
                 res.x[2][2] = Cosine;
                 return res;
                }

                //========================================================================
                Matrix RotateZ (double Angle)
                {
                 Matrix res(1);
                 double Cosine = cos(Angle);
                 double Sine = sin(Angle);
                 res.x[0][0] = Cosine;
                 res.x[1][0] = -Sine;
                 res.x[0][1] = Sine;
                 res.x[1][1] = Cosine;
                 return res;
                }

                //========================================================================
                Matrix Rotate (const Vector& axis, double Angle)
                {
                 Matrix res(1);
                 double Cosine = cos(Angle);
                 double Sine = sin(Angle);
                 res.x[0][0] = axis.x * axis.x + (1 - axis.x * axis.x)* Cosine;
                 res.x[0][1] = axis.x * axis.y * (1 - Cosine) + axis.z * Sine;
                 res.x[0][2] = axis.x * axis.z * (1 - Cosine) - axis.y * Sine;
                 res.x[0][3] = 0;
                 res.x[1][0] = axis.x * axis.y * (1 - Cosine) - axis.z * Sine;
                 res.x[1][1] = axis.y * axis.y + (1 - axis.y * axis.y)* Cosine;
                 res.x[1][2] = axis.y * axis.z * (1 - Cosine) + axis.x * Sine;
                 res.x[1][3] = 0;
                 res.x[2][0] = axis.x * axis.z * (1 - Cosine) + axis.y * Sine;
                 res.x[2][1] = axis.y * axis.z * (1 - Cosine) - axis.x * Sine;
                 res.x[2][2] = axis.z * axis.z + (1 - axis.z * axis.z)* Cosine;
                 res.x[2][3] = 0;
                 res.x[3][0] = 0;
                 res.x[3][1] = 0;
                 res.x[3][2] = 0;
                 res.x[3][3] = 1;
                 return res;
                }

                //========================================================================
                Matrix MirrorX ()
                {
                 Matrix res(1);
                 res.x[0][0] = -1;
                 return res;
                }

                //========================================================================
                Matrix MirrorY ()
                {
                 Matrix res(1);
                 res.x[1][1] = -1;
                 return res;
                }

                //========================================================================
                Matrix MirrorZ ()
                {
                 Matrix res(1);
                 res.x[2][2] = -1;
                 return res;
                }

                //========================================================================
                  CODE
                  // Класс отрезок
                  // SEGMENT.HPP

                  #ifndef __SEGMENT__
                  #define __SEGMENT__

                  #include "vectors.hpp"
                  #include "matrix.hpp"

                  class segment
                  {
                  private:
                   Vector begin_point, end_point;
                   int status;
                  public:
                   inline segment(){status = 0;}
                   inline segment(Vector b, Vector e)
                       {begin_point = b, end_point = e, status = 1;}
                   inline segment(Vector b, Vector e, int s)
                       {begin_point = b, end_point = e, status = s;}
                   segment & operator = (const segment &);
                  //  segment & operator * (const Matrix &);
                   friend segment  operator * (const segment &, const Matrix &);
                   inline Vector & get_begin(){return begin_point;};
                   inline Vector & get_end(){return end_point;};
                   inline int & get_status(){return status;};
                   inline Vector & operator [](int n)
                       {if(n) return end_point; else return begin_point;};
                  };

                  #endif
                    CODE
                    // SEGMENT.cpp

                    #include "segment.hpp"

                    //========================================================================
                    /*segment::segment(const segment & RR)
                    {
                     begin_point.x = RR.begin_point.x;
                     begin_point.y = RR.begin_point.y;
                     begin_point.z = RR.begin_point.z;
                     end_point = RR.end_point;
                     status = RR.status;
                    }*/
                    //========================================================================
                    segment & segment::operator = (const segment & s)
                    {
                     begin_point = s.begin_point;
                     end_point = s.end_point;
                     status = s.status; return * this;
                    }

                    //========================================================================
                    /*segment & segment::operator * (const Matrix & m)
                    {
                     begin_point = m * begin_point;
                     end_point = m * end_point;
                     return * this;
                    } */

                    //========================================================================
                    segment operator * (const segment & s, const Matrix & m)
                    {
                     return segment(m * s.begin_point, m * s.end_point, s.status);
                    }
                      CODE
                      // Параллелепипед
                      // PARALL0.HPP
                      #ifndef __PARALL0__
                      #define __PARALL0__
                      #include "vectors.hpp"
                      #include "matrix.hpp"
                      #include "segment.hpp"
                      class parall
                      {
                      private:
                       Vector tlb, brf;         // две вершины задающие параллелепипед
                       Vector solid[8];         // вершины позиционированные
                       segment view_table[12];  // отрезки на картинной плоскости
                       Vector normal[6];        // нормали к граням параллелепипеда
                       Matrix AA;
                       Matrix pos;      // матрица позиционирования параллелепипеда
                       void create_solid();// создает массивы вершин и нормалей к граням
                       int vis_seg(int, Vector);// проверка видимости ребра
                       float vis_plane(int, Vector);// проверка видимости грани
                      public:
                       parall();//{Matrix BB(1); AA = BB; pos = BB;}
                       segment * rot_x(int);
                       segment * rot_y(int);
                       segment * rot_z(int);
                       segment * rot_v(int);
                       segment * get_V_table(const Vector, const Matrix V);
                       inline Vector & get_tlb(){return tlb;}
                       inline Vector & get_brf(){return brf;}
                       inline Vector * get_solid(){return solid;}
                       inline Vector * get_normal(){return normal;}
                       inline Matrix & get_pos(){return pos;}
                       //inline int get_status(){return 0;}
                      };
                      #endif
                      Сообщение отредактировано: MeG -
                        CODE
                        // parall0.cpp

                        #include "parall0.hpp"

                        //========================================================================
                        parall::parall()
                        {
                         Matrix BB(1);
                         AA = BB;
                         pos = BB;
                         //tlb = Vector(-20);
                         //brf = Vector(80);
                         tlb = Vector(-30, -50, -30);
                         brf = Vector(30, 50, 50);
                        }

                        //========================================================================
                        void parall::create_solid()
                        {
                         //pos = RotateX(1.0);
                         //pos = RotateY(1.0) *  RotateX(1.0);
                         //pos = Scale( Vector() = 1.5) * RotateY(3.1415926 / 4) * RotateX(3.1415926 / 4);
                         //pos = Scale( Vector() = 1.5);
                         solid[0] = pos * tlb;                          // слева, сверху, сзади
                         solid[1] = pos * Vector(tlb.x, tlb.y, brf.z);  // слева, сверху, спереди
                         solid[2] = pos * Vector(brf.x, tlb.y, brf.z);  // справа, сверху, спереди
                         solid[3] = pos * Vector(brf.x, tlb.y, tlb.z);  // справа, сверху, сзади
                         solid[4] = pos * Vector(brf.x, brf.y, tlb.z);  // справа, снизу, сзади
                         solid[5] = pos * Vector(tlb.x, brf.y, tlb.z);  // слева, снизу, сзади
                         solid[6] = pos * Vector(tlb.x, brf.y, brf.z);  // слева, снизу, спереди
                         solid[7] = pos * brf;                          // спрва, снизу, спереди

                         normal[0] = pos * Vector(0, -1, 0);    // к верхней грани
                         normal[1] = pos * Vector(-1, 0, 0);   // к левой грани
                         normal[2] = pos * Vector(0, 0, 1);    // к передней грани
                         normal[3] = pos * Vector(1, 0, 0);    // к правой грани
                         normal[4] = pos * Vector(0, 0, -1);   // к задней грани
                         normal[5] = pos * Vector(0, 1, 0);   // к нижней грани
                        }

                        //========================================================================
                        // Заполняет таблицу отрезков и возвращает указатель на нее
                        segment * parall::get_V_table(const Vector d, const Matrix  V)
                        {
                         create_solid();
                         //vis_plane(d);//(Vector)//вычисляет cos_seg[6] с позиции камеры
                         view_table[0] = segment(solid[0], solid[1], vis_seg(0, d)) * V;
                         view_table[1] = segment(solid[1], solid[2], vis_seg(1, d)) * V;
                         view_table[2] = segment(solid[2], solid[3], vis_seg(2, d)) * V;
                         view_table[3] = segment(solid[0], solid[3], vis_seg(3, d)) * V;
                         view_table[4] = segment(solid[0], solid[5], vis_seg(4, d)) * V;
                         view_table[5] = segment(solid[1], solid[6], vis_seg(5, d)) * V;
                         view_table[6] = segment(solid[2], solid[7], vis_seg(6, d)) * V;
                         view_table[7] = segment(solid[3], solid[4], vis_seg(7, d)) * V;
                         view_table[8] = segment(solid[4], solid[5], vis_seg(8, d)) * V;
                         view_table[9] = segment(solid[5], solid[6], vis_seg(9, d)) * V;
                         view_table[10] = segment(solid[6], solid[7], vis_seg(10, d)) * V;
                         view_table[11] = segment(solid[7], solid[4], vis_seg(11, d)) * V;
                         return view_table;
                        }

                        //========================================================================

                        //========================================================================
                        // вычисляет видимость грани с позиции точки размещения камеры
                        float parall::vis_plane(int n, Vector s)
                        {
                         Vector v;
                         switch(n)
                         {
                           case 0 : v = solid[0]; break;       // 0, 1, 2, 3
                           case 1 : v = solid[0]; break;       // 0, 1, 5, 6
                           case 2 : v = solid[1]; break;       // 1, 2, 6, 7
                           case 3 : v = solid[2]; break;       // 2, 3, 4, 7
                           case 4 : v = solid[0]; break;       // 0, 3, 4, 5
                           case 5 : v = solid[4]; break;       // 4, 5, 6, 7
                         }
                         return normal[n].z * s.z - (normal[n].x * v.x +
                             normal[n].y * v.y + normal[n].z * v.z);
                        }

                        //========================================================================
                        // вычисляет видимость ребра
                        // возвращает номер типа линии для данного отрезка
                        int parall::vis_seg(int seg, Vector dir)
                        {
                         int v_s = 8, nv_s = 10;
                         switch(seg)
                         {
                           case 0: return
                           ((vis_plane(0, dir) < 0) && (vis_plane(1, dir) < 0)) ? nv_s : v_s;
                           case 1: return
                           ((vis_plane(0, dir) < 0) && (vis_plane(2, dir) < 0)) ? nv_s : v_s;
                           case 2: return
                           ((vis_plane(0, dir) < 0) && (vis_plane(3, dir) < 0)) ? nv_s : v_s;
                           case 3: return
                           ((vis_plane(0, dir) < 0) && (vis_plane(4, dir) < 0)) ? nv_s : v_s;
                           case 4: return
                           ((vis_plane(4, dir) < 0) && (vis_plane(1, dir) < 0)) ? nv_s : v_s;
                           case 5: return
                           ((vis_plane(2, dir) < 0) && (vis_plane(1, dir) < 0)) ? nv_s : v_s;
                           case 6: return
                           ((vis_plane(2, dir) < 0) && (vis_plane(3, dir) < 0)) ? nv_s : v_s;
                           case 7: return
                           ((vis_plane(3, dir) < 0) && (vis_plane(4, dir) < 0)) ? nv_s : v_s;
                           case 8: return
                           ((vis_plane(4, dir) < 0) && (vis_plane(5, dir) < 0)) ? nv_s : v_s;
                           case 9: return
                           ((vis_plane(1, dir) < 0) && (vis_plane(5, dir) < 0)) ? nv_s : v_s;
                           case 10: return
                           ((vis_plane(2, dir) < 0) && (vis_plane(5, dir) < 0)) ? nv_s : v_s;
                           case 11: return
                           ((vis_plane(3, dir) < 0) && (vis_plane(5, dir) < 0)) ? nv_s : v_s;
                         }
                         return 0;
                        }
                        //========================================================================
                          CODE
                          // Класс пространства
                          // Space.hpp
                          #ifndef __SPACE__
                          #define __SPACE__
                          #include "vectors.hpp"
                          #include "matrix.hpp"
                          #include "segment.hpp"
                          #include "parall0.hpp"
                          #include "seg_cross.hpp"
                          class space
                          {
                          //Vector * m_pp;
                          Vector m_center;
                          Vector view_center;
                          Vector camera_center;
                          Matrix view, proj;
                          segment AA, BB, CC;
                          segment axisX, axisY, axisZ;
                          segment seg[40], * par;
                          int proj_num;
                          parall parallelepiped;
                          Matrix & projection(int); // номер проекции
                          crosser line_c;
                          public:
                          space();
                          Vector & get_view_center();
                          void set_out_seg();
                          segment & get_seg(int);
                          segment & get_axis(int);
                          segment * get_parall();
                          inline segment * get_line()
                          {
                          line_c.inwardly(parallelepiped.get_solid(),
                          parallelepiped.get_normal());
                          // line_c.shadow(camera_center, parallelepiped.get_solid());
                          return line_c.get_cross(view);
                          };
                          inline Matrix & get_p_pos()
                          {
                          return parallelepiped.get_pos();
                          }
                          inline void move_seg_ex(int dx){line_c.move_end(Vector(dx, 0, 0));}
                          inline void move_seg_bx(int dx){line_c.move_begin(Vector(dx, 0, 0));}
                          };
                          #endif

                          CODE
                          Vector view_center; --- вектор для промежуточных вычислений матрицы
                          отображения;
                          Vector camera_center; --- вектор указывающий положение камеры;
                          Matrix view; --- матрица проецирования;
                          int proj_num; --- номер проекции;
                          parall parallelepiped; --- сам параллелепипед;
                          crosser line_c; --- пересекаемая линия;
                          методы:
                          Matrix & projection(int); --- устанавливает и возвращает матрицу проецирования;
                          space();] --- конструктор класса;
                          Vector & get_view_center(); --- возвращает ссылку на вектор смещения центра координат;
                          segment * get_parall(); --- возвращает указатель массива отрезков параллелепипеда;
                          segment * get_line(); --- возвращает указатель массива отрезков рассекаемой линии;
                          Matrix & get_p_pos() --- берет ссылку из объекта параллелепипеда на матрицу позиционирования;
                          void move_seg_ex(int dx) --- передает в объект пересекаемой линии смещение конца отрезка;
                          void move_seg_bx(int dx) --- передает в объект пересекаемой линии смещение начала отрезка;
                            а ещё говорят, что с++ - лаконичный язык!!
                            да я на паскале 3д екшын написал в ~600 строк, включая мыша и вывод на екран!!!
                            а если только ядро, то ~200 строк
                            http://enzyme.nm.ru/vrash.rar /action.exe
                            выходить буквой q
                              Лаконичный-лаконичный smile.gif

                              Если теперь забыть про внутренности етой векторно-матричной библиотеки, то вся программа будет написана в виде

                              vect2 = vect1 * matr3;
                              smile.gif
                                ну так у меня тоже приблизительно так, правда у меня матрица каждый раз заново считается sad.gif
                                только если её считать заранее, наверняка моя программа станет ещё меньше, со всеми внутренностями!
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


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