Russian Qt Forum
Октябрь 01, 2024, 14:35 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: От С++ к Qt C++  (Прочитано 7780 раз)
Skrypnyk
Гость
« : Март 17, 2013, 11:19 »

Здравствуйте!
Я делаю проект для учебы. Мне нужно создать массив атомов. В этом массиве юзер выбирает плоскость используя индексы Миллера. На экране должны быть отображены атомы, принадлежащие плоскости. Я написал код в С++:
Код:
/* I. Create a FCC lattice
   II. Determine the projection plane using Miller indices notation
   III. Calculate the angles between a projection of the normal to the projection plane
        on 3 different planes (XY, XZ and YZ) and axes X [1;0;0], Y [0;1;0] and Z [0;0;1] respectively
   IV. Rotate the grid (do the projection) */
 
#include <iostream>
#include <math.h>
 
using std::cout; // Using standart namespace
using std::cin;
using std::endl;
 
class Atom
{
  public:
    float x, y, z; // Coordinates of the atoms
};
 
typedef class Atom AtomType;
 
    AtomType Atom1 [10][10][10]; // Create a 3 dimensional array to fill the space with atoms of type 1
    AtomType Atom2 [10][10][10]; // Create a 3 dimensional array to fill the space with atoms of type 2
    AtomType Atom3 [10][10][10]; // Create a 3 dimensional array to fill the space with atoms of type 3
    AtomType Atom4 [10][10][10]; // Create a 3 dimensional array to fill the space with atoms of type 4
    AtomType Atom11 [10][10][10]; // Create a 3 dimensional array of atoms of type 1 that belong to projection plane
    AtomType Atom22 [10][10][10]; // Create a 3 dimensional array of atoms of type 2 that belong to projection plane
    AtomType Atom33 [10][10][10]; // Create a 3 dimensional array of atoms of type 3 that belong to projection plane
    AtomType Atom44 [10][10][10]; // Create a 3 dimensional array of atoms of type 4 that belong to projection plane
 
    //float x, y, z;
    int i, j, k; // Variables for array Atom [i][j][k]
    int a, b, c; // Integers, which represent reciprocal values of interceptions of the projection plane
                 // with axes X, Y and Z respectively & also represent a normal to the projection plane
 
void projection();
 
int main ()
{
    float angleX, angleY, angleZ; // Variables to represent angles between a projection of the normal to the projection plane
                                  // on 3 different planes (XY, XZ and YZ) and axes X [1;0;0], Y [0;1;0] and Z [0;0;1] respectively
    // Do item I
    // 3 nested 'for' loops create the grid of atoms of type 1, 2, 3 and 4
    cout << "Atom1                Atom2                   Atom3                Atom4" << endl;
    cout << "-----------------------------------------------------------------------" << endl;
 
    for (i=0; i<10; i++)
    {
        for (j=0; j<10; j++)
        {
            for (k=0; k<10; k++)
            {
                Atom1 [i][j][k].x=i-4; // We get '-4' because we want our origin to be in the centre of array
                Atom1 [i][j][k].y=j-4;
                Atom1 [i][j][k].z=k-4;
 
                Atom2 [i][j][k].x=i-4+0.5; // We get '+0.5' because the atoms of type 2 are shifted on 0.5 along X axis
                Atom2 [i][j][k].y=j-4+0.5; // We get '+0.5' because the atoms of type 2 are shifted on 0.5 along Y axis
                Atom2 [i][j][k].z=k-4;
 
                Atom3 [i][j][k].x=i-4;
                Atom3 [i][j][k].y=j-4+0.5; // We get '+0.5' because the atoms of type 2 are shifted on 0.5 along Y axis
                Atom3 [i][j][k].z=k-4+0.5; // We get '+0.5' because the atoms of type 2 are shifted on 0.5 along Z axis
 
                Atom4 [i][j][k].x=i-4+0.5; // We get '+0.5' because the atoms of type 2 are shifted on 0.5 along X axis
                Atom4 [i][j][k].y=j-4;
                Atom4 [i][j][k].z=k-4+0.5; // We get '+0.5' because the atoms of type 2 are shifted on 0.5 along Z axis
 
                cout << Atom1 [i][j][k].x << " " << Atom1 [i][j][k].y << " " << Atom1 [i][j][k].z << "          ";
                cout << Atom2 [i][j][k].x << " " << Atom2 [i][j][k].y << " " << Atom2 [i][j][k].z << "          ";
                cout << Atom3 [i][j][k].x << " " << Atom3 [i][j][k].y << " " << Atom3 [i][j][k].z << "          ";
                cout << Atom4 [i][j][k].x << " " << Atom4 [i][j][k].y << " " << Atom4 [i][j][k].z << "          " << endl;
            }
        }
    }
 
    // Do item II
    cout << "Please enter the projection plane using Miller indices notation (e.g. 111),\npressing Enter between integers:";
    cin >> a >> b >> c;
 
    // Do item III
    angleX=acos(fabs(a*1+b*0+0*0)/(sqrt(a*a+b*b+0*0)*sqrt(1*1+0*0+0*0))); // The angle is in radians, because any functions from
    angleY=acos(fabs(0*0+b*1+c*0)/(sqrt(0*0+b*b+c*c)*sqrt(0*0+1*1+0*0))); // 'math.h' that operate on angles use radians as the
    angleZ=acos(fabs(a*0+0*0+c*1)/(sqrt(a*a+0*0+c*c)*sqrt(0*0+0*0+1*1))); // unit of angle
 
    // Do item IV
    /* To obtain a new position of atoms we need to multiply the current position by rotation matrix.
       Current position:
 
       [AtomN [i][j][k].x, AtomN [i][j][k].y, AtomN [i][j][k].z] // N - any number from 1 to 4
 
       Rotation about X axis matrix:
 
       1        0               0
       0    cos(angleX)    sin(angleX)
       0   -sin(angleX)    cos(angleX)
 
       Rotation about Y axis matrix:
 
       cos(angleY)   0    -sin(angleY)
            0        1          0
       sin(angleY)   0     cos(angleY)
 
       Rotation about Z axis matrix:
 
       cos(angleZ)   sin(angleZ)   0
      -sin(angleZ)   cos(angleZ)   0
            0            0         1
       */
 
    cout << "Atom1                Atom2                   Atom3                Atom4" << endl;
    cout << "-----------------------------------------------------------------------" << endl;
 
    // Do rotation about X axis
    for (i=0; i<10; i++)
    {
        for (j=0; j<10; j++)
        {
            for (k=0; k<10; k++)
            {
                Atom1 [i][j][k].x=Atom1 [i][j][k].x*1+Atom1 [i][j][k].y*0+Atom1 [i][j][k].z*0;
                Atom1 [i][j][k].y=Atom1 [i][j][k].x*0+Atom1 [i][j][k].y*cos(angleX)+Atom1 [i][j][k].z*(-sin(angleX));
                Atom1 [i][j][k].z=Atom1 [i][j][k].x*0+Atom1 [i][j][k].y*sin(angleX)+Atom1 [i][j][k].z*cos(angleX);
 
                Atom2 [i][j][k].x=Atom2 [i][j][k].x*1+Atom2 [i][j][k].y*0+Atom2 [i][j][k].z*0;
                Atom2 [i][j][k].y=Atom2 [i][j][k].x*0+Atom2 [i][j][k].y*cos(angleX)+Atom2 [i][j][k].z*(-sin(angleX));
                Atom2 [i][j][k].z=Atom2 [i][j][k].x*0+Atom2 [i][j][k].y*sin(angleX)+Atom2 [i][j][k].z*cos(angleX);
 
                Atom3 [i][j][k].x=Atom3 [i][j][k].x*1+Atom3 [i][j][k].y*0+Atom3 [i][j][k].z*0;
                Atom3 [i][j][k].y=Atom3 [i][j][k].x*0+Atom3 [i][j][k].y*cos(angleX)+Atom3 [i][j][k].z*(-sin(angleX));
                Atom3 [i][j][k].z=Atom3 [i][j][k].x*0+Atom3 [i][j][k].y*sin(angleX)+Atom3 [i][j][k].z*cos(angleX);
 
                Atom4 [i][j][k].x=Atom4 [i][j][k].x*1+Atom4 [i][j][k].y*0+Atom4 [i][j][k].z*0;
                Atom4 [i][j][k].y=Atom4 [i][j][k].x*0+Atom4 [i][j][k].y*cos(angleX)+Atom4 [i][j][k].z*(-sin(angleX));
                Atom4 [i][j][k].z=Atom4 [i][j][k].x*0+Atom4 [i][j][k].y*sin(angleX)+Atom4 [i][j][k].z*cos(angleX);
            }
        }
    }
    // Do rotation about Y axis
    for (i=0; i<10; i++)
    {
        for (j=0; j<10; j++)
        {
            for (k=0; k<10; k++)
            {
                Atom1 [i][j][k].x=Atom1 [i][j][k].x*cos(angleY)+Atom1 [i][j][k].y*0+Atom1 [i][j][k].z*sin(angleY);
                Atom1 [i][j][k].y=Atom1 [i][j][k].x*0+Atom1 [i][j][k].y*1+Atom1 [i][j][k].z*0;
                Atom1 [i][j][k].z=Atom1 [i][j][k].x*(-sin(angleY))+Atom1 [i][j][k].y*0+Atom1 [i][j][k].z*cos(angleY);
 
                Atom2 [i][j][k].x=Atom2 [i][j][k].x*cos(angleY)+Atom2 [i][j][k].y*0+Atom2 [i][j][k].z*sin(angleY);
                Atom2 [i][j][k].y=Atom2 [i][j][k].x*0+Atom2 [i][j][k].y*1+Atom2 [i][j][k].z*0;
                Atom2 [i][j][k].z=Atom2 [i][j][k].x*(-sin(angleY))+Atom2 [i][j][k].y*0+Atom2 [i][j][k].z*cos(angleY);
 
                Atom3 [i][j][k].x=Atom3 [i][j][k].x*cos(angleY)+Atom3 [i][j][k].y*0+Atom3 [i][j][k].z*sin(angleY);
                Atom3 [i][j][k].y=Atom3 [i][j][k].x*0+Atom3 [i][j][k].y*1+Atom3 [i][j][k].z*0;
                Atom3 [i][j][k].z=Atom3 [i][j][k].x*(-sin(angleY))+Atom3 [i][j][k].y*0+Atom3 [i][j][k].z*cos(angleY);
 
                Atom4 [i][j][k].x=Atom4 [i][j][k].x*cos(angleY)+Atom4 [i][j][k].y*0+Atom4 [i][j][k].z*sin(angleY);
                Atom4 [i][j][k].y=Atom4 [i][j][k].x*0+Atom4 [i][j][k].y*1+Atom4 [i][j][k].z*0;
                Atom4 [i][j][k].z=Atom4 [i][j][k].x*(-sin(angleY))+Atom4 [i][j][k].y*0+Atom4 [i][j][k].z*cos(angleY);
            }
        }
    }
    // Do rotation about Z axis
    for (i=0; i<10; i++)
    {
        for (j=0; j<10; j++)
        {
            for (k=0; k<10; k++)
            {
                Atom1 [i][j][k].x=Atom1 [i][j][k].x*cos(angleZ)+Atom1 [i][j][k].y*(-sin(angleZ))+Atom1 [i][j][k].z*0;
                Atom1 [i][j][k].y=Atom1 [i][j][k].x*sin(angleZ)+Atom1 [i][j][k].y*cos(angleZ)+Atom1 [i][j][k].z*0;
                Atom1 [i][j][k].z=Atom1 [i][j][k].x*0+Atom1 [i][j][k].y*0+Atom1 [i][j][k].z*1;
 
                Atom2 [i][j][k].x=Atom2 [i][j][k].x*cos(angleZ)+Atom2 [i][j][k].y*(-sin(angleZ))+Atom2 [i][j][k].z*0;
                Atom2 [i][j][k].y=Atom2 [i][j][k].x*sin(angleZ)+Atom2 [i][j][k].y*cos(angleZ)+Atom2 [i][j][k].z*0;
                Atom2 [i][j][k].z=Atom2 [i][j][k].x*0+Atom2 [i][j][k].y*0+Atom2 [i][j][k].z*1;
 
                Atom3 [i][j][k].x=Atom3 [i][j][k].x*cos(angleZ)+Atom3 [i][j][k].y*(-sin(angleZ))+Atom3 [i][j][k].z*0;
                Atom3 [i][j][k].y=Atom3 [i][j][k].x*sin(angleZ)+Atom3 [i][j][k].y*cos(angleZ)+Atom3 [i][j][k].z*0;
                Atom3 [i][j][k].z=Atom3 [i][j][k].x*0+Atom3 [i][j][k].y*0+Atom3 [i][j][k].z*1;
 
                Atom4 [i][j][k].x=Atom4 [i][j][k].x*cos(angleZ)+Atom4 [i][j][k].y*(-sin(angleZ))+Atom4 [i][j][k].z*0;
                Atom4 [i][j][k].y=Atom4 [i][j][k].x*sin(angleZ)+Atom4 [i][j][k].y*cos(angleZ)+Atom4 [i][j][k].z*0;
                Atom4 [i][j][k].z=Atom4 [i][j][k].x*0+Atom4 [i][j][k].y*0+Atom4 [i][j][k].z*1;
 
                cout << Atom1 [i][j][k].x << " " << Atom1 [i][j][k].y << " " << Atom1 [i][j][k].z << "          ";
                cout << Atom2 [i][j][k].x << " " << Atom2 [i][j][k].y << " " << Atom2 [i][j][k].z << "          ";
                cout << Atom3 [i][j][k].x << " " << Atom3 [i][j][k].y << " " << Atom3 [i][j][k].z << "          ";
                cout << Atom4 [i][j][k].x << " " << Atom4 [i][j][k].y << " " << Atom4 [i][j][k].z << "          " << endl;
            }
        }
    }
    projection (); // function projection evaluates whether atoms belong to the projection plane
 
    return 0;
}
 
void projection ()
{
    for (i=0; i<10; i++)
    {
        for (j=0; j<10; j++)
        {
            for (k=0; k<10; k++)
            {
                // Condition for Atom1
                if (Atom1 [i][j][k].x*a + Atom1 [i][j][k].y*b + Atom1 [i][j][k].z*c==1)
                 // Intercept equation of the projection plane is x/m+y/n+z/p=1, but m=1/a; n=1/b; p=1/c;
                {
                    Atom11 [i][j][k].x=Atom1 [i][j][k].x;
                    Atom11 [i][j][k].y=Atom1 [i][j][k].y;
                    Atom11 [i][j][k].z=Atom1 [i][j][k].z;
                }
                else break;
                // Condition for Atom2
                if (Atom2 [i][j][k].x*a + Atom2 [i][j][k].y*b + Atom2 [i][j][k].z*c==1)
                {
                    Atom22 [i][j][k].x=Atom2 [i][j][k].x;
                    Atom22 [i][j][k].y=Atom2 [i][j][k].y;
                    Atom22 [i][j][k].z=Atom2 [i][j][k].z;
                }
                else break;
                // Condition for Atom3
                if (Atom3 [i][j][k].x*a + Atom3 [i][j][k].y*b + Atom3 [i][j][k].z*c==1)
                {
                    Atom33 [i][j][k].x=Atom3 [i][j][k].x;
                    Atom33 [i][j][k].y=Atom3 [i][j][k].y;
                    Atom33 [i][j][k].z=Atom3 [i][j][k].z;
                }
                else break;
                // Condition for Atom4
                if (Atom4 [i][j][k].x*a + Atom4 [i][j][k].y*b + Atom4 [i][j][k].z*c==1)
                {
                    Atom44 [i][j][k].x=Atom4 [i][j][k].x;
                    Atom44 [i][j][k].y=Atom4 [i][j][k].y;
                    Atom44 [i][j][k].z=Atom4 [i][j][k].z;
                }
                else break;
            }
        }
    }
}
 

Я смотрел видео на Ютюбе, читал документацию Qt, но ничего конкретного для решения моей проблемы не нашел. Основной дилеммой является визуализация атомов в плоскости (Аtom11 - Atom44).

Подскажите, пожалуйста, какие-нибудь источники или посоветуйте что-нибудь для решения моей проблемы.

Заранее благодарен!
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Март 17, 2013, 12:45 »

Приведенный код называется "не ленивый программист" (ужасно). Ладно, об этом Вы не спрашивали, чисто по алгоритму:

Зачем Вы связались с поворотами? Что Вы от них хотели? Вам надо найти точки принадлежащие данной плоскости - ну и находите. Задайте плоскость вектором  (a, b, c)  + расстоянием до начала координат (d) и спокойно находите расстояние до нее
Код
C++ (Qt)
bool OnPlane( const Atom & atom, float a, float b, float c, float d, float epsilon )
{
float dist = atom.x * a + atom.y * b + atom.z * c + d;
return fabs(dist) < epsilon;
}
 
Вот и вся любовь
Записан
Dancing_on_water
Гость
« Ответ #2 : Март 17, 2013, 12:51 »

Э-кхм, начну с того, что неплохо подучить C++ как таковой.

В вашем коде стек уже забит дай боже как, еще что-либо в подобном роде и программа начнет вылетать с криками: "Stack Overflow".

Теперь к самому вопросу:

Если вам нужен 3d с кучей объектов, то тут openGL без вариантов.
Если 2d , то пойдет QGraphicsScene

Все прочее не подходит, т.к. у вас в одной плоскости уже 1000 объектов.

Записан
Skrypnyk
Гость
« Ответ #3 : Март 17, 2013, 13:46 »

Приведенный код называется "не ленивый программист" (ужасно). Ладно, об этом Вы не спрашивали, чисто по алгоритму:

Зачем Вы связались с поворотами? Что Вы от них хотели? Вам надо найти точки принадлежащие данной плоскости - ну и находите. Задайте плоскость вектором  (a, b, c)  + расстоянием до начала координат (d) и спокойно находите расстояние до нее
Код
C++ (Qt)
bool OnPlane( const Atom & atom, float a, float b, float c, float d, float epsilon )
{
float dist = atom.x * a + atom.y * b + atom.z * c + d;
return fabs(dist) < epsilon;
}
 
Вот и вся любовь

Повороты нужны для отображения плоскости проекции. Таким образом мы будем смотреть по направлению нормали к плоскости и получим реальные расстояния между атомами на экране.
Записан
Skrypnyk
Гость
« Ответ #4 : Март 17, 2013, 13:50 »

Э-кхм, начну с того, что неплохо подучить C++ как таковой.

В вашем коде стек уже забит дай боже как, еще что-либо в подобном роде и программа начнет вылетать с криками: "Stack Overflow".

Теперь к самому вопросу:

Если вам нужен 3d с кучей объектов, то тут openGL без вариантов.
Если 2d , то пойдет QGraphicsScene

Все прочее не подходит, т.к. у вас в одной плоскости уже 1000 объектов.



Я недавно учу С++, причем программирование -  не основное направление моей учебы. Но мне интересно. Жаль, что времени мало. Спасибо за ответ. Буду читать о QGraphicsScene.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Март 17, 2013, 14:31 »

Лучше не злоупотреблять цитированием если и так ясно о чем речь
Повороты нужны для отображения плоскости проекции. Таким образом мы будем смотреть по направлению нормали к плоскости и получим реальные расстояния между атомами на экране.
Экран всего лишь отображает, поэтому расстояния на экране реальными быть не могут Улыбающийся Если же Вы хотите отобразить на экране секущую плоскость (с найденными точками), то Вам совершенно не нужно изучать какие-то мудреные классы и/или OpenGL. Надо просто перевести найденные точки в экранные координаты построив матрицу поворота. Сначала выведите исходные точки в плоскости XY
Код
C++ (Qt)
QPointF Atom2Screen( const Atom & atom,
                    int w, int h,   // ширина и высота экрана (области вывода)
                    float sizeX, float sizeY )  // размер решетки атомов
{
float scale = qMin(w / sizeX, h / sizeY);
float x = (atom.x - sizeX / 2) * scale + w / 2;
float y = h / 2 - (atom.y - sizeY / 2) * scale;
return QPointF(x, y);
}
 
Чтобы нарисовать найденные точки - все то же самое, только сначала надо помножить точку на матрицу. Чтобы воздух не гонять - нарисуйте исходные, а матрицу я Вам покажу
Записан
Skrypnyk
Гость
« Ответ #6 : Март 17, 2013, 21:08 »

Igors, я получил двухмерные координаты точек секущей. Теперь хотелось бы их визуализировать. Как это сделать, если всем точкам отвечают элементы массива с координатами x, y (Atom11 [j][k].x, Atom11 [j][k].y, и то же для атомов типа 22, 33, 44)?

В Вашей функции Atom2Screen первый аргумент
Цитировать
const Atom & atom
требует ввода указателя, если я не ошибаюсь. Мне нужно создать указатель?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Март 18, 2013, 12:17 »

В Вашей функции Atom2Screen первый аргумент
Цитировать
const Atom & atom
требует ввода указателя, если я не ошибаюсь. Мне нужно создать указатель?
Это "ссылка", в данном случае константная. Просто подавайте в ф-цию элемент массива, указатель создавать не нужно. Подробнее о ссылках - см любую книгу по С++

я получил двухмерные координаты точек секущей. Теперь хотелось бы их визуализировать. Как это сделать, если всем точкам отвечают элементы массива с координатами x, y (Atom11 [j][k].x, Atom11 [j][k].y, и то же для атомов типа 22, 33, 44)?
Визуализация (перевод в экранные координаты) в любом случае выполняется ф-цией которую я привел в предыдущем посте. Если 2 или более точек совпадают в данной проекции - ну увидите их все вместе как одну, это нормально.

То что Вы реализовали называется "углы Эйлера"  (последовательность поворотов). Это длинно и мутно, "зато" в данном случае совершенно неуместно и неправильно. Нужно получить уравнения секущих плоскостей из отрезков Миллера. Это можно сделать напр так
Код
C++ (Qt)
// на основании Вашего текста
QVector3D axisX(10, 0, 0);
QVector3D axisY(0, 10, 0);
QVector3D axisZ(0, 0, 10);
QVector3D cntr(-4, -4, -4);
 
void Miller2Plane( int a, int b, int с, QVector <QVector4D> & plane )
{
for (int i = 0; i < qMax(a, 1); ++i) {
 for (int j = 0; j < qMax(b, 1); ++j) {
  for (int k = 0; k < qMax(c, 1); ++k) {
 
// находим 3 точки плоскости
   QVector <QVector3D> vec;  
   if (a) vec.push_back(cntr + axisX / (i + 1));
   if (b) vec.push_back(cntr + axisY / (j + 1));
   if (c) vec.push_back(cntr + axisZ / (k + 1));
   assert(vec.size() > 0);
   if (!a) vec.push_back(vec.back() + axisX);
   if (!b) vec.push_back(vec.back() + axisY);
   if (!c) vec.push_back(vec.back() + axisZ);
 
// записываем уравнение плоскости (QVector4D)
   QVector3D nor = QVector3D::normal(vec[0], vec[1], vec[2]).normalize();
   plane.push_back(QVector4D(nor, -QVector3D::dotProduct(nor, vec[0])));
  }
 }
}
}
Если a, b, c нули или единицы - одна плоскость, иначе "семейство".
« Последнее редактирование: Март 19, 2013, 11:54 от Igors » Записан
Skrypnyk
Гость
« Ответ #8 : Март 18, 2013, 15:12 »

Igors, спасибо за Ваш ответ. Очень ценная для меня информация. Я использовал углы Эйлера, потому что это был единственный доступный для меня инструмент поворота. У меня есть несколько вопросов по части приведенного Вами кода:

1. QVector <QVector4D> & plane - что нужно вводить как аргумент при вызове функции Miller2Plane (1,1,1, ?)? И зачем нужен QVector4D? Чему отвечает 4-я координата?
2. push_back() - эквивалентно append (), как я понял из документации Кьют.  Т.е. добавляет в конец вектора новое значение?
3. assert(vec.size() > 0) - зачем оценивать количество элементов вектора именно на этом этапе (оценки равны или нет переменные a, b, c нулю)?
4. back()? - зачем возвращать ссылку на последний вектор?
5. В Вашей записи vec
  • , vec [1], vec [2] - обозначаются первые 3 элемента массива vec, которые отвечают индексам Миллера?
6. В
Код:
plane.push_back(QVector4D(nor, -QVector3D::dotProduct(nor, vec[0])));
функция QVector4D - это QVector4D::QVector4D(const QVector3D & vector, float wpos)?
Зачем нужно скалярное произведение нормали к плоскости с, как я понимаю, первым отрезком Миллера? Да еще и со знаком минус?
« Последнее редактирование: Март 18, 2013, 15:14 от Skrypnyk » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Март 18, 2013, 18:32 »

Простейший случай: индекс = (1, 1, 1). Одна секущая плоскость по диагонали. cntr + axisX(Y, Z) есть 3 точки лежащие в этой плоскости. Уравнение плоскости

ax + by + cz + d = 0;

a, b, c  - нормаль к плоскости, d - расстояние до начала координат. Если подставить точку (x. y. z) в это уравнение, результат будет (знаковое) расстояние от точки до плоскости. Если точка лежит на плоскости, то уравнение даст ноль. Находим нормаль и d и записываем это в Vector4D

Если все 3 индекса == 0, это случай недопустимый, вываливаемся по assert. А вот 1 или 2 индекса могут быть нулевыми - ось(и) параллельны плоскости. Тогда cntr+axis не проходит, но мы можем добавить отрезок оси к уже имеющейся на плоскости точки - и получить новую.

Да, все это "аналитическая геометрия", курс первого семестра который традиционно считается легким (в теории).  По поводу остальных Ваших вопросов по векторам и др - общий ответ "да" и учите плюсы, по-другому не получится
Записан
Skrypnyk
Гость
« Ответ #10 : Март 18, 2013, 18:42 »

Получается вместо QVector <QVector4D> & plane при вызове функции Miller2Plane должно быть записано расстояние от начала координат до плоскости?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Март 18, 2013, 18:57 »

Получается вместо QVector <QVector4D> & plane при вызове функции Miller2Plane должно быть записано расстояние от начала координат до плоскости?
Что-то совсем мрачно  Плачущий Как Вы знаете, 3 индекса Миллера могут задавать любое число секущих плоскостей, поэтому ф-ция заполняет контейнер (вектор) каждый элемент которого QVector4D описывающий секущую плоскость: x, y, z есть нормаль к плоскости и w - расстояние
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #12 : Март 18, 2013, 20:07 »

Получается вместо QVector <QVector4D> & plane при вызове функции Miller2Plane должно быть записано расстояние от начала координат до плоскости?
Что-то совсем мрачно  Плачущий Как Вы знаете, 3 индекса Миллера могут задавать любое число секущих плоскостей, поэтому ф-ция заполняет контейнер (вектор) каждый элемент которого QVector4D описывающий секущую плоскость: x, y, z есть нормаль к плоскости и w - расстояние

А если вектора кристаллической решётки не ортогональны?  Подмигивающий
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Март 18, 2013, 21:07 »

А если вектора кристаллической решётки не ортогональны?  Подмигивающий
На здоровье - задавайте неортогональные axisX(Y, Z)
Записан
Skrypnyk
Гость
« Ответ #14 : Март 18, 2013, 23:22 »

Igors, тогда еще вопрос: -QVector3D::dotProduct(nor, vec[0]) - тоже получается расстояние в функции QVector4D(nor, -QVector3D::dotProduct(nor, vec[0]))?
И еще хочу поинтересоваться: в чем смысл трех вложенных циклов for? Я задаю столько вопросов, потому что не силен в программировании, а мне нужно знать какие процессы описываются приведенным Вами кодом. Я не сомневаюсь, что он дает результат. Но хочется узнать что он делает, чтобы получить конечный результат. Еще раз спасибо.
« Последнее редактирование: Март 19, 2013, 00:06 от Skrypnyk » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.123 секунд. Запросов: 23.