Нижеследующая функция вычисляет координаты основания перпендикуляра, опущенного из точки на плоскость полигона.
Функция возвращает результат типа vector.
Аргументы функции:
a - тип vector, координаты точки полигона;
b - тип vector, координаты точки полигона;
c - тип vector, координаты точки полигона;
point - тип vector, координаты точки.
ppCross(a,b,c,point)
{ var normal;
var D,t,x1,y1,z1;
normal = vnorm(vcross(vector(b.x-a.x, b.y-a.y, b.z-a.z),
vector(c.x-a.x, c.y-a.y, c.z-a.z)));
D = -(normal.x*a.x + normal.y*a.y + normal.z*a.z);
t = -(normal.x*point.x + normal.y*point.y + normal.z*point.z + D)/
(normal.x*normal.x + normal.y*normal.y + normal.z*normal.z);
x1 = point.x + normal.x*t;
y1 = point.y + normal.y*t;
z1 = point.z + normal.z*t;
return vector(x1,y1,z1);
}
Пример использования:
Создаем полигон из четырех точек. Добавляем к нему 2 точки (они не присоединены ни к какому полигону). В результате получили 6 точек. Можно посмотреть их в Structure (Mode->Points).
Правой кнопкой мыши на нашем полигоне в Object Manager, New Expression->C.O.F.F.E.E. Expression.
В Expression Editor вводим следующее:
ppCross(a,b,c,point)
{ var normal;
var D,t,x1,y1,z1;
normal = vnorm(vcross(vector(b.x-a.x, b.y-a.y, b.z-a.z),
vector(c.x-a.x, c.y-a.y, c.z-a.z)));
D = -(normal.x*a.x + normal.y*a.y + normal.z*a.z);
t = -(normal.x*point.x + normal.y*point.y + normal.z*point.z + D)/
(normal.x*normal.x + normal.y*normal.y + normal.z*normal.z);
x1 = point.x + normal.x*t;
y1 = point.y + normal.y*t;
z1 = point.z + normal.z*t;
return vector(x1,y1,z1);
}
main(doc,op)
{ var p1,p2,p3,pp;
p1 = op->GetPoint(0);
p2 = op->GetPoint(1);
p3 = op->GetPoint(2);
pp = op->GetPoint(4);
op->SetPoint(5, ppCross(p1,p2,p3,pp));
op->Message(MSG_UPDATE);
}
Теперь если выделить точку 4 и перемещать ее в пространстве, то точка 5 будет занимать положение основания перпендикуляра, опущенного из точки 4 на плоскость полигона.
Да, у меня встречный вопрос. Каким образом можно узнавать, попала ли точка на полигон или нет?
Вот файл сцены: http://oxygen-c4d.mail333.com/pp for SOD.zip
В нем также двигаем точку, а вторая занимает положение основания перпендикуляра. При этом выводится сообщение, попала она на полигон или нет. Полигон, с которым работаем надо выделить.
Так вот для среднего ряда четырехугольных полигонов все работает правильно. А для ряда выше или ниже - нет. Для верхних и нижних треугольных полигонов все тоже работает верно.
Кому интересно, может посмотреть. Времени на поиск ошибки уже не осталось. Кто чего скажет?