Текстовый формат GNU Octave

Материал из Xgu.ru

Перейти к: навигация, поиск
stub.png
Данная страница находится в разработке.
Эта страница ещё не закончена. Информация, представленная здесь, может оказаться неполной или неверной.

Если вы считаете, что её стоило бы доработать как можно быстрее, пожалуйста, скажите об этом.

Автор: Владимир Кореньков
Правильная ссылка: http://xgu.ru/wiki/octave/txt_data_parser

Содержание


[править] Постановка задачи

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

В качестве "лабораторного образца" выберем файл графического формата *.stl. Это один из промежуточных форматов представления данных о топологии поверхностей 3D модели. Фактически любая трехмерная поверхность (по крайней мере технически реализуемая на современном оборудовании) может бить интерполирована сеткой треугольников: вершины этих треугольников принадлежат поверхностям, а максимальное отклонение плоскости от профиля зависит от наперед заданной точности интерполяции. Особенностями stl-формата являются:

  • направление вектора нормали к плоскости треугольника всегда указывает "наружу" детали;
  • все координаты вершин являются положительными числами (если не заданы особые настройки при конвертировании);
  • информация несколько избыточна, т.к. одна и та же точка должна принадлежать нескольким треугольникам.

Непосредственно сам файл имеет следующую структуру.

Пример описания одного треугольника в файле *.stl

solid Название файла
...
facet normal CosA CosB CosC
outer loop
vertex x1 y1 z1
vertex x2 y2 z2
vertex x3 y3 z3
endloop
endfacet
...
endsolid

Задача состоит в том, чтобы извлечь информацию и представить ее в виде матрицы, например с названием Matrix:

Форма представления конечного результата

> Matrix
x1 y1 z1 CosA CosB CosC
x2 y2 z2 CosA CosB CosC
x3 y3 z3 CosA CosB CosC
...

[править] Исходные данные

На сегодняшний день фактически каждая 3D CAD или дизайнерская система имеет в своем арсенале возможность импорта/экспорта stl-моделей. Поэтому для упрощения проверки результата в качестве 3D модели нарисуем параллелепипед и сохраним его с названием Cube.stl.

Cube triangle.PNG

Содержимое файла Cube.stl

solid Cube
facet normal -1.000000e+000 0.000000e+000 0.000000e+000
outer loop
vertex 0.000000e+000 0.000000e+000 3.000000e+001
vertex 0.000000e+000 4.500000e+001 3.000000e+001
vertex 0.000000e+000 0.000000e+000 0.000000e+000
endloop
endfacet
facet normal -1.000000e+000 0.000000e+000 0.000000e+000
outer loop
vertex 0.000000e+000 0.000000e+000 0.000000e+000
vertex 0.000000e+000 4.500000e+001 3.000000e+001
vertex 0.000000e+000 4.500000e+001 0.000000e+000
endloop
endfacet
facet normal 0.000000e+000 -1.000000e+000 0.000000e+000
outer loop
vertex 6.000000e+001 0.000000e+000 3.000000e+001
vertex 0.000000e+000 0.000000e+000 3.000000e+001
vertex 6.000000e+001 0.000000e+000 0.000000e+000
endloop
endfacet
facet normal 0.000000e+000 -1.000000e+000 0.000000e+000
outer loop
vertex 6.000000e+001 0.000000e+000 0.000000e+000
vertex 0.000000e+000 0.000000e+000 3.000000e+001
vertex 0.000000e+000 0.000000e+000 0.000000e+000
endloop
endfacet
facet normal 1.000000e+000 0.000000e+000 0.000000e+000
outer loop
vertex 6.000000e+001 4.500000e+001 3.000000e+001
vertex 6.000000e+001 0.000000e+000 3.000000e+001
vertex 6.000000e+001 4.500000e+001 0.000000e+000
endloop
endfacet
facet normal 1.000000e+000 0.000000e+000 0.000000e+000
outer loop
vertex 6.000000e+001 4.500000e+001 0.000000e+000
vertex 6.000000e+001 0.000000e+000 3.000000e+001
vertex 6.000000e+001 0.000000e+000 0.000000e+000
endloop
endfacet
facet normal 0.000000e+000 1.000000e+000 0.000000e+000
outer loop
vertex 0.000000e+000 4.500000e+001 3.000000e+001
vertex 6.000000e+001 4.500000e+001 3.000000e+001
vertex 0.000000e+000 4.500000e+001 0.000000e+000
endloop
endfacet
facet normal 0.000000e+000 1.000000e+000 0.000000e+000
outer loop
vertex 0.000000e+000 4.500000e+001 0.000000e+000
vertex 6.000000e+001 4.500000e+001 3.000000e+001
vertex 6.000000e+001 4.500000e+001 0.000000e+000
endloop
endfacet
facet normal 0.000000e+000 0.000000e+000 1.000000e+000
outer loop
vertex 6.000000e+001 0.000000e+000 3.000000e+001
vertex 6.000000e+001 4.500000e+001 3.000000e+001
vertex 0.000000e+000 0.000000e+000 3.000000e+001
endloop
endfacet
facet normal 0.000000e+000 0.000000e+000 1.000000e+000
outer loop
vertex 0.000000e+000 0.000000e+000 3.000000e+001
vertex 6.000000e+001 4.500000e+001 3.000000e+001
vertex 0.000000e+000 4.500000e+001 3.000000e+001
endloop
endfacet
facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
outer loop
vertex 6.000000e+001 4.500000e+001 0.000000e+000
vertex 6.000000e+001 0.000000e+000 0.000000e+000
vertex 0.000000e+000 4.500000e+001 0.000000e+000
endloop
endfacet
facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
outer loop
vertex 0.000000e+000 4.500000e+001 0.000000e+000
vertex 6.000000e+001 0.000000e+000 0.000000e+000
vertex 0.000000e+000 0.000000e+000 0.000000e+000
endloop
endfacet
endsolid

[править] Пример решения

Поместим в одну директорию файлы Cube.stl и ниже приведенный StlToArray.m.

Файл StlToArray.m

function Array = StlToArray(FileName)
# определяем массив
Array = [];

# создаем файловую переменную file и открываем файл FileName для чтения
file = fopen (FileName,"r");

# просматриваем файл до конца (feof - end of file)
while (! feof(file))

# переменной String присваиваем всю строку
String = fgetl(file);

# переменная Pattern1 содержит шаблон для поиска направляющих косинусов вектора нормали плоскости треугольника,
# переменная Pattern2 - его координат вершин
# согласно приведенным ниже регулярным выражениям, поиск будет выполняться только в строках, содержащих
# слова "normal" или "vertex", и в виде отдельных элементов массива сохранять координаты -
# целостные фрагменты из цифр "0-9", разделителя дробной части ".", знаков "+" или "-" и обозначения степени "e"
Pattern1 = 'normal\s*([0-9.+-e]*)\s*([0-9.+-e]*)\s*([0-9.+-e]*)';
Pattern2 = 'vertex\s*([0-9.+-e]*)\s*([0-9.+-e]*)\s*([0-9.+-e]*)';

# выполняем поиск
[s,e,te,m,t,nm] = regexp(String,Pattern1);
# какие-то действия можно выполнять только если найдено совпадение подстроки с шаблоном Pattern1
if (length(t) != 0)
# параметр t является массивом из одного элемента, содержащего в себе подмассив интересующих нас координат,
# поэтому есть два пути: первый - создать вектор row, который будет состоять из 3-х элементов, и работать
# с этим вектором; второй - использовать доступ к cell array напрямую: t{1}{2} (см. ниже)
row = t{1};
# преобразовываем все строки массива из текстового формата в числовой
CosA = str2num(row{1});
CosB = str2num(row{2});
CosC = str2num(row{3});
endif

# еще раз выполняем поиск
[s,e,te,m,t,nm] = regexp(String,Pattern2);
# если найдено совпадение подстроки с шаблоном Pattern2, формируем новую строку массива Array,
# описывающую отдельную вершину треугольника
if (length(t) != 0)
X = str2num(t{1}{1});
Y = str2num(t{1}{2});
Z = str2num(t{1}{3});
Array = [Аrray; X, Y, Z, CosA, CosB, CosC];
endif

endwhile
# закрываем файл
fclose(file);

endfunction

Пример использования

> Matrix = StlToArray("Cube.stl");
> Matrix

В результате получим массив Matrix, состоящий из 36 строк и 6 столбцов, содержащий вершины треугольников и направляющие косинусы векторов нормалей (см. приведенный ниже вывод на экран) в удобном для работы виде.

0 0 30 -1 0 0
0 45 30 -1 0 0
0 0 0 -1 0 0
0 0 0 -1 0 0
0 45 30 -1 0 0
0 45 0 -1 0 0
60 0 30 0 -1 0
0 0 30 0 -1 0
60 0 0 0 -1 0
60 0 0 0 -1 0
0 0 30 0 -1 0
0 0 0 0 -1 0
60 45 30 1 0 0
60 0 30 1 0 0
60 45 0 1 0 0
60 45 0 1 0 0
60 0 30 1 0 0
60 0 0 1 0 0
0 45 30 0 1 0
60 45 30 0 1 0
0 45 0 0 1 0
0 45 0 0 1 0
60 45 30 0 1 0
60 45 0 0 1 0
60 0 30 0 0 1
60 45 30 0 0 1
0 0 30 0 0 1
0 0 30 0 0 1
60 45 30 0 0 1
0 45 30 0 0 1
60 45 0 0 0 -1
60 0 0 0 0 -1
0 45 0 0 0 -1
0 45 0 0 0 -1
60 0 0 0 0 -1
0 0 0 0 0 -1


Octave GNU Octave

Инсталляция | Синтаксис языка | Командная строка
Скрипты | Функции | Регулярные выражения | Массивы | Графики | Ввод/вывод данных
Распределенные вычисления | Численные методы | Сплайны