Разбираемся с технологией 3D программирования

Автор Kadet, 23 июня 2021, 09:16

0 Пользователи и 1 гость просматривают эту тему.

Kadet

Кое-что распознал, но пока не понял как это использовать:
Transformation
Line1
Column1 12040 - Width Размера
Column2 0 -
Column3 1719 - X Позиции
Line2
Column1 0 -
Column2 295 - Height Размера
Column3 3151 - Y Позиции
Line3
Column1 0 -
Column2 0 -
Column3 1 -


Чтобы было понятно "куда иду" и зачем мне сей "посох".
Случилась мне необходимость нарисовать куб и наклонить его на определённый угол. Нет, конечно я могу всё это нарисовать полигонами из 24 точек, но хочется найти способ попроще, из уже готового.
Поэтому беру фигуру "куб", вытягиваю его в горизонтальный параллелепипед и, с помощью метода RotateAngle, пытаюсь его наклонить. Фигура наклоняется, но при этом смещается.
Эмпирическим путём вычислил, что смещение и наклон выполняется относительно некоей фиксированной точки, которая как бы является центром окружности, по которой смещается вся эта фигура, и который, как ни странно, находится за пределами размеров этой фигуры (наверное пляшет от общих центровых координат всей сцены). Так как других вариантов не нашёл, предполагаю, что вышеописанная структура Transformation как раз и описывает местоположение этого центра.

Перед наклоном так же можно отцентровать эту фигуру, посредством метода - xShape3D.D3DPositionIsCenter = True, и тогда центр вращения смещается в точку, описанную в структуре Position, и тогда при наклоне фигура просто проворачивается относительно этого центра. Но, при этом и сама фигура тоже смещается, так, что координаты Position становятся не её началом (как это по-умолчанию), а центром. Т.е. - фигура просто сдвигается по X  и Y.

Вот и пытаюсь придумать, что проще - найти и сместить фиксированный центр, при помощи структуры, подобной Transformation, или заблаговременно сместить в нужное место координаты  Position, а потом отцентровать и наклонить?

Kadet

Протестировал второй вариант, со смещением и оцентровкой. Не получается. Всё равно идёт смещение.

mikekaganski

С уважением,
Михаил Каганский

Kadet

#33
Однако, не понятный парадокс.
Что бы я не делал, в итоге всё равно получаю смещение.
Центрирую и смещаю центр, наклоняю... Получаю смещение начала фигуры по X и Y.
Другой вариант - рисую фигуру без смещения по Y. Наклоняю. Смещения нет. Потом поднимаю её до нужной высоты по Y и уже там получаю смещение.

Где же собака порылась?
Почему же получается смещение по X при изменении одной координаты - Y?

Kadet

Цитата: mikekaganski от 16 июля 2021, 16:39Это просто матрица линейных преобразований 3x3.
Похоже. Вопрос-размышление, как её перекроить под собственные нужны?
Есть ещё подобная матрица 3D.
D3DTransformMatrix
Line1
Column1
Column2
Column3
Column4
Line2
Column1
Column2
Column3
Column4
Line3
Column1
Column2
Column3
Column4
Line4
Column1
Column2
Column3
Column4

Там цифирёк, тьма, и все в основном <1.

P.S. не проще ли нарисовать полигоном?!

Kadet

Таки решил эту задачу со всеми не известными.
Уверен, что есть более корректное и простое решение, но я сделал так.
В общем, корректирую позицию фигуры на величины смещения по X и Y. Вычисляю с помощью формул прямоугольного треугольника, вычисляя катеты из гипотенузы (она же радиус смещения и она же Ypoz) и известного угла смещения.
If TypeName(Rotate)<>"Error" Then
oSheet.getCellByPosition(0, 1008).setFormula("=SIN(A1008)")
oSheet.getCellByPosition(0, 1010).setFormula("=COS(A1010)")
oSheet.getCellByPosition(0, 1009).setValue(Rotate/5729.58)
Ys = Ypoz*oSheet.getCellByPosition(0, 1010).getValue()
oSheet.getCellByPosition(0, 1007).setValue(Rotate/5729.58)
Xs = Ypoz*oSheet.getCellByPosition(0, 1008).getValue()
aPosition3D.PositionX = Xpoz+Xs
aPosition3D.PositionY = Ypoz+(Ypoz-Ys)
aPosition3D.PositionZ = Zpoz
xShape3D.D3DPosition = aPosition3D
End If

Kadet

Засада какая-то. Проблема не решена.

Изменил размеры конструкции и получил (во вложении)

Kadet

#37
Кое-что для меня поясняется.
Дело в том, что метод RotateAngle это просто не наклон самой фигуры на определённый угол, а поворот всей плоскости координат ЭТОЙ фигуры, вместе с самой фигурой, на этот угол.
Поворот, почему-то поворачивает только плоскость осей Ox и Oy. Z, почему-то не участвует, а выступает как бы осью поворота.
Осью поворота является ось Z с координатами (0,0) по X и Y соответственно.

Т.е., что получается. Рисуем фигуру в общей системе координат (в сцене). Потом у этой фигуры наклоняем (проворачиваем) плоскость OxOy. И теперь какие бы координаты X, Y мы не вводили бы в эту фигуру они все будут смещены относительно общей системы координат на угол RotateAngle.
И для того, чтобы поставить фигуру со смещением в определённое место в общей системе координат (которая без смещения) нужно вычислять координаты обратного смещения. Т.е. - те координаты, которые после смещения должны попасть в нужные нам координаты общей системе координат. (Замудрёно, но думаю кому надо поймёт, что я пытаюсь выразить).
Попробую вычислить их с помощью вычисления координат точки на окружности: X = X0 + R*cos(ф) и Y = Y0 + R*sin(ф). Где X0 и Y0 - коодинаты точки (0,0), а R - позиция Y в которую нужно поставить начало фигуры/ D моём случает начальную координату фигуры нужно просто поднять вверх по Y, а X при это не меняется, т.е. X=0.
Пробую.

Kadet

#38
Получилось

Kadet

#39
И вот подстерегла меня очередная засада.
Случилась мне необходимость нарисовать в сцене цилиндры. Цилиндр создаётся как "объект вращения" (com.sun.star.drawing.Shape3DLatheObject - в буквальном переводе - "объект токарного станка").

Однако, у объектов вращения, как и у многих других 3D-моделей полигонального типа, нет методов D3DPosition и D3DSize, как в модели куба или сферы. Как выставить их местоположение и размер в сцене пока загадка. Мало того, у объектов вращения почему-то вообще не изменяются данные по координате Z в методе D3DPolyPolygon3D. А изменяя наборы координат X и Y в том же D3DPolyPolygon3D получается лишь растянуть или расширить форму цилиндра, сделать его шире/уже или выше/ниже. При этом центром оси вращения всегда остаётся координата (0,0,0), а вращение происходит по оси Oy.

Ищу выход из положения.

Kadet

Муторное дело, я вам доложу, рисовать цилиндр полигонами.
Надо таки расковырять и понять фигуры вращения.
Или буду рисовать всё кубами и сферами, хоть это и не правильно.

Kadet


Kadet

Совсем непонятное поведение фигуры при вращении сцены.

Вращаю посредством изменения геометрии камеры, изменяя координаты X и Z по формуле нахождения точки окружности: X=X0+cos(ф); Z=Z0+sin(ф)

mikekaganski

Не заглядывал в Ваш файл (у Вас обычно столько всего там, что не разберёшься), но хочу спросить: Вы используете матрицу преобразований? Самый правильный способ был бы для Вас создать несколько функций для создания матриц вращения, сдвига, масштабирования и т.п. и для перемножения матриц, затем создавать комбинированную матрицу (считать текущую матрицу из объекта, создать несколько дополнительных матриц, перемножить в нужном порядке), и наконец присвоить результат объекту.
С уважением,
Михаил Каганский

Kadet

Нет, матрицы не пересчитываю. Надеюсь на собственные "силы" LO. Он, как бы, предоставляет такие возможности.

К тому же, пока не пойму. У меня сцена состоит из десятков вложенных в неё моделей. Ведь матрицы пересчитывать нужно по каждому объекту.
Уже вижу, что рано или поздно придётся этим заняться. Но пока не представляю как это делать.