Небольшая статейка о том, как сделать, чтобы при отзеркаливание параметрического объекта СПДС не зеркалился текст прописаный в геометрии объекта (UText)
Даже если вы создадите для объекта вид сзади, который будет зеркален виду спереди, текст в геометрии себя будет вести неадекватно
Неадекватное поведение текста на виде сзади
Во-первых, мы не будем создавать вид сзади. Мы заставим объект отзеркалиться обратно!
Что нам для этого надо:
Мой объект — Пример для отзеркаливания текста (пустышка).mcd
Вводим две переменные в объект:
rAngleX (назовём её «Угол X») и rAngleY (назовём её «Угол Y»)
Для переменной «Угол X» вычисляем угол между глобальной осью oY и вектором нашего объекта vecDirection
rAngleX = angleTwoPi(oY,vecDirection);
Для «Угол Y» вычисляем угол между осью oY и вектором нашего объекта vecPlane
rAngleY = angleTwoPi(oY,vecPlane);
Создаём функцию MirrorObject вначале нашего кода и прописываем там наши формулы
function MirrorObject
{
rAngleX = angleTwoPi(oY,vecDirection);
rAngleY = angleTwoPi(oY,vecPlane);
}
Прописываем нашу функцию в функциях OnInitialization, чтобы инициализировать при вставке объекта наши переменные, и в OnMakeParameters, что при обновление объекта с помощью команды SPREGENSTD наши параметры обновились (на видео я запускаю эту команду через кнопку)
Видео определения угла
Из видео видно, что если мы зеркалим объект по оси Y то
Угол X = 90
Угол Y = 0
А если по X, то
Угол X = 270
Угол Y = 180
Прописываем iff'ы, которые при определённых значения rAngleX и rAngleY будут разворачивать наш объект.
И загоняем их в нашу функцию MirrorObject.
Рассмотрим момент, когда мы зеркалим по оси Y.
Что происходит в этот момент с объектом?
У него меняется направления вектора vecDirection. Значит, чтобы отзеркалить объект обратно, нам надо для начала поменять направления вектора vecDirection!
пишем:
if(rAngleX==90 && rAngleY==0)
{
vecDirection = -vecDirection;
}
А при зеркале по оси X меняется направление vecPlane, как следствие:
if(rAngleX==270 && rAngleY==180)
{
vecPlane= -vecPlane;
}
Загоняем это в нашу функцию
function MirrorObject
{
rAngleX = angleTwoPi(oY,vecDirection);
rAngleY = angleTwoPi(oY,vecPlane);
if(rAngleX==90 && rAngleY==0)
{
vecDirection = -vecDirection;
}
if(rAngleX==270 && rAngleY==180)
{
vecPlane= -vecPlane;
}
}
Сохраняем объект и обновляем его на чертеже
О чудо, всё заработало!)
Но ещё рано радоваться, проверяем разные случаи и получаем:
Видео с проверкой
Логика та же, что и раньше, дописываем iff'ы исходя из угла)
function MirrorObject
{
rAngleY = angleTwoPi(oY,vecPlane);
rAngleX = angleTwoPi(oY,vecDirection);
if(rAngleX==90 && rAngleY==0)
{
vecDirection=-vecDirection;
}
if(rAngleX==270 && rAngleY==180)
{
vecPlane=-vecPlane;
}
if(rAngleX==0 && rAngleY==270)
{
vecDirection=-vecDirection;
}
if(rAngleX==180 && rAngleY==90)
{
vecPlane=-vecPlane;
}
}
Запись специально не упрощал, но вы можете, если хотите, объединить через «или» (||) часть кода)
Проверяем результат:
Проверяем результат
Текст не зеркалится, но крутится.
Чтобы решить эту проблему, надо ввести переменную, отвечающую за поворот текста.
В ActHeader в Public дописываем переменную
sTextAngle, "hidden"
Я её скрыл, потому что вручную менять не планирую, если хотите, можете оставить открытой.
А коде исполнения UText дополняем переменной нашего угла (и не забывем перевести градусы в радианы):
UText(mp, DegToRad(sTextAngle), 2.5*rSymScl/rScl, 0, 0.0000, T, 1,1);
Далее мы определяем в каких значения Угла X и Угла Y у нас текст повёрнут и выставляем для этого случая нужное нам значение sTextAngle, тем самым формирую итоговый вид нашей функции:
function MirrorObject
{
rAngleY = angleTwoPi(oY,vecPlane);
rAngleX = angleTwoPi(oY,vecDirection);
if(rAngleX==90 && rAngleY==0)
{
vecDirection=-vecDirection;
}
if(rAngleX==270 && rAngleY==180)
{
vecPlane=-vecPlane;
}
if(rAngleX==0 && rAngleY==270)
{
vecDirection=-vecDirection;
}
if(rAngleX==180 && rAngleY==90)
{
vecPlane=-vecPlane;
}
if(rAngleY==180 || rAngleY==270)
{
sTextAngle=180;
}
else
{
sTextAngle=0;
}
}
Сохраняем и обновляем наши объекты:
Сохраняем и обновляем объекты
Третий пункт нашей задачи нам не понадобился, так как точка вставки объекта находится по его центру.
Если же точка вставки объекта находилась у края объекта, то нам пришлось бы кроме отзеркаливания объекта обратно в коде, прописывать дополнительно смещения объекта.
Проведу часть такого кода из своего другого объекта, чтобы было понятна логика действия:
anY = angleTwoPi(oY,vecPlane);
anX = angleTwoPi(oY,vecDirection);
pnt1x = pntOrigin:x;
pnt1y = pntOrigin:y;
if (anX==180 && anY==90)
{
pntOrigin:x = pnt1x - L;
vecPlane=-vecPlane;
}
if (anX==90 && anY==0)
{
pntOrigin:x = pnt1x - B;
vecDirection=-vecDirection;
}
Примеры моих объектов, с применение данной логики для отзеркаливания:
Плита перекрытия (ПБ)
Монолитный участок (8 точек)
Отлично !!! Я бы не смог догадаться как сделать.
Спасибо!