2013-09-20 4 views
1

У меня есть уравнение плоскости, описывающее точки, принадлежащие плоскости в 3D, и начало нормальных X, Y, Z. Этого должно быть достаточно, чтобы иметь возможность генерировать что-то вроде трехмерная стрелка. В pcl это возможно через зрителя, но я хотел бы фактически сохранить эти 3D-точки внутри облака. Как их сгенерировать? Цилиндр с конусом сверху?Как нарисовать нормаль к плоскости в PCL

ответ

1

Чтобы создать линию, перпендикулярную к плоскости:

У вас есть уравнение плоскости. Это дает вам направление нормали к плоскости. Если вы использовали PCL для получения плоскости, это в ModelCoefficients. Смотрите подробность здесь: SampleConsensusModelPerpendicularPlane

Первого шаг должны сделать линию перпендикулярно к нормали в точке, где вы упоминаете (X, Y, Z). Пусть (NORMAL_X, NORMAL_Y, NORMAL_Z) будет нормальным, что вы получили от уравнения вашей плоскости. Что-то вроде.

pcl::PointXYZ pnt_on_line; 
for(double distfromstart=0.0;distfromstart<LINE_LENGTH;distfromstart+=DISTANCE_INCREMENT){ 
    pnt_on_line.x = X + distfromstart*NORMAL_X; 
    pnt_on_line.y = Y + distfromstart*NORMAL_Y; 
    pnt_on_line.z = Z + distfromstart*NORMAL_Z; 
    my_cloud.points.push_back(pnt_on_line); 
} 

Теперь вы хотите, чтобы положить шляпу на свою стрелку и теперь pnt_on_line содержит конец строки, где вы хотите поместить его. Чтобы сделать конус, вы можете зацикливаться на угол и расстояние по стрелке, вычислить локальные x и y и z из этого и преобразовать их в точки в облаке облаков точек: часть z будет преобразована в систему координат вашего облака точек путем умножения с нормальным вектором, как и выше, x и y будут умножаться на векторы, перпендикулярные этому нормальному вектору E. Чтобы получить их, выберите произвольный единичный вектор, перпендикулярный нормальному вектору (для вашей оси x), и перекрестите его с нормальным вектором, чтобы найти ось y.

Вторая часть этого объяснения довольно короткая, но первая часть может быть более важной.

Update

Так, возможно, лучший способ описать, как сделать конус, чтобы начать с цилиндром, который является продолжением линии, описанной выше. В случае линии существует (часть) одномерное многообразие, вложенное в трехмерное пространство. То есть у нас есть одна переменная, которую мы зацикливаем на добавление точек. Цилиндр представляет собой двумерный объект, поэтому мы должны зацикливаться на двух измерениях: угол и расстояние. В случае линии у нас уже есть расстояние. Таким образом, вышеуказанный цикл будет выглядеть так:

for(double distfromstart=0.0;distfromstart<LINE_LENGTH;distfromstart+=DISTANCE_INCREMENT){ 
    for(double angle=0.0;angle<2*M_PI;angle+=M_PI/8){ 
     //calculate coordinates of point and add to cloud 
    } 
} 

Теперь для того, чтобы вычислить координаты новой точки, а у нас уже есть точки на линии, теперь мы просто нужно добавить его к вектору двигаться это от линии в соответствующем направлении угла. Скажем, радиус нашего цилиндра будет равным 0,1, и, скажем, ортонормированный базис, который мы уже рассчитали перпендикулярно нормали плоскости (который мы увидим, как рассчитать позже), равен perpendicular_1 и perpendicular_2 (т. Е. Два вектора перпендикулярны друг с другом, длины 1, а также перпендикулярно вектору (NORMAL_X, NORMAL_Y, NORMAL_Z)):

//calculate coordinates of point and add to cloud 
pnt_on_cylinder.x = pnt_on_line.x + 0.1 * perpendicular_1.x * 0.1 * cos(angle) + perpendicular_2.x * sin(angle) 
pnt_on_cylinder.y = pnt_on_line.y + perpendicular_1.y * 0.1 * cos(angle) + perpendicular_2.y * 0.1 * sin(angle) 
pnt_on_cylinder.z = pnt_on_line.z + perpendicular_1.z * 0.1 * cos(angle) + perpendicular_2.z * 0.1 * sin(angle) 
my_cloud.points.push_back(pnt_on_cylinder); 

на самом деле, это вектор суммирования и если мы должны были написать работу в качестве векторов это будет выглядеть :

pnt_on_line+perpendicular_1*cos(angle)+perpendicular_2*sin(angle) 

Теперь я сказал, что буду говорить о том, как рассчитать perpendicular_1 и perpendicular_2. Пусть K - любой единичный вектор, который не параллелен (NORMAL_X, NORMAL_Y, NORMAL_Z) (это можно найти, попробовав, например,(1,0,0) затем (0,1,0)).

Тогда

perpendicular_1 = K X (NORMAL_X,NORMAL_Y,NORMAL_Z) 
perpendicular_2 = perpendicular_1 X (NORMAL_X,NORMAL_Y,NORMAL_Z) 

Здесь X вектор перекрестное произведение и выше являются векторными. Заметим также, что исходный расчет pnt_on_line включал вектор dot product и векторное суммирование (я просто пишу это для полноты экспозиции).

Если вы можете справиться с этим, то конус легко просто изменить пару вещей в двойном цикле: радиус просто изменяется вдоль его длины, пока он не станет нулевым в конце цикла, и в цикле distfromstart не будет начинаются с 0.

+0

спасибо! – valentin

+0

было бы возможно, что можно немного расширить часть генерации конуса ... любая помощь приветствуется – valentin

+0

Здравствуйте, если вы сообщите мне, что у вас есть, я, вероятно, смогу помочь в правильном направлении. Я добавлю немного больше, хотя скоро в области, я думаю, может быть полезно, если позволит время. –

Смежные вопросы