@tonline_kms65

Как создать цилиндрическую винтовую линию?

5f1755f0d29ed423713815.jpeg
Нужно создать винтовую линию в 3d пространстве.
У меня есть код создания винтовой линии:
float t = distance/100.0;                    // длина линии
    pos2[0] = StartPos[0];                       // начальная позиция StartPos(точка вокруг которой будет рисоваться окружность)
    pos2[1] = StartPos[1] + radius;
    pos2[2] = StartPos[2];

        while (angle <= PI*t){
            x = radius * Cosine(angle);
            y = radius * Sine(angle);

            pos1[0] = pos2[0] + t;
            pos1[1] = pos2[1] + x;
            pos1[2] = pos2[2] + y;

            Здесь функция рисования линии.........................

            pos2 = pos1;
            angle += PI/10.0; // количество сегментов окружности (PI/10  -  10 сегментов)
        }

Но этот код рисует линию только в одном направлении. Мне нужно что бы этот код мог рисовать линию в направлении нужного мне вектора, не могу придумать как это сделать. Я понимаю что нужно как то повернуть плоскость в которой рисуется линия.
  • Вопрос задан
  • 224 просмотра
Решения вопроса 1
Можно умножить получаемые координаты на нужную матрицу трансформации.
https://habr.com/ru/post/319144/ раздел "Матрица вращения"
Матрица считается один раз перед рисовкой, а потом все координаты спирали умножаются на неё.

Пример:
Есть у нас вектор, вокруг которого хотим повернуть всю спираль: (vx,vy,vz)
Есть угол, на который хотим повернуть: a

Тогда матрица поворота вокруг этого вектора выглядит так:
{
	{cos(a)+(1-cos(a))*vx*vx,     (1-cos(a))*vx*vy-sin(a)*vz,   (1-cos(a))*vx*vz+sin(a)*vy,  0},
	{(1-cos(a))*vy*vx+sin(a)*vz,  cos(a)+(1-cos(a))*vy*vy,     (1-cos(a))*vy*vz-sin(a)*vx,   0},
	{(1-cos(a))*vz*vx-sin(a)*vy,  (a-cos(a))*vz*vy+sin(a)*vx,  cos(a)+(1-cos(a))*vz*vz,      0},
	{0,                           0,                           0,                            1}
}


Чтобы упростить формулы, обозначу элементы матрицы через переменные a,b,c,d,e,f,g,h,i
a=cos(a)+(1-cos(a))*vx*vx
b=(1-cos(a))*vx*vy-sin(a)*vz
c=(1-cos(a))*vx*vz+sin(a)*vy
d=(1-cos(a))*vy*vx+sin(a)*vz
e=cos(a)+(1-cos(a))*vy*vy
f=(1-cos(a))*vy*vz-sin(a)*vx
g=(1-cos(a))*vz*vx-sin(a)*vy
h=(a-cos(a))*vz*vy+sin(a)*vx
i=cos(a)+(1-cos(a))*vz*vz


Получается уже не такая страшная матрица:
a, b, c, 0
d, e, f, 0
g, h, i, 0
0, 0, 0, 1

Чтобы повернуть любую точку (x,y,z), используя эту матрицу, достаточно перемножить координаты точки на матрицу, добавив еще единицу как четвертую координату.

5f1bd4d78ffe6921159705.gif

Перемножаем, получая новые координаты точки (x,y,z) (повернутые на заданный угол вокруг заданного вектора)

newx = a*x + b*y + c*z
newy = d*x + e*y + f*z
newz = g*x + h*y + i*z

Можете использовать эту формулу перемножения, вообще не думая о матрицах.
Просто подставляйте вместо букв a-i соответствующие куски тригонометрии, которые я выше написал.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@inFureal
Смотри, используешь формулу для спирали
espiral.png
И двигаешь по оси Z. Чем чаще ты вызовы, тем плотнее точки, соединяешь и рисуешь
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы