Как интерполировать в AutoCad

Обновлено: 21.11.2024

Целью этого приложения является интеграция конкретной базы данных для тех 3D-моделей, которые по тем или иным причинам дают низкую производительность. Приложение адресовано профессионалам, которым при разработке своих проектов необходима точная проработка и подробная 3-D модель месторождения

Платформа — AUTOCAD.

Приложение включает два разных метода интерполяции:

  • Линейная интерполяция между трехмерными точками
  • Интерполяция между средневзвешенными трехмерными точками

Линейная интерполяция между трехмерными точками

В этом случае используется классический метод линейной интерполяции между двумя трехмерными точками

  • z x = значение точки линейной интерполяции
  • i = наклон между двумя точками (относится к линейной интерполяции)
  • d = расстояние между двумя точками, затронутыми линейной интерполяцией.
  • Zn = значение точки линейной интерполяции
  • Zx 1 = это значение высоты первой известной точки для интерполяции
  • Zx 2 = это значение высоты второй известной точки для интерполяции
  • Dx 2 Dx 1 = это расстояние между двумя точками, затронутыми линейной интерполяцией
  • Dx 1 Dx 1 = это расстояние между первой точкой линейной интерполяции и самой собой (всегда равно нулю)
  • Dx 1 Dxn = это расстояние между первой точкой, затронутой линейной интерполяцией, и точкой интерполяции

Интерполяция между средневзвешенными трехмерными точками

В этом случае будет применяться уравнение для расчета средневзвешенного значения точки.

  • z x = значение интерполированной точки
  • n = количество точек, выбранных для интерполяции (значение радиуса — это область выбора)
  • z = высота точек внутри радиуса выделения (все точки, затронутые интерполяцией)
  • d = расстояние между точкой пересечения и точками интерполяции.
  • k = кригинговое значение интерполяции

Блог для разработчиков, использующих платформы Autodesk, особенно AutoCAD и Forge. Особое внимание уделяется AR/VR и IoT.

02 марта 2009 г.

Еще раз спасибо Фентону Уэббу за предоставление кода для первого сообщения в серии и Джереми Таммику за предложение этой альтернативной реализации.

Этот пост является продолжением предыдущего поста, в котором представлена ​​техника плавного перехода между 3D-видами в AutoCAD. Он применяет более стандартный алгоритм, известный как сферическая линейная интерполяция (или Slerp для его друзей :-), для интерполяции между представлениями, а не для интерполяции отдельных значений с использованием специальной функции CosInterp() Фентона. Мы по-прежнему используем CosInterp() для интерполяции ширины и высоты поля зрения, но в остальном приведенный ниже код использует Slerp для точек и векторов, которые необходимо настроить.

общедоступный класс MyView

публичная позиция Point3d;

общедоступная цель Point3d;

общедоступный Vector3d upVector;

открытое двойное полеWidth;

открытое двойное полеHeight;

// Для постоянных определений ниже SWIso и т. д.

двойной x1, двойной y1, двойной z1

двойной x2, двойной y2, двойной z2

двойной x3, двойной y3, двойной z3

двойной x4, двойной y4

позиция = новый Point3d (x1, y1, z1);

цель = новый Point3d (x2, y2, z2);

upVector = новый Vector3d (x3, y3, z3);

Позиция Point3d, Цель Point3d, Vector3d upVector,

двойная ширина поля, двойная высота поля

это .position = position;

это .target = target;

это .upVector = upVector;

это .fieldWidth = fieldWidth;

это .fieldHeight = fieldHeight;

Команды общедоступного класса

статический MyView defaultView =

0,0,1,0,0,0, 3279,8, 1702,6

статический MyView topView =

0.0,1.0,0.0, 474.0, 246.0

статический MyView, нижний вид =

0.0,1.0,0.0, 474.0, 246.0

статический MyView leftView =

0,0,0,0,1,0, 256,5, 133,2

статический MyView rightView =

0,0,0,0,1,0, 256,5, 133,2

статический MyView SWIso =

0,4,0,4,0,8, 739,7, 384,0

статический MyView SEISo =

-0,4,0,4,0,8, 739,7, 384,0

статический MyView NEISo =

-0,4,-0,4,0,8, 739,7, 384,0

статический MyView NWIso =

1003,9, 1882,3, 840,2, 1576,8, 1309,5,

267,3, 0,4, -0,4, 0,8, 739,7, 384,0

// Осуществляет плавный переход от текущего вида к другому

// новый вид с использованием сферической линейной интерполяции (Slerp)

статический Matrix3d ​​SmoothViewToSlerp(

MyView nv, двойной timeToTake

Matrix3d ​​newViewMatrix = Matrix3d ​​.Identity;

// Получить текущую область просмотра

Приложение .GetSystemVariable("CVPORT")

Вид вида = gsm.GetGsView(vpn, true);

// Устанавливаем стандартную частоту кадров для глаза

Matrix3d ​​viewMatrix = view.ViewingMatrix;

// Получаем текущие настройки просмотра

view.Position, view.Target, view.UpVector,

// Устанавливаем начальные позиции

Point3d intPos = cv.position;

Point3d intTgt = cv.target;

Vector3d intUpVec = cv.upVector;

двойной intWid = cv.fieldWidth;

двойной intHgt = cv.fieldHeight;

// Теперь анимируем смену представления между

// currentview и viewToChangeTo

для (поплавок мю = 0; мю

// Сначала преобразуем позиции в векторы

// (чтобы мы могли просто вызвать существующую функцию)

Vector3d startPos = cv.position - Point3d .Origin,

endPos = nv.position - Point3d .Origin,

// Затем получаем относительные целевые векторы

// в позицию просмотра

от = cv.target - cv.position,

to = nv.target - nv.position,

// Теперь просканируем различные векторы

res1 = Slerp(startPos, endPos, mu),

res2 = Slerp(от, до, мю),

res3 = Slerp(cv.upVector, nv.upVector, мю);

// Затем мы извлекаем соответствующую информацию.

// Получаем точку из вектора положения

intPos = Point3d .Origin + res1;

// Получить целевую точку относительно этой позиции

intTgt = intPos + res2;

// А ап-вектор это просто :-)

// Используем нашу предыдущую функцию интерполяции

// для ширины и высоты поля

CosInterp(cv.fieldWidth, nv.fieldWidth, мю);

CosInterp(cv.fieldHeight, nv.fieldHeight, мю);

// Теперь устанавливаем интерполированный вид

view.SetView(intPos, intTgt, intUpVec, intWid, intHgt);

// Обновляем элемент управления

// Уменьшаем время ожидания, а точнее увеличиваем

// скорость изменения вида по мере работы

double sleepTime = timeToTake - (mu * 10);

Thread .Sleep(( int )(sleepTime > 50 ? 0 : sleepTime));

// Наконец устанавливаем новый вид

gsm.SetViewportFromView(vpn, view, true , true , false );

Система.Windows.Forms. Приложение .DoEvents();

static double CosInterp( double y1, double y2, double mu)

mu2 = (1- Math .Cos(mu* Math .PI))/2;

// Сферическая линейная интерполяция

static Vector3d Slerp( Vector3d from, Vector3d to, float step)

если (от == до || шаг == 1)

// Нормализуем векторы

Vector3d unitfrom = from.GetNormal(),

// Вычисляем прилежащий угол

// Избегаем повторного вычисления синуса

// Возвращаем геометрическую сферическую линейную интерполяцию

от * ( Math .Sin((1 - step) * theta) / st) +

к * Math .Sin(шаг * theta) / st;

// Функция для создания однородного сплошного фона

// цвет фона нашего 2D-пространства модели

// (уменьшает зрительный шок, как это сделал бы цвет

// иначе переключаемся на серый и обратно)

частный статический ObjectId CreateBackground()

постоянная строка bgKey = "TTIF_BG" ;

ObjectId vtId = ObjectId .Null;

// Получаем номер текущего окна просмотра

Приложение .GetSystemVariable("CVPORT")

// Нет необходимости устанавливать фон, если соответствующий

// 3D-вид уже существует

Идентификатор объекта bgId = ObjectId .Null;

// Получить или создать наш фоновый словарь

Фон .GetBackgroundDictionaryId(db, true);

// Если нашего фона не существует.

// Получаем цвет фона 2D-пространства модели

( AcadPreferences ) Приложение .Preferences;

// Создаем фон с соответствующим RGB

SolidBackground sb = новый SolidBackground();

новый Autodesk.AutoCAD.Colors. Цвет сущности (

(байт)(rawCol & 0x000000FF),

(байт)((rawCol & 0x0000FF00) >> 8),

(байт)((rawCol & 0x00FF0000) >> 16)

// Добавляем в фоновый словарь

bgId = bgd.SetAt(bgKey, sb);

// Устанавливаем фон на активном видовом экране пространства модели

foreach (идентификатор ObjectId в vt)

if (vtr.Name == "*Active")

private static void RemoveBackground( ObjectId vtId)

// Открываем ранее измененное окно просмотра

// И устанавливаем свой предыдущий фон

static public void TransitionViewSlerp()

Идентификатор объекта vtId = CreateBackground();

если (vtId != ObjectId .Null)

Что особенно примечательно в этой реализации, так это насколько она похожа на предыдущую. Фентон придумал довольно хороший метод интерполяции, не зная о Slerp, который дает очень похожие - возможно, идентичные, хотя я их не проверял - результаты. Очень круто.

Со своей стороны, я ничего не слышал о Slerp и имел лишь смутное представление о том, что такое кватернион — даже сейчас я бы не узнал кватернион, если бы он укусил меня за нос, так что хорошо, что статья в википедии содержит геометрическую альтернативу кватернионной формуле Слерпа.

Так зачем использовать один метод вместо другого? Есть несколько возможных отличий, которые могут иметь значение для людей.

Во-первых, существует вероятность того, что реализация Slerp более эффективна. Нам нужно меньше вызовов Slerp(), чем мы использовали для CosInterp(), просто потому, что мы интерполируем несколько значений одновременно. Но это вряд ли будет заметной разницей в любом реальном приложении, так что меня это в любом случае не должно беспокоить.

Все это говорит о том, что две версии кода во многом одинаковы, если все сказано и сделано. Я предоставил как в основном в целях интеллектуального любопытства, так и в случае, если показанные методы имеют отношение к другим сценариям.

Сплайновые объекты — это линейные или площадные объекты (в зависимости от того, замкнуты они или нет) и используются для представления объектов с плавными кривыми. Каждый сплайн имеет ряд атрибутов, которые полностью составляют сплайн. Когда параметр считывателя «Сохранить определения сплайна» включен, считыватель устанавливает координаты либо в качестве точек соответствия, либо в качестве контрольных точек (в зависимости от того, что используется для определения сплайна).

Сплайны всегда являются трехмерными — в AutoCAD нет способа указать, предназначен ли элемент только для двухмерного изображения. Если параметр считывателя «Сохранить определения сплайна» включен, координаты сплайна, возвращаемые считывателем, являются интерполированными значениями на основе определения сплайна.

Совет. Для преобразования AutoCAD в AutoCAD всегда следует включать параметр "Сохранить определения сплайнов", чтобы получить наилучшие результаты.

Сплайны AutoCAD имеют несколько атрибутов, которые возвращаются при чтении и должны быть указаны при записи.

Допуск контрольных точек.

Вес контрольной точки. Разделенный запятыми список значений веса для каждой управляющей вершины.

Списки, разделенные запятыми, представляющие координаты контрольных точек сплайна. В каждом списке должно быть ровно n записей, где n – значение autocad_num_cntl_pts .

Если включен параметр чтения "Сохранить определения сплайнов", контрольные точки также сохраняются как координаты.

Степень полинома, используемого для формирования сплайна.

Степень сплайна.

Допуск точек соответствия.

Списки, разделенные запятыми, представляющие координаты точек соответствия сплайна типа точки соответствия.

В каждом списке должно быть ровно n записей, где n — значение autocad_num_fit_pts .

Флаг, указывающий тип сплайна.

Это битовый вектор, обычно используемый только при переводе из AutoCAD в AutoCAD.

Метод вычисления, используемый для определения кривизны сплайна между точками соответствия для сплайнов типа точки соответствия.

Диапазон: аккорд | квадратный аккорд | униформа | обычай

Допуск сплайновых узлов.

Допуск сучков.

Количество контрольных точек.

Количество точек соответствия.

Количество узлов.

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

Диапазон: подходит | control_vertices

Вектор, представляющий начальный тангенс для сплайнов с заданной точкой.

При записи в сплайны сплайн должен быть указан точно так же, как он возвращается из считывателя, когда включен параметр считывателя «Сохранить определения сплайнов»:

AutoCAD позволяет хранить объекты SPLINE в файлах DXF, определяемые только подходящими точками, проблема в том, что такое определение сплайна имеет бесконечное число правильных решений, и Autodesk не предоставляет необходимой информации для расчета требуемых параметров из заданного соответствия. баллы.

tl;dr - Отсутствующая информация - это предполагаемые начальные и конечные касательные в направлении и величине для входных касательных к глобальной интерполяции B-сплайна с конечными производными, может ли кто-нибудь помочь рассчитать эти значения?

Я использую BricsCAD для тестирования, но "Trueview 2020" показывает те же результаты.

1. Сценарий

Даны только точки соответствия с использованием интерполяции глобальной кривой без каких-либо ограничений для получения сплайна, определяемого контрольными вершинами:

Сплайн, интерполированный BricsCAD из соответствующих точек, не соответствует сплайну, определенному интерполированными контрольными вершинами:

2. Сценарий

Помимо точек соответствия я сохраняю также значения начального и конечного касательных в файле DXF.Интерполяция выполняется интерполяцией глобальной кривой с конечными производными (Piegl & Tiller: "The NURBS Book" - глава 9.2.2).

Я выбрал произвольный угол (100 градусов) в качестве начальной и конечной касательной, величина касательной оценивается методом "Общая длина хорды".

Сплайн, интерполированный BricsCAD, теперь точно соответствует сплайну, определенному интерполированными контрольными вершинами:

Теперь я знаю, что метод интерполяции верен, и все, что мне нужно для визуализации того же сплайна из точек соответствия, что и в BricsCAD, — это конечные касательные в направлении и величине, полученные из точек соответствия.

3. Сценарий

Мне нужны управляющие вершины для визуализации B-сплайна, но начальные и конечные касательные не сохраняются в файле DXF, как в сценарии 1. Требуется оценка начальных и конечных касательных, лучший результат: "5 Point Интерполяция» из «Книги NURBS», Piegl & Tiller

И удивительно, что оценки неверны, сплайн BricsCAD имеет углы касания 101,0035408517495 и -101,0035408517495 градусов.

И действительно раздражает то, что если я использую углы BricsCAD в качестве входных данных, сплайны все равно не совпадают, поэтому я предположил, что оценка величины касательной отличается от сценария 2.

4. Проверка теории

Следующие значения рассчитываются из файла DXF, сохраненного BricsCAD, и SPLINE «Метод» переключен с «подходящих точек» на «контрольные вершины». Из этих данных я рассчитал касательные углы, а также величины, касательный вектор = 2-я контрольная вершина - 1-я контрольная вершина

Теперь сплайны снова совпадают:

  1. Если заданы касательные (сохраненные в формате DXF), величина входных касательных для функции интерполяции равна "общей длине хорды".
  2. Без заданных касательных величина отличается, в этом примере: m1*1.3097943444804256 , но это не постоянный коэффициент.

Большой вопрос: как оценить начальные и конечные касательные по направлению и величине, как в AutoCAD или BricsCAD, для сплайнов, определяемых только подходящими точками?

Заранее спасибо,

Время от времени мне приходилось ломать голову над тем, как AutoCAD вычисляет некоторые их значения, например дуги и эллипсы. Это вне моей лиги. Похоже, Math.SE может немного прижиться. Пробовали ли вы и там?

2 ответа 2

Объект SPLINE может иметь необязательные групповые коды 12,22,32 для начальной касательной x,y,z и 13,23,33 для конечной касательной x,y,z. Я проверил исходный код проекта netDxf, и из этого следует, что если для определения сплайна используются только точки соответствия, то должны быть указаны начальные и конечные значения касательной.

Из справочника AutoCAD 2012 DXF для объекта SPLINE:

12 Начальная касательная — может быть опущена (в WCS) DXF: значение X; APP: 3D-точка

22, 32 DXF: значения Y и Z начальной касательной — могут быть опущены (в WCS)

13 Конечная касательная — может быть опущена (в WCS) DXF : значение X; APP: 3D-точка

23, 33 DXF: значения Y и Z конечной касательной — могут быть опущены (в WCS)

Вчера мы с моим коллегой создали несколько файлов DXF в Autocad 2020, включая сплайны с заданными точками. После экспорта в DXF сплайны определялись контрольными точками и узлами. Так что у меня есть предположение, что точки соответствия — это что-то устаревшее или предназначенное только для пользовательского интерфейса.

Спасибо! Но причиной этого вопроса было воссоздание того же сплайна, что и в AutoCAD или BricsCAD, если конечные касательные не заданы/не указаны. Задача решена для случая заданных концевых касательных. У вас будет та же проблема, если вы получите файлы DXF из других источников, а не из AutoCAD (например, от пользователей ezdxf ;-), и СПЛАЙН, определяемый только точками соответствия без конечных касательных, является допустимой конструкцией DXF.

Третий сценарий кажется решенным: объекты SPLINE из соответствующих точек без заданных конечных касательных.

Применение кубической интерполяции кривой Безье кажется решением:

Нет визуальной разницы между BricsCAD/AutoCAD и ezdxf SPLINE.

Это работает только для кубических B-сплайнов (наиболее часто используемых B-сплайнов), а BricsCAD/AutoCAD допускает только степень 2 или 3 для объектов SPLINE, определяемых только точками соответствия. Не хватает только интерполяции квадратичных B-сплайнов как квадратичных кривых Безье.

Дальнейшие исследования показали, что квадратичные B-сплайны, определяемые точками соответствия, загружаются в BricsCAD/AutoCAD как кубические B-сплайны. Дополнение к заявлению выше:

BricsCAD и AutoCAD используют только степень 3 для объектов SPLINE, определяемых только точками соответствия.

Решением для B-сплайна без заданных конечных касательных является кубическая интерполяция Безье, вычисление конечного касания не требуется.

ОБНОВЛЕНИЕ: не решение

К сожалению, все это работает только для небольших простых B-сплайнов:

  • желтый: SPLINE by BricsCAD
  • голубой: интерполяция кривой Безье
  • пурпурный: глобальная интерполяция кривой

Интерполяция глобальной кривой — гораздо лучшее решение, чем интерполяция кривой Безье. Он расходится только в начале B-сплайна, где интерполяция кривой Безье полностью не работает.

Читайте также: