В MultiCAD.NET используется метод менеджера объектов public static McObjectId SelectObject(string sPromt, ref Point3d pnt), как можно вставить объект используя угол наклона, выбранного объекта и точку вставки - точку в которой был произведен клик?
У объектов нет понятия “угла наклона”.
Есть матрица трансформации, и то, если объект её поддерживает.
Вообще, о каком типе объектов идёт речь, что вы хотите вставить?
Дана ось пути, состоящая из отрезков и дуг. Нужно вставить параметрический объект (опора) выбирая точку на оси пути. Объект необходимо вставлять перпендикулярно отрезку или касательной дуги в точке вставке. И еще McObjectId SelectObject(string sPromt, ref Point3d pnt) при выборе отрезка выдает точку, которая не находится на отрезке.
Для точного выбора точки на пути стоит пользоваться объектом InputJig. SelectObject не возвращает точку точно на объекте, это так и должно быть.
Для размещения объекта на пути с нужным сдвигом, поворотом используете метод Obj.DbEntity.Transfotm. И вот в передаваемой матрице можно заложить любые трансформации объекта в пространстве.
Где можно найти описание данного метода и пример использования?
Вам надо подготовить матрицу трансформации объекта.
Для сдвига используем метод: Matrix3d.MakeTranslation
Для поворота: Matrix3d.Rotation
Действия можно объединять в одну матрицу. Например, чтобы повернуть и сдвинуть, надо сначала сделать матрицу поворота, потом домножить её СЛЕВА на матрицу сдвига. И потом позвать Transform на объекте. Он и повернётся и подвинется.
Пояснение: из-за того, что в Autodesk (Автокад) матричные операции используют транспонированные матрицы, то для формирования общей матрицы последующее действие нужно домножать слева. Нанокад, ZWCAD, BricsCad вынуждены повторять такое поведение. Я без понятия, кто так там решил и зачем. Но это вот такая “реальность, данная нам в ощущениях”
В API есть метаданные, к каждому методу есть описание. + рекомендую почитать про матричные преобразования. Википедия или еще какой ресурс..
Вот что получилось
if (dbObj is ParametricEntity entity)// если объект параметрический
{
//создаем переменные угла и точки,
(double Angle, NativePlatform.Geometry.Point3d Point) = GetPointAndAngle();
// создаем матрицу поворота
NativePlatform.Geometry.Matrix3d rotationMatrix = NativePlatform.Geometry.Matrix3d.Rotation(
Angle + Math.PI/2, // угол берем из функции и прибавляем 90 градусов
NativePlatform.Geometry.Vector3d.ZAxis,
Point
);
//создаем вектор перемещения
NativePlatform.Geometry.Vector3d displacementVector = new NativePlatform.Geometry.Vector3d(Point[0], Point[1],Point[2]);
// создаем матрицу перемещения
NativePlatform.Geometry.Matrix3d translationMatrix = NativePlatform.Geometry.Matrix3d.Displacement(displacementVector);
// объединяем матрицы умножением
NativePlatform.Geometry.Matrix3d combinedMatrix = rotationMatrix * translationMatrix;
// Применяем поворот и перемещение к объекту
entity.TransformBy(combinedMatrix);
tr.Commit();//обновляем транзакцию
не получалось точку Point3d перевести в вектор Vector3d, пришлось переводить по индексам, а есть способ сделать это проще?
Как можно у существующего параметрического объекта узнать угол поворота на чертеже?
Ваш пример кода - это не MultiCAD API, хотя изначально про него речь шла.
Но принцип примерно правильный. Из точки вектор получить можно методом Point3d.GetAsVector. Но это у нас в Мильтикде. За API платформы я не ручаюсь.
В общем случае никак.
Потому как поворот - это действие, для которого нужно знать положение оси поворота в пространстве. Если вы её не знаете, задача не решается. Если знаете, то это можно вычислить. Но зачем.. Обычно это не нужно. Если вы оперируете матрицей вставки объекта, то никакие “углы”, “сдвиги” не нужны. Есть матрица трансформации, она в себе всё содержит.
Вот с этой точки зрения нужно смотреть на вопрос размещения объектов в чертеже.
Если такой случай. Нужно вставить в чертеж объект привязываясь к существующему объекту на чертеже, допустим вставить объект в точку вставки существующего объекта и повернуть его на 90 градусов относительно существующего объекта. Для этого нужно знать точку вставки существующего объекта и его угол (Angle).
а еще вопрос. как считать значение параметра из параметрического объекта. В SDK много примеров как создать параметр, а как считать я не нашел. Параметр, как я предполагаю считается как string, как его перевести, допустим в double?
так и я могу )))
просто у меня в этой строке
//double Gabarit = double.Parse(Obj2.GetElementData().GetParameter(“KS_OP_GABARIT”).Value);
возникает исключение, возможно есть какой-нибудь безопасный способ получения из параметра тип которого string значения double
конечно, как вариант
Хотелось получить описание и пример процедуры bool GetParameterValue(String^ sName, double% dVal); - Процедура получения значения параметра, если он дробного (double) типа, из справки SDK
насухую, нет у меня бима
double val;
if(Obj2.GetElementData().GetParameterValue(“KS_OP_GABARIT”, val))
{
return val;
}
else
{
throw new ArgumentException();
}
Угол знать не надо. Просто формируете матрицу поворота на нужный угол вокруг нужной оси. Матрица просто довернёт объект.
Точка вставки параметрического объекта: McParametricObject.Origin
Направление оси поворота относительно его плоскости размещения: ParamObj.Direction.CrossProduct(ParamObj.PlaneVector)
Про параметры не понимаю. С каким типом объектов вы работаете?
Если вопрос не про Мультикад API, я откланиваюсь.
Вот пример из SDK где происходит создание параметрического объекта и вставка параметров в него.
var entity = ParametricEntityFactory.Create();
// Параметры для объекта - длина, ширина и высота. Использованы стандартные имена параметров для которых есть определения.
// Тем не менее можно было использовать собственные имена параметров.
entity.GetElementData().AddParameter(“DIM_WIDTH”).Value = “1000”;
entity.GetElementData().AddParameter(“DIM_HEIGHT”).Value = “1000”;
entity.GetElementData().AddParameter(“DIM_LENGTH”).Value = “1000”;
Хотелось бы понять как считывать параметры из существующего объекта.