Векторная геометрия для разработчиков Revit API

|  Revit API

Класс XYZ представляет координаты в RevitAPI. А раз мы имеем дело с координатами, то следует рассмотреть азы векторной геометрии. Всего два действия: сложение и вычитание векторов, позволят сделать кучу полезной работы.

Для начала предлагаю ознакомиться со спецификацией класса XYZ здесь. Что такое векторы можно почитать в википедии.

Класс XYZ в RevitAPI в пространстве модели можно представить в виде вектора, начало которого находится в нулевой точке или базовой точке проекта (X =0, Y = 0, Z = 0), а конец вектора находится в точке, которую нам указывают координаты, например XYZ (-44.6464513504241, 82.7973662674829, 33.0782338854701). Все значения координат указываются в футах. Класс XYZ имеет методы, присущие векторам, которые ниже будут рассмотрены.

Рассмотрим векторы на примере линии детализации в Ревит. Базовую точку отметим как А. Тогда первая точка линии (с которой мы начали ее вести) будет В, завершающая точка линии будет С. Соответственно мы получим векторы АВ и ВС.

В Revit API предусмотрены методы для доступа к первой точке и последней точки линии.

Показать код C# →

Reference r = uiapp.ActiveUIDocument.Selection.PickObject(ObjectType.Element) Element line = doc.GetElement(r.ElementId);

XYZ vectorAB = (line.Location as LocationCurve).Curve.GetEndPoint(0);

XYZ vectorAC = (line.Location as LocationCurve).Curve.GetEndPoint(1);

TaskDialog.Show("Векторы", vectorAB.ToString() + "\n" + vectorAC);

Для работы с линией детализации как с вектором нам нужен вектор ВС. Для получения вектора линии детализации ВС используем вычитание векторов. ВС = АС - АВ.

Все просто, в данном выражении конец вектора АС будет будет концом вектора ВС (первое число в разности - конец). Конец вектора АВ будет началом вектора ВС (второе число в разности - начало).

Показать код C# →

XYZ vectorBC = vectorAC - vectorAB;

Теперь, имея вектор линии детализации, можно сделать много интересных вещей. К примеру можно построить копию линии, которая будет в два раза длиннее или найти середину линии детализации.

XYZ vectorBC_1 = vectorBC * (-2); // удлиняется в сторону точки B

XYZ vectorBC_2 = vectorBC * 2; // удлиняется в сторону точки С

XYZ vectorBC_05 = vectorBC * .5 // середина вектора ВС

// код создания линии Line

line = Line.CreateBound(vectorAB, vectorBC_2); // начальная и конечная точка, ведь класс XYZ - это координаты

doc.Create.NewDetailCurve(doc.ActiveView, line);

Далее рассмотрим сложение векторов.

Сложение векторов очень пригодится, если нужно разместить какой-либо объект на определенном расстоянии от уже известной точки. Для этого нужно будет воспользоваться координатами такой точки и нормализованным вектором (или единичным вектором). Нормализованный или единичный вектор - это вектор, длина которого равна единице. Подробнее читайте тут.

Построим дубликат линии, расположенной горизонтально вправо на расстоянии 2000 мм от существующей. Для этого сначала я отображу графически необходимый результат. Сначала найдем необходимые координаты по правилу параллелограмма. Координаты новой линии детализации определяется так:

AF = AC + СF; AD = AB + BD;

По правилу параллелограмма, вместо векторов CF и BD мы можем воспользоваться вектором AX, который очень просто вычисляется. Воспользуемся нормализованным вектором, который в наше распоряжение предоставляет Revit API - это XYZ.BasisX. Длина этого вектора равна единице, и он, как все базисные векторы, расположен в начале координат. Поэтому умножим его на 2000мм, не забывая перевести миллиметры в футы.

Показать код C# →

XYZ vectorAX = XYZ.BasisX * (2000 / 304.8); // Находим веторы AF и AD

XYZ vectorAF = vectorAC + vectorAX;

XYZ vectorAD = vectorAB + vectorAX;

Найденные векторы vectorAF и vectorAD являются точными координатами для построения новой линии детализации.

Посмотрим как можно, например удлинить нашу линию детализации на 1000 мм в сторону точки С или B.

Показать код C# →

// Удлиняем в сторону точки С XYZ directionToC = vectorBC.Normalize();

XYZ newC = vectorAC + (directionToC * (1000 / 304.8)); // Удлиняем в с сторону точки В

XYZ vectorCB = vectorAB - vectorAC;

XYZ directionToB = vectorCB.Normalize();

XYZ newB = vectorAB + (directionToB * (1000 / 304.8));

Пару слов о методе Normalize класса XYZ. Normalize возвращает нормализованный вектор BC или CB. То есть это вектор BC или CB, укороченный до длины равной 1 и помещенный в начало координат с сохранением направления.

Для увлекательного путешествия по трехмерному миру при разработке программ для Ревит нам нужна только опорная точка с известными координатами и указатель движения в виде нормализованного (единичного) вектора, и расстояние. Произведение указателя с расстоянием, и прибавленная к ним опорная точка дадут новые координаты. Пространство проекта в Ревит просто наполнено указателями, которые можно получать из многих элементов. Мы можем вычислять свои указатели как в примере выше.

Для комфортного путешествия по трехмерному миру нам нужно еще вооружиться знаниями о нормали к прямой или к поверхности и скалярным произведением векторов. Нужно получить информацию о пересечении прямых и, популярным в Ревит, частным случаем - пересечении отрезков.

Ниже можно посмотреть листинг макроса для Ревит, который сдвигает выбранную линию детализации на 2000мм вправо и удлиняет ее на 1000мм в обе стороны.

Показать код C# →

/*

;* Created by SharpDevelop.

* User: Akunets Aleksandr

* Date: 27.08.2017

* Time: 20:37

*

* To change this template use Tools | Options | Coding | Edit Standard Headers.

*/

using System;

using Autodesk.Revit.UI;

using Autodesk.Revit.DB;

using Autodesk.Revit.UI.Selection;

using System.Collections.Generic;

using System.Linq;

namespace Vector

{

[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]

[Autodesk.Revit.DB.Macros.AddInId("17333FA7-9C10-4B4E-A179-7B56E33FC6B3")]

public partial class ThisApplication

{

private void Module_Startup(object sender, EventArgs e)

{

}

private void Module_Shutdown(object sender, EventArgs e)

{

}

public void Vector()

{

UIDocument uidoc = this.ActiveUIDocument;

Document doc = uidoc.Document; //получаем документ

Selection selection = uidoc.Selection;

Reference r = selection.PickObject(ObjectType.Element, "Выделите линию детализации"); // получаем линию

Element line = doc.GetElement(r.ElementId); // получаем линию как элемент

XYZ vectorAB = (line.Location as LocationCurve).Curve.GetEndPoint(0); // получаем вектор к первой точке

XYZ vectorAC = (line.Location as LocationCurve).Curve.GetEndPoint(1); // получаем вектор ко второй точке

XYZ vectorBC = vectorAC - vectorAB; // получаем вектор, определяющий линию детализации

XYZ vectorAX = XYZ.BasisX * (2000 / 304.8); // получаем вектор сдвига на 2000мм вправо (от нулевой точки 2000мм вправо)

XYZ vectorAF = vectorAC + vectorAX; // получаем вектор (координаты) новой точки

XYZ vectorAD = vectorAB + vectorAX; // получаем вектор (координаты) новой точки

XYZ directionToC = vectorBC.Normalize(); // получаем направление (единичный вектор) в сторону точки С,

// и используем его для любых параллельных ему векторов

XYZ newC = vectorAF + (directionToC * (1000 / 304.8)); // получаем вектор (координаты) новой точки для новой линии

// Удлиняем в с сторону точки В

XYZ vectorCB = vectorAB - vectorAC; // получаем вектор, зеркальный вектору BC

XYZ directionToB = vectorCB.Normalize(); // получаем направление (единичный вектор) в сторону точки B,

// и используем его для любых параллельных ему векторов

XYZ newB = vectorAD + (directionToB * (1000 / 304.8)); // получаем вектор (координаты) новой точки для новой линии

Transaction t = new Transaction(doc, "Create Detail Line");

{

t.Start();

Line geomLine = Line.CreateBound(newB, newC);

DetailLine detailline = doc.Create.NewDetailCurve(doc.ActiveView, geomLine ) as DetailLine;

t.Commit();

}

}

private void InternalStartup()

{

this.Startup += new System.EventHandler(Module_Startup); this.Shutdown += new System.EventHandler(Module_Shutdown);

} } }

PS: Ознакомится с азами векторной алгебры вы можете в этой статье - Линейная алгебра для разработчиков игр.

Поддержите мои бесплатные приложения для Revit. Нажмайте "Нравится"!

Узнавайте о новых расширениях для Revit подписавшись на страницу BIM3D в Твиттере!

Извините за предствленные неудобства. Всплывающее окно больше не побеспокоит Вас!

Назад