Ответы пользователя по тегу 3D
  • Как построить модель цилиндрической волны?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Если достаточно приближенной модели, можно сделать так:
    r1=sqrt(x^2+y^2)
    a=A*p/sqrt(p^2+x^2+y^2)
    z=a*sin(k*r1-w*t)
    где p - размер области в окрестности нуля с насильственно ограниченной амплитудой,
    A - максимальная амплитуда (в нуле)
    k - пространственная частота (т.е. 2*pi/k - расстояние между волнами)
    w - временнАя частота (2*pi/w - период).
    w/k - скорость распространения.
    Ответ написан
    Комментировать
  • Зачем нужны однородные координаты?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    По большому счёту, однородные координаты нужны с единственной целью - чтобы при получении экранных координат точки не нужно было различать ортогональную и перспективную проекции. В остальных ситуациях их полная поддержка была бы только лишней тратой ресурсов.
    Сразу надо сказать, что матрицей 3*3 вы не обойдётесь. Такие матрицы описывают только поворот, а в перемещениях объекта и камеры в 3D есть ещё сдвиги. Поэтому нужна матрица, по меньшей мере, 3*4 (в конвенции компьютерной графики, когда вектор это строка а не столбец).
    В терминах линейной алгебры пользоваться такими матрицами неудобно, поэтому к ним добавляют столбец (0,0,0,1), а к координатам точки - четвёртую координату 1. Де-факто мы при этом получаем проективное пространство, представленное однородными координатами. Но при любых операциях над матрицами и точками у нас последний столбец всегда будет (0,0,0,1), а последняя координата точки - 1.
    Если знать это, то можно хорошо сэкономить: для хранения матрицы хватит 12 чисел вместо 16, для перемножения двух матриц - 36 умножений вместо 64, а для умножения матрицы на точку - 9 умножений вместо 16. Надеюсь, что в реальных проектах так и делают.
    Но есть одно место, где последний столбец не равен (0,0,0,1), и четвёртая координата точки может отличаться от 1 - это перспективная матрица для вывода на экран (ссылку вам уже дали). Для вывода точки (x,y,z) результат её применения может быть, условно, (x,y,z,1) - тогда имеет место ортогональная проекция, и выведется точка (x,y), а может - (x,y,-1,z) - тогда координаты точки окажутся (x/z,y/z), и проекция будет перспективной. Хватило бы одного бита - как интерпретировать точку, делить ли на z. Но разработчики компьютерной графики решили, что матрица 4*4 и однородные координаты - это более эффективно. Им виднее.
    Ответ написан
    1 комментарий
  • Как найти положение камеры по трем точкам в пространстве?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Непростая задача.
    Сначала по фотографии измеряете углы между лучами, а по модели - расстояния между точками. Потом обозначаете через x,y,z неизвестные расстояния от камеры до точек (длину каждого луча), и записываете уравнения из теоремы косинусов:
    x^2-2*a*x*y+y^2=P^2
    x^2-2*b*x*z+z^2=Q^2
    y^2-2*c*y*z+z^2=R^2
    Здесь a,b,c - косинусы углов между лучами, а P,Q,R - расстояния.
    Дальше надо решить эту систему. Теоретически, она сводится к уравнению 8-й степени от одной переменной z. MAPLE смог найти этот многочлен, он занимает чуть больше экрана. Не знаю, хороший ли это вариант - может быть, и да. Можно попытаться решить систему численно - перебрать разные стартовые значения x,y,z и искать корень методом Ньютона. Но учтите, что система плохая - у неё вполне могут найтись 4 близких корня с положительными x,y,z. А могут и не найтись - тогда будут локальные минимумы. Можно перебрать расстояние x с мелким шагом. Для каждого x найти два варианта y, два варианта z, подставить их в третье уравнение, и из самой лучшей тройки начать искать решение - можно методом Ньютона, но можно и делением отрезка пополам.
    После того, как x,y,z найдены, находите положение центра камеры - как точку пересечения трёх сфер. И дальше надо найти правильную ориентацию. Это довольно противно, но должно быть не очень сложно (по сравнению со всеми предыдущими шагами).
    Ответ написан
  • Как найти длину перпендикуляра с точки на отрезок?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    double L=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    double PR=(x-x1)*(x2-x1)+(y-y1)*(y2-y1);
    bool res=true;
    double cf=PR/L;
    if(cf<0){ cf=0; res=false; }
    if(cf>1){ cf=1; res=false; }
    double xres=x1+cf*(x2-x1);
    double yres=y1+cf*(y2-y1);

    В (xres,yres) будут координаты ближайшей точки отрезка, а переменная res покажет, перпендикуляр получился, или нет.
    Ответ написан
  • Почему именно синус?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    В этой задаче синус не нужен.

    double r=sqrt(x*x+y*y);
    double cf=1+10/r;
    double x1=x*cf,y1=y*cf;

    (x1,y1) - координаты искомой точки.
    Ответ написан
    3 комментария
  • Как построить 3D модель, используя плоскость и линию?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Соединяются точки, находящиеся либо на соседних строках матрицы на одном кадре, либо на одной и той же строке на соседних кадрах. В результате получается сетка из четырёхугольников. Их можно разделить на треугольники по более короткой диагонали.
    Если на какой-нибудь строке зелёной точки не найдётся - в модели будет дырка.
    Ответ написан
    4 комментария
  • По каким формулам вычислить новые координаты объекта в трёхмерном пространстве при относительном перемещении?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Сначала вам надо чётко определить, что такое "Углы поворота объекта по всем трём осям". Поскольку повороты не коммутируют, то задание поворота несколькими углами - это всегда последовательность поворотов относительно некоторых осей на определённый угол (или поворот вокруг одного вектора - но это уже кватернионное представление). Например, углы Эйлера - последовательность поворотов относительно OZ, OX и снова OZ.
    Если у вас объект получается из базового объекта последовательностью поворотов (OX,a), (OY,b), (OZ,c) (a,b,c - углы в радианах), и есть вектор (dx,dy,dz) в локальной системе координат повёрнутого объекта, то получить сдвиг объекта на этот вектор в глобальной системе координат можно так:
    dy1=cos(a)*dy+sin(a)*dz; dz1=-sin(a)*dy+cos(a)*dz; // поворот относительно OX
    dx1=cos(b)*dx-sin(b)*dz1; dz2=sin(b)*dx+cos(b)*dz1; // поворот относительно OY
    dx2=cos(c)*dx1+sin(c)*dy1; dy2=-sin(c)*dx1+cos(c)*dy1; // поворот относительно OZ
    Тогда (dx2,dy2,dz2) - искомый вектор сдвига.
    Если углы заданы в градусах, они переводятся в радианы умножением на pi/180.
    Общее правило: преобразование координат, которое использовалось для перемещения объекта из его базового состояния в текущее - это то же преобразование, которое используется для перевода координат из текущей локальной системы координат объекта в глобальную.
    Ответ написан
  • Что делать с кватернионом при смене базиса?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    У кватерниона изменится ось вращения (она отразится симметрично) и направление поворота. Таким образом, кватернион (x,y,z,w) перейдёт в (-x,y,z,-w).
    Ответ написан
  • Как подсчитать объем?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Достаточно для каждой грани
    vertex x1 y1 z1
    vertex x2 y2 z2
    vertex x3 y3 z3
    посчитать величину Vj=(x1*(y2*z3-y3*z2)+x2*(y3*z1-y1*z3)+x3*(y1*z2-y2*z1))/6, и найти сумму этих величин (часть из них будет отрицательной, но это не страшно). Для замкнутой модели она и будет искомым объёмом.

    Работать проще с бинарным STL - там не нужно тратить силы на синтаксический разбор.
    Ответ написан
    6 комментариев