<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Электронный научно-практический журнал «Современная техника и технологии» &#187; AbramovaOF</title>
	<atom:link href="http://technology.snauka.ru/author/abramovaof/feed" rel="self" type="application/rss+xml" />
	<link>https://technology.snauka.ru</link>
	<description></description>
	<lastBuildDate>Fri, 30 Jan 2026 18:56:12 +0000</lastBuildDate>
	<language>ru</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Особенности формирования банка тестовых заданий по специальным техническим дисциплинам для программной реализации системы адаптивного тестирования</title>
		<link>https://technology.snauka.ru/2013/11/2570</link>
		<comments>https://technology.snauka.ru/2013/11/2570#comments</comments>
		<pubDate>Sat, 02 Nov 2013 19:17:16 +0000</pubDate>
		<dc:creator>AbramovaOF</dc:creator>
				<category><![CDATA[Общая рубрика]]></category>
		<category><![CDATA[адаптивное компьютерное тестирование]]></category>
		<category><![CDATA[система адаптивного тестирования]]></category>
		<category><![CDATA[технические дисциплины]]></category>

		<guid isPermaLink="false">https://technology.snauka.ru/?p=2570</guid>
		<description><![CDATA[      В настоящее время различные виды тестирования, применяемые  для определения уровня знаний обучаемого, используются достаточно широко. Наиболее  перспективным методом в  этой области можно назвать метод адаптивного тестирования [1],  который отличается тем, что позволяет  корректировать тестовые задания по содержанию, сложности и изменять их  последовательность непосредственно в ходе тестирования, руководствуясь при этом  сформированной моделью тестируемого.  Данная модель [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">      В настоящее время различные виды тестирования, применяемые  для определения уровня знаний обучаемого, используются достаточно широко. Наиболее  перспективным методом в  этой области можно назвать метод адаптивного тестирования [1],  который отличается тем, что позволяет  корректировать тестовые задания по содержанию, сложности и изменять их  последовательность непосредственно в ходе тестирования, руководствуясь при этом  сформированной моделью тестируемого.  Данная модель создается системой самостоятельно на основе  предварительных заданий. Такой подход позволяет существенно улучшить оценку  уровня знаний обучаемого и исключает субъективность в оценивании, так как  тестовый материал подбирается с учетом индивидуальных особенностей и знаний  тестируемого.</p>
<p style="text-align: justify;">     При моделировании  программных систем,  способных оценить  уровень знаний испытуемого с учетом основных постулатов адаптивного  тестирования, необходимо, чтобы система отвечала следующим требованиям:</p>
<ul style="text-align: justify;">
<li>наличие базы  предварительно оцененных разработчиком заданий, каждое из которых дает  возможность выбора адекватного последующего задания при тестировании;</li>
<li>использование  специальных алгоритмов, позволяющих в реальном времени выполнять подбор заданий  индивидуально;</li>
<li> использование  современных способов оценки тестовых заданий.</li>
</ul>
<p style="text-align: justify;">      Т.е. одним из самых  важных моментов в системе адаптивного компьютерного тестирования можно считать  наличие базы тестовых заданий, сложность которых была тщательно оценена  предварительно с использованием современных методов и теорий оценки теста.  Одной из таких теорий, широко используемой в настоящее время, является теория  моделирования и параметризации педагогических тестов Item Response Theory (IRT), принципиальное отличие которой  заключается в уникальности оценки  тестовых заданий. Т.е. каждое тестовой задание, диагностика которого  производится, например, с помощью двухпараметрической модели Бирнбаума,  рассматривается как самостоятельная элементарная составляющая теста. Параметры  каждого задания оцениваются индивидуально и никак не связаны с параметрами  других заданий теста. Оценка тестовых заданий производится с помощью  определенных функций (функций успеха), выражающих зависимость верного ответа на  задание от уровня подготовки обучаемого. Для этого используются достаточно  сложные итерационные методы, но результаты оправдывают их применение, т.к.  позволяют, например, записать результаты прохождения теста по различным  вариантам на единую шкалу или свести воедино результаты прохождения разных по  уровню трудности тестов.</p>
<p style="text-align: justify;">       Для оценки качества  тестовых заданий используются такие понятия, как надежность теста –  характеристика невосприимчивости результатов на влияние посторонних случайных  факторов, отражающая точность измерения; и валидность теста – способность теста  измерять определенные характеристики с помощью экспертных оценок. Все эти  характеристики, включая оценку трудности задания, измеряются и устанавливаются  составителем теста. Не говоря уж о составлении самого тестового вопроса. И вот  тут начинает действовать проблема «восприятия информации». В чем она  выражается? Каждый испытуемый в первую очередь человек, со своими личными  страхами, особенностями менталитета, специфическими гранями личности. Эти же  утверждения относятся в полной мере и к составителю теста. Поэтому на практике,  даже при условии достаточно хорошего уровня знаний у испытуемого, возможны  ситуации, когда ответ выбран не правильный. В силу различных причин: не  понимания сути вопроса, не понимания смысла вариантов ответа, волнения, страха  и т.п. Особенно это касается тестовых заданий по специальным дисциплинам,  длительность обучения которым не так велика, а знания, которые необходимо усвоить  студентам, достаточно обширны и многословны. Т.е. правильный ответ  подразумевает множество текстовых вариантов, сформулировать которые  преподаватель и студент могут совершенно по-разному, в силу разного уровня как  профессиональных, так и общенаучных словарей. Например, студенту первого курса  при прохождении тестового опроса по дисциплине «Введение в программную  инженерию» предлагается следующий тестовый вопрос:</p>
<p style="text-align: justify;">«Какова главная цель программной  инженерии:</p>
<p style="padding-left: 30px;">a)  найти лучший подход к созданию ПО;</p>
<p style="padding-left: 30px;">b)  сократить стоимость ПО;</p>
<p style="padding-left: 30px;">c)  правильно составленная документация;</p>
<p style="padding-left: 30px;">d)  умение работать в команде»</p>
<p style="text-align: justify;">Этот же вопрос, но сформулированный иначе:</p>
<p style="text-align: justify;">«Определите одну из важнейших задач  программной инженерии:</p>
<p style="text-align: justify; padding-left: 30px;">a)  минимизация расходов на разработку и  создание ПО;</p>
<p style="text-align: justify; padding-left: 30px;">b)  обеспечение ПО надежной и достаточной  документацией;</p>
<p style="text-align: justify; padding-left: 30px;">c)  формирование специалиста, умеющего  работать в команде;</p>
<p style="text-align: justify; padding-left: 30px;">d)  определение наилучших методов и средств  создания ПО»</p>
<p style="text-align: justify;">        Вопрос тот же, ответы  по смыслу те же, а вот восприятие таких заданий студентом совершенно разное. В  первом случае постановка вопроса достаточно размыта, и не предполагает от  студента одного конкретного ответа (хотя оценивается именно один правильный  ответ – b),  но формулировка задания и вариантов ответа упрощены, а потому воспринимаются  студентом-первокурсником легче. Во втором случае сам вопрос уже содержит  конкретную подсказку на количество вариантов ответа, но варианты ответов  сформулированы достаточно серьезным научным слогом. И у студента, еще не  имеющего большого научного словаря в силу краткости обучения в вузе, такие  варианты могут вызвать замешательство, а в некоторых случаях и просто ступор, так как ситуация накаляется нервозностью по поводу краткости времени,  отведенного на опрос, неопытностью,  неустойчивостью имеющихся и, вроде бы, усвоенных знаний и т.п. И в такой  ситуации оценить действительный уровень знаний испытуемого достаточно трудно,  не говоря уже о том, чтобы студент имел возможность проанализировать свои  ответы и укрепить свои знания по предмету.</p>
<p style="text-align: justify;">      Т.е. с уверенностью  можно говорить о том, что система адаптивного тестирования, содержащая тестовые  задания, которые не соответствуют требованиям дисциплины либо по смысловой  нагрузке, либо по результатам оценки их практической значимости и эффективности,  малоэффективна. Так же мало полезны будут тестовые задания, вызывающие неоднозначную  реакцию у тестируемых: плохое ориентирование в вариантах ответов из-за большого  их количества или неточных формулировок, непонимание смысла вопроса из-за  достаточно запутанной формулировки,  и  т.п. Даже при условии формирования системой адаптивного тестирования некоторых  рекомендаций для обучаемого по литературным источникам или предоставление  правильных ответов на неудачно пройденные вопросы (по окончании теста),  основная цель – успешное усвоение материала – в большинстве случаев достигнута  не будет. Литературные источники предлагают слишком обширный материал, а  предложенный системой правильный ответ, наоборот, слишком краток, и не  подразумевает понимание вопроса. Т.е. такая система не нацелена на достижение  основной цели процесса обучения – получение и максимальное усвоение студентом  необходимых знаний по дисциплине.</p>
<p style="text-align: justify;">     С другой стороны,  современные студенты достаточно избалованны наличием в повседневной жизни  интересных, увлекательных графических визуализаций на совершенно разные темы: это  и различные фото- и видео-инструкции по решению самых различных бытовых проблем,  электронные учебники и тренажеры, и. т.п. Современный образ жизни приучил студента  к поиску наиболее быстрого, простого и понятного решения. А решение,  представленное графически, именно таким и является [2,3].</p>
<p style="text-align: justify;">     Следовательно, при разработке системы адаптивного тестирования по специальным  дисциплинам на первое место выходит проблема разработки достаточного набора адекватных  тестовых заданий, способных объективно оценить уровень знаний испытуемых. Для  этого можно учитывать следующие рекомендации.</p>
<ol style="text-align: justify;">
<li>Формирование  тестовых заданий необходимо производить с учетом профессионального и научного  словаря испытуемых. Для этого можно, например, проводить предварительный тест  заданий на «восприятие информации», предлагая студенту оценить по определенной  шкале (допустим, от 0 до 1) уровень его личного понимания смысла вопроса и  ответов. При этом не путать эту оценку с наличием  знания ответа на поставленный вопрос. Тест на  «восприятие» можно провести как до непосредственного тестирования на уровень  знаний по дисциплине, так и после. А затем сравнить результаты. Проведенный  автором эксперимент среди первокурсников по дисциплине «Введение в программную  инженерию»  показал, что вопросы с очень  низким уровнем «восприятия» (от 0 до 0,5), т.е. непонятные студенту по  различным причинам, имели и достаточной низкий процент правильных ответов.  Студенты в выборе ответов руководствовались методом «выбор наугад», что,  естественно, приводило к плачевным результатам. В качестве причин низкого  уровня восприятия выдвигались следующие: «многословность вопроса», «большое  количество вариантов ответа», «многословность ответов», «высокая научность  теста», «размытость формулировок» и т.п. Соответственно, вопросы с низким  уровнем восприятия были переформулированы с учетом заявленных требований,<br />
причем в изменении тестовых заданий принимали участие сами студенты.</li>
</ol>
<p>Например,  тестовое задание «Верны  ли следующие утверждения: А) Методы разработки ПО в основном ориентируются на  поэтапное преобразование некоторой модели ПО в программу. Б) Методы не включают  в себя компоненты описания модели системы и нотацию.</p>
<p style="text-align: justify; padding-left: 30px;">a) Верны оба суждения.</p>
<p style="text-align: justify; padding-left: 30px;">b) Верно только А.</p>
<p style="text-align: justify; padding-left: 30px;">c) верно только Б.»</p>
<p style="text-align: justify;">страдает  многословностью и размытостью постановки вопроса. Задание не сбалансировано по  смыслу, содержит, по сути два разных вопроса, и, как следствие, вызвало большое  замешательство среди испытуемых именно на этапе понимания. После модернизации  тестовое задание было разбито на два, вопросы и варианты ответов стали  предельно лаконичными, и, соответственно, более понятными.</p>
<p style="text-align: justify;">« 1. Методы разработки ПО  ориентированы:</p>
<p style="text-align: justify; padding-left: 30px;">a)  на поэтапное преобразование модели ПО в  программный код;</p>
<p style="text-align: justify; padding-left: 30px;">b)  на формирование цельного программного кода ПО  без учета модели;</p>
<p style="text-align: justify; padding-left: 30px;">c)  моделирование – это один процесс,  программирование – другой, и между собой они не связаны.</p>
<p style="text-align: justify;">2.  Методы разработки ПО:</p>
<p style="text-align: justify; padding-left: 30px;">a)  не включают в себя описания компонентов модели  системы;</p>
<p style="text-align: justify; padding-left: 30px;">b)  основаны на описании компонентов модели системы;</p>
<p style="text-align: justify; padding-left: 30px;">c)  используют описания компонентов модели системы  по ситуации.»</p>
<p style="text-align: justify;">Такие  тестовые задания получили от студентов оценку «восприятия информации» 1, и  никаких дополнительных вопросов не вызвали. Двойной  тест был проведен снова, но на другой группе испытуемых. Результаты  тестирования значительно улучшились, хотя входные данные (количество занятий,  предлагаемая информация на лекционных и практических занятиях, время проведения  теста и др.) остались приблизительно на том же уровне.</p>
<p style="text-align: justify;">      2. Количество  вариантов ответа на тестовое задание должно быть минимизировано, а сами ответы  должны быть предельно просты и понятны. В идеале, конечно, это два варианта  ответа: «Да» и «Нет». Но такие тесты грешат большим процентом угадываний правильных ответов: студенты, не зная правильный ответ, выбирают его наугад, и  достаточно часто попадают на правильный. Поэтому такие варианты тестовых  заданий для специальных дисциплин не подходят. Но разумная минимизация должна<br />
присутствовать. Например, два варианта тестового задания:</p>
<p>            1. Перечислите  принципы кодекса этики: 1) общество ,  2)  клиент и работодатель, 3) продукт, 4) суждение, 5) понятие, 6) менеджмент, 7) профессия, 8) коллеги,  9) личность:</p>
<p style="text-align: justify; padding-left: 30px;">a) 1, 2, 3, 6, 7, 9</p>
<p style="text-align: justify; padding-left: 30px;">b) 1, 2, 3, 4, 6, 7, 8, 9</p>
<p style="text-align: justify; padding-left: 30px;">c) 1, 2, 3, 4, 5, 6, 7, 8, 9»</p>
<p>           2. К  принципам кодекса этики программного инженера не относят:</p>
<p style="text-align: justify; padding-left: 30px;">a)    суждение</p>
<p style="text-align: justify; padding-left: 30px;">b)   понятие</p>
<p style="text-align: justify; padding-left: 30px;">c)    коллеги</p>
<p style="text-align: justify; padding-left: 30px;">d)   личность.</p>
<p style="text-align: justify;">вызывали у респондентов совершенно разную  реакцию. Даже при условии знания правильного ответа, первое тестовое задание  приводило тестируемого в замешательство, так оно предполагает приложение  больших дополнительных усилий на понимание самого вопроса и отождествление всех  вариантов ответа (как правило) с формулировкой вопроса. Поэтому оценку  «восприятие информации» задание получило 0,5, а правильно ответили на него 70%  опрошенных. Второй же вариант тестового задания никаких дополнительных умственных усилий от испытуемого не требует, а соответственно и  результативность его выше (98% правильных ответов), а время затраченное на  выбор ответа, меньше.</p>
<p style="text-align: justify;">        3. Тестовые  задания, сформированные с использованием простых графических элементов  (графиков, блок-схем), или в виде последовательность примитивных графических  картинок (комиксов), повышают заинтересованность студента в самом тесте,  предельно упрощают понимание им вопроса и определение ответа [4]. И, можно  сказать, успокаивают испытуемого (особенно первокурсника), снимая лишнюю  тревожность, так как графическая информация воспринимается им намного легче,  чем сложный научный текст. Поэтому сложные задания, визуализированные  графически (с помощью графиков, схем, диаграмм и т.п.) принесут большую пользу  и повысят эффективность как самого теста, так и оценки им уровня знаний  испытуемых.</p>
<p style="text-align: justify;">        4. База  тестовых заданий должна содержать некоторое количество вопросов, одинаковых по  смыслу, но сформулированных по-разному (разные формулировки вопроса, с  использованием более сложных и более простых научных оборотов; разные  формулировки ответов, и т.п.). Наличие таких заданий в тесте позволит исключить  выбор студентом правильного ответа наугад и подтвердит (или опровергнет) его  знания по этой теме.</p>
<p style="text-align: justify;">        Разработка обучающих  систем адаптивного тестирования является одной из актуальных и важных задач на  современном этапе обучения специальным техническим дисциплинам. И формирование  базы тестовых заданий, позволяющих  оценить реальный уровень знаний студентов по дисциплине, это один из  главных моментов при создании таких систем. Анализируя практический опыт  проведения тестовых опросов в группе студентов первого курса по дисциплине  «Введение в программную инженерию», автор сформулировал несколько рекомендаций  по составлению тестовых заданий.</p>
]]></content:encoded>
			<wfw:commentRss>https://technology.snauka.ru/2013/11/2570/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>К вопросу об импорте 3D моделей в программы с использованием графической библиотеки OpenGl</title>
		<link>https://technology.snauka.ru/2014/01/2965</link>
		<comments>https://technology.snauka.ru/2014/01/2965#comments</comments>
		<pubDate>Mon, 27 Jan 2014 11:40:20 +0000</pubDate>
		<dc:creator>AbramovaOF</dc:creator>
				<category><![CDATA[Общая рубрика]]></category>
		<category><![CDATA[3D-моделирование]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[алгоритм]]></category>
		<category><![CDATA[импорт]]></category>
		<category><![CDATA[компьютерная графика]]></category>
		<category><![CDATA[конвертер]]></category>
		<category><![CDATA[программная реализация]]></category>

		<guid isPermaLink="false">https://technology.snauka.ru/?p=2965</guid>
		<description><![CDATA[Изучать  компьютерную графику люди всегда начинают с определенными целями, будь это желание сделать красивую трехмерную сцену или просто успешно сдать работу по данной дисциплине в институте. В последнем случае чаще всего рассматривается графическая подсистема OpenGl. В принципе, в современном мире, благодаря доступности различных интернет-ресурсов, найти информацию по этой платформе не представляет особой сложности. Есть и [...]]]></description>
			<content:encoded><![CDATA[<h1><span style=" 13px; font-weight: normal;">Изучать  компьютерную графику люди всегда начинают с определенными целями, будь это желание сделать красивую трехмерную сцену или просто успешно сдать работу по данной дисциплине в институте. В последнем случае чаще всего рассматривается графическая подсистема OpenGl. В принципе, в современном мире, благодаря доступности различных интернет-ресурсов, найти информацию по этой платформе не представляет особой сложности. Есть и уроки, и спецификации, и многое другое [1]. Вот только есть темы, о которых даже в интернете (по крайней мере, в его русскоязычном сегменте) найти информацию достаточно трудно. В этой статье речь пойдет об одной из них.</span></h1>
<p>Когда человек начинает писать программу с использованием инструментов графической библиотеки OpenGl, то рано или поздно он понимает, что стандартных средств интерфейса совершенно недостаточно для построения графического объекта хоть сколько-нибудь приемлемой сложности. Много ли можно сделать из прямоугольников и треугольников? Много, совершенно справедливо ответите вы. И будете правы, ибо полигональные модели как раз и формируются из этих самых треугольников. Собственно, полигон – это и есть многоугольник, причем чаще всего используются как раз треугольники или прямоугольники[2]. Вот только вручную просчитать расположение сотен (а то и тысяч, и сотен тысяч) полигонов – занятие, конечно, реализуемое, но маловероятное. Нет, конечно же, еще фигуры можно задавать массивами координат, но высчитать подобный массив – задача не намного легче.</p>
<p>Как поступает студент в таком случае? Он использует 3D-редакторы для отрисовки сложных 3D-объектов. 3D-редакторы обладают удобным графическим интерфейсом, интуитивно понятным даже для новичка, и научиться создавать с их помощью достаточно сложные объекты, а затем переводить их в понятные для OpenGl списки координат, не составит для увлеченного человека особого труда. И вот тут разработчика ожидает серьезная проблема: к сожалению, OpenGl не содержит встроенных средств для чтения 3D-моделей. Поэтому  реализовывать такое приложение приходится самому.</p>
<p>Нет, с одной стороны, координаты – это всегда координаты, и вроде бы ничего сложного в переносе нет. В крайнем случае, можно взять массив координат, полученный в редакторе, и вручную вставить его в код. Можно даже перенести 10 тысяч полигонов из 3D-редактора в код. Но сколько времени займет данная операция?</p>
<p>Для решения этой проблемы можно избрать следующий путь:  привлечь «автозамену», встроенную в любой текстовый редактор, и с помощью неё постараться подогнать форматы. Но это тоже не избавит вас от огромной ручной работы. Да и «автозамена» никогда не была интеллектуальным алгоритмом, и гарантии, что после такой длительной работы у вас все заработает, никто не даст.</p>
<p>Следовательно, скажет пытливый читатель, процесс преобразования надо автоматизировать. И, разумеется, будет в чем-то прав. Такой вывод напрашивается сам собой, поэтому обойти стороной такое решение мы не могли. Вот только реально эта задача труднореализуема: в интернете с большим трудом, но все-таки можно найти весьма сложные встраиваемые комплексы, которые после включения в ваш программный код динамически загружают и обрабатывают модели. Так вот же решение, скажете вы: и код компилируется быстро (массив координат содержится вне кода, и в компиляции не участвует), и новую модель подключить не сложно. И будете не совсем правы. Потому как данный подход  обладает рядом довольно весомых недостатков. Самый важный из них – сложность данного способа. Для человека, который не слишком хорошо разбирается в объектно-ориентированном стиле программирования  (т.к. большинство этих способов реализованы именно в виде подключаемых классов), понять, что делает подобный загрузчик, чрезвычайно трудно. Да и объем у подобного загрузчика весьма велик. А если я просто хочу сделать вращающийся стул? При этом код всей программы будет раз в 10 меньше кода загрузки модели, и это ставит под серьезные сомнения возможность применения такого подхода. И для начинающих его вряд ли можно посоветовать.</p>
<p>Поэтому мы пойдем другим путем. Мы разработаем несложный алгоритм преобразования нашего файла с координатами в код, спокойно читаемый OpenGl. И лучше всего будет оформить данный алгоритм в отдельную программу, которая будет конвертировать необходимые модели для реализации их с помощью графической библиотеки OpenGl.</p>
<p>Рассмотрим процесс создания алгоритма для конвертирования 3D-моделей из 3D-редактора в программный код. Для начала выберем исходный формат файла-источника. Предлагаю использовать OBJ-формате, и для этого есть две веские причины. Во-первых, это один из самых распространённых форматов хранения данных, а во-вторых (и это главное в нашем случае), он текстовый и, как следствие, более понятный для восприятия.</p>
<p>Но для начала немного уточним терминологию. Как в OpenGl, так и в OBJ есть координаты и индексы [3]. Координата – это расположение точки на виртуальной координатной плоскости в программе (по трем измерениям). Тут все просто. А вот с понятием «индекс» могут возникнуть сложности.  В нашем случае «индекс» – это номер координаты в массиве координат. Поясним ситуацию на примере: допустим, дан массив из 4-х наборов координат по трем осям X, Y, Z:</p>
<p align="center">          (x, y, z)</p>
<p align="center">    1)    1,  3, 5</p>
<p align="center">   2)   -2, 7, 9</p>
<p align="center">    3)   -5, 4, -7</p>
<p align="center">     4)    8, -6, -1</p>
<p>И координата некоторой точки, указанная в индексах:</p>
<p align="center">Точка 1: 4, 3, 2</p>
<p>В этом случае значения индексов точки означают номер ряда из массива, по соответствующей оси. В нашем случае, индекс по оси X равен 4, следовательно, необходимо взять координату оси Х из четвертого ряда (у нас это 8). Точно так же восстанавливаем координаты по оси Y (третий ряд, вторая цифра &#8211; 4) и Z (второй ряд, третья цифра – 9).</p>
<p>В итоге получаем, что координаты точки, заданной с помощью индексов будут следующие:</p>
<p align="center">Точка 1: 4, 8, 9</p>
<p>Подобный метод индексации необходим для сокращения количества координат. Ведь у многогранных фигур очень часто встречаются либо общие точки, когда совпадают все три координаты, либо точки, находящиеся на одной линии, у которых общие одна из координат.</p>
<p>Также необходимо учитывать, что для описания модели используют три типа координат: координаты модели (то есть самого объекта), координаты нормалей (необходимы для распределения освещенности в сцене) и координаты текстур (при наличии текстур в модели).</p>
<p>Теперь пару слов непосредственно про формат OBJ. Информация в нем хранится в текстовом виде, что позволяет ее просмотреть с помощью любого текстового редактора. Во многих подобных файлах помимо координат хранятся еще и ссылки к материалам, текстурам и др. Стандартный вид obj-файла следующий:</p>
<p># Max2Obj Version 4.0 Mar 10th, 2001</p>
<p>v  10.4335  217.914  7.80485</p>
<p>v  -8.02548  219.079  6.90515</p>
<p>v  -8.22437  219.042  6.90515</p>
<p>v   4.414604  70.340584  7.308666</p>
<p># 4 vertices</p>
<p>vn  0.000000 0.000002 -1.000000</p>
<p>vn  -1.000000 0.000000 0.000000</p>
<p>vn  0.000000 0.000000 1.000000</p>
<p># 3 vertex normal</p>
<p>vt  0.47683 0.51250</p>
<p>vt  0.46556 0.50879</p>
<p>vt  0.46335 0.50876</p>
<p># 3 texture vertices</p>
<p>f  1/1/1  1/2/1  2/3/1</p>
<p>f  4/2/1  3/1/3  4/1 1</p>
<p>f 3/1/3  2/3/1  3/1/2</p>
<p># 3 faces</p>
<p>Разберем данный пример подробнее. Первая строка представляет собой комментарий, содержащий не интересующую нас общую информацию. Начиная со второй строки располагается массив координат модели (обозначается латинской V).</p>
<p>v  10.4335  217.914  7.80485</p>
<p>v  -8.02548  219.079  6.90515</p>
<p>v  -8.22437  219.042  6.90515</p>
<p>v   4.414604  70.340584  7.308666</p>
<p>Это описание каркаса нашей модели (точнее, массив координат каркаса, помним про индексы). Он есть в любом файле.</p>
<p>Затем указаны координаты нормалей:</p>
<p>vn 0.000000 0.000002 -1.000000</p>
<p>vn -1.000000 0.000000 0.000000</p>
<p>vn 0.000000 0.000000 1.000000</p>
<p>Координаты нормалей никогда не принимают значение большее единицы и указывают направление света. Указываются в файлах далеко не всегда: нет освещенности, нет и нормалей.</p>
<p>Далее перечисляются координаты текстуры:</p>
<p>vt 0.47683 0.51250</p>
<p>vt 0.46556 0.50879</p>
<p>vt 0.46335 0.50876</p>
<p>Поскольку текстура сама по себе двухмерная, третья координата обычно либо не указывается, либо равна 0 (vt 0.46335 0.50876 0). Данного блока может не быть, если у модели нет текстур.</p>
<p>Зачастую между блоками встречаются комментарии с указанием количества этих самых блоков ( # 3 texture vertices). Также можно уточнить, что количество точек каркаса, текстур и нормалей не всегда соответствует друг другу. Это совершенно нормально и  приводится в соответствие с помощью индексов.</p>
<p>Какую же полезную информацию может почерпнуть разработчик из представленных массивов данных?</p>
<p>1. В пределах одной модели порядок массивов координат всегда сохраняется: сначала указывается блок V (координаты моделей), потом блок VT (текстуры), затем блок VN (нормали). Блоки никогда не перемешиваются и не меняются местами (то есть, блока текстур может не быть вообще, но если он есть, то идет всегда после массива координат каркаса).</p>
<p>2. Между собой данные разделяются пробелом.</p>
<p>Эти два факта мы будем активно использовать  для реализации конвертера 3D-моделей.</p>
<p>Но это еще не все содержимое obj-файла. За блоком текстур располагается блок, строки которого начинаются с буквы f:</p>
<p>f  1/1/1  1/2/1  2/3/1</p>
<p>f  4/2/1  3/1/3  4/1 1</p>
<p>f  3/1/3  2/3/1  3/1/2</p>
<p>Это массив индексов. И составные элементы этого блока очень важны для понимания работы алгоритма конвертера, поэтому мы рассмотрим их подробнее. Буква f, как уже было сказано,  обозначает начало строки с индексами. Далее идут числа с разделителями, значения которых расшифровываются следующим образом: пробелом разделяются оси (соответственно, блоков чисел всегда 3: ось х, ось y, ось z), а внутри каждого блока допускается существование от 1 до 3 цифр, разделенных знаком «/» (или «//»):</p>
<p>f  1//1//1  1//2//1  2//3//1</p>
<p>f  4 3 4</p>
<p>f  3/1  2/2  3/1</p>
<p>Каждая тройка чисел несет следующую информацию: индекс каркаса//индекс текстуры//индекс нормали. Соответственно, если у модели нет текстур или нормалей, то и соответствующих индексов в блоке не будет.</p>
<p>Например,  рассмотрим одну из точек, строка индексов которой указана последней в блоке f:  f  3/1/3  2/3/1  3/1/2. Индекс координат данной точки: 3, 2, 3 (первые цифры каждого блока), следовательно, значения её координат мы выбираем из массива координат модели v из третьего, второго и снова третьего ряда: -8.22437,   219.079, 6.90515. Индекс текстур точки: 1, 3, 1 (вторые цифры блока). Следовательно, текстурные координаты данной точки 0.47683, 0.50876. Нормали выбираются по тому же принципу.</p>
<p>Также важно помнить,  что в одном файле могут быть указаны описания нескольких моделей, каждое из которых состоит из вышеперечисленных блоков.</p>
<p>Рассмотрим  теперь способ записи координат в OpenGl проекте.  В общем виде описание изображения с использованием массивов выглядит, например, так:</p>
<p>glEnableClientState(GL_VERTEX_ARRAY);</p>
<p>glEnableClientState(GL_NORMAL_ARRAY);</p>
<p>glEnableClientState(GL_TEXTURE_COORD_ARRAY);</p>
<p>GLfloat pVerts1[]= {</p>
<p>-610.2380, 0.0000, 1368.7837,</p>
<p>-610.2380, 0.0000, 504.9502</p>
<p>};</p>
<p>GLfloat pNorm1[]= {</p>
<p>0.0000, -1.0000, -0.0000,</p>
<p>0.0000, 1.0000, -0.0000,</p>
<p>0.0000, 0.0000, 1.0000</p>
<p>};</p>
<p>GLfloat pTexCoord1[]= {</p>
<p>1.0000, 1.0000,</p>
<p>0.0000, 0.0000,</p>
<p>};</p>
<p>glVertexPointer(3, GL_FLOAT, 0, pVerts1);</p>
<p>glNormalPointer(GL_FLOAT, 0, pNorm1);</p>
<p>glTexCoordPointer(2,GL_FLOAT, 0,  pTexCoord1);</p>
<p>glDrawArrays(GL_TRIANGLES,0,3);</p>
<p>glDisableClientState (GL_VERTEX_ARRAY);</p>
<p>glDisableClientState (GL_NORMAL_ARRAY);</p>
<p>glDisableClientState (GL_TEXTURE_COORD_ARRAY);</p>
<p>Первые три строки необходимы для указания того, что будут использоваться 3 массива: массив вершин (GL_VERTEX_ARRAY),массив  нормалей (GL_NORMAL_ARRAY) и массив текстур (GL_TEXTURE_COORD_ARRAY). Далее указывается непосредствнно массив координат модели pVerts1[], который, в отличие от блока в OBJ, хранит уже готовые координаты, по которым строится каркас (напомним, что в OBJ каркас модели строился по индексам). При этом координаты в массиве pVerts1[] разделяются не пробелом, как в obj-файле, а запятыми. Затем инициализируются массив нормалей pNorm1[] и массив текстур pTexCoord1[].</p>
<p>Следующие три строки необходимы для указания, во-первых, какой из массивов содержит какие конкретно значения, а, во-вторых, каким способом эти значения из массива надо брать:</p>
<ul>
<li>glVertexPointer(3, GL_FLOAT, 0, pVerts1) &#8211;  определяем, что массивом вершин будет именно массив pVerts1, определяем тип значений этого массива «float», и количество координат на одну вершину (по три, то есть три оси);</li>
<li> glNormalPointer(GL_FLOAT, 0, pNorm1) &#8211;  массив нормалей называется pNorm1 и также хранит значения типа «float»;</li>
<li> glTexCoordPointer(2,GL_FLOAT, 0,  pTexCoord1) &#8211; текстурный массив с именем pTexCoord1 и количеством переменных на точку – 2 (текстуры у нас двумерные).Далее переходим к отрисовке самой модели: glDrawArrays (GL_TRIANGLES,0,3). Здесь GL_TRIANGLES указывает, что рисовать будем треугольники; 0 – выборку координат из массива начнем  с нулевого элемента; 3 – на одну вершину будем считывать по три значения. Данная команда выводит треугольники по нашим координатам, пока они (координаты) не кончатся. Последние три строки примера необходимы для отключения установленных режимов обработки массивов. Эту функцию  необходимо  задавать в конце всего процесса вывода, но не обязательно для каждой модели.Перейдем теперь непосредственно к процессу перевода одного формата в другой. При этом при создании OBJ файла по умолчанию считаем, что отрисовывать будем треугольники. Не будем останавливаться на таких проблемах, как разные разделители координат (в файлах пробелы, в коде запятые), или отличающийся вид самих массивов (в файле каждая строка обозначается буквами, в коде достаточно фигурной скобки в начале блока), и прочем. Это можно достаточно просто исправить простейшими текстовыми преобразованиями (типа «автозамены»). Но вот об одной проблеме поговорим подробнее.
<p>Как уже говорилось выше, в obj-формате все точки хранятся не в чистых координатах, а в массивах индексов. Библиотека OpenGl такого описания не понимает. Вернее, понимает, но массив индексов при построении фигуры можно использовать только один – координат каркаса, а вот нормали и текстуры будут проигнорированы.  Как следствие, если нам нужен только каркас без всего остального, работа сильно упрощается. Но мы сейчас говорим о полноценном построении трехмерной модели, поэтому нам важны все три массива значений.</p>
<p>Итак, для начала нам требуется считать файл. Чтение файла происходит построчно. При этом индексы в конце файла указывают на массив координат в его начале. Появляется проблема: или перечитывать файл на каждый индекс (что не слишком эффективно, учитывая, что точек – тысячи), либо сначала считывать и обрабатывать файл (и распределять по массивам в памяти), а потом уже формировать код. Поэтому выбираем второй способ. Так же необходимы места для хранения считанного массива. Будем использовать двухмерные массивы (код на Си):</p>
<p>float coord_vert [1000000][2];</p>
<p>float coord_ norm [1000000][2];</p>
<p>float coord_ tex [1000000][2];</p>
<p>Здесь мы объявили три массива типа «float», в которых будем хранить массивы вершин, нормалей и текстур соответственно. Количество элементов в массиве: миллион строк (что для высокополигональных моделей имеет смысл) и по 3 элемента в каждой строке (оси X,Y,Z). По умолчанию будем считать, что первая цифра – это номер самого массива, вторая – номер элемента в этом массиве.</p>
<p>Таким же образом создаем массивы для хранения трех индексов, но с учетом того, что индексы у нас целочисленные (тип int):</p>
<p>int  ind_vert [1000000][2];</p>
<p>int  ind _ norm [1000000][2];</p>
<p>int  ind _ tex [1000000][2];</p>
<p>Тогда конвертация трехмерной модели будет проходить в два этапа:</li>
</ul>
<ol>
<li>считывание и обработка исходного файла;</li>
<li>построение файла с кодом.На первом этапе мы считываем одну модель и распределяем её по массивам. Далее осуществляем обработку массивов по отдельности: массивов координат и массивов индексов. Сначала ищем в строке символы “v”, “vt”, “vn”,  и, в случае обнаружения, следующие 3 координаты записываем в соответствующий массив под соответствующими номерами. И увеличиваем номер этого массива на 1.Когда мы доходим до массива индексов (символ “f”), мы должны отключить поиск координат (если этого не сделать, то к нам может попасть массив координат от следующей модели). Считывание индексов происходит по следующему алгоритму:</li>
</ol>
<ol>
<li>читаем первое число за пробелом, вносим его в массив индексов  каркаса (под соответствующим номером) как первый элемент массива (координата Х);</li>
<li>проверяем на наличие знака разделителя: «/» или «//» (т.к.  мы не знаем вид исходного файла);</li>
<li>если знак разделителя найден, то проверяем, есть ли у нас структура с координатами текстур (как  уже говорилось ранее, в индексах координаты идут по порядку (вершины/текстуры/нормали), но если текстур нет, то и текстурных индексов соответственно не будет, и без этой проверки мы можем выполнить запись индексов «не по адресу»);</li>
<li>записываем число после знака разделителя в массив с индексами текстур (или нормалей, если текстур нет) в первый элемент массива;</li>
<li>снова проверяем на наличие разделителя, и, при его обнаружении,  формируем массив нормалей;</li>
<li>выполняем поиск пробела;</li>
<li>число, следующее за пробелом, записываем в массивы с тем же номером и в том же порядке (сначала вершины, потом текстуры, потом нормали), но уже во второй элемент массива (т.е. формируем координаты оси Y);</li>
<li>повторяем те же действия для оси Z.Выполняем вышеуказанные действия до обнаружения знака начала комментариев (#), новых координат вершин (v) или конца файла. Затем  осуществляем  вывод нужного кода в следующем порядке:</li>
</ol>
<ul>
<li>сначала выводим оформление кода: GLfloat pVerts1[]= {</li>
<li>затем выводим координаты (по три в строке,  что удобнее для восприятия).Вывод координат осуществляется следующим образом: запускаем цикл (от нуля до того количества индексов, которое мы записали); выводим первый элемент массива; в качестве номера самого массива берем значение из массива индексов:for (int i=0; i&lt;kol_vo_indexov_vert; i++)
<p>coord_vert [(ind_vert[i][0])-1] [0] «,»</p>
<p>coord_vert [(ind_vert[i][1])-1] [1] «,»</p>
<p>coord_vert [(ind_vert[i][2])-1] [2]  «,»</p>
<p>В качестве индекса текущего элемента указываем формулу, с помощью которой можно будет сортировать значения: второй индекс равен 0, следовательно,  мы работаем с осью Х;  для оси Y второй индекс будет равен 1, а для оси Z &#8211; 2. Вычитание же единицы из индекса производится потому, что в Си индексация элементов массива начинается с нуля,  а в ob- формате – с единицы. Таким образом, происходит построение нового файла с кодом, включая вывод блоков текстур и  нормалей.</p>
<p>Затем в конвертер 3D-моделей добавляется вывод:</p>
<p>glVertexPointer(3, GL_FLOAT, 0, pVerts1);</p>
<p>glNormalPointer(GL_FLOAT, 0, pNorm1);</p>
<p>glTexCoordPointer(2,GL_FLOAT, 0,  pTexCoord1);</p>
<p>glDrawArrays(GL_TRIANGLES,0,3);</p>
<p>И осуществляется проверка достижения конца файла. В случае неуспеха, означающего, что в файле есть описания других моделей, все действия повторяются для остальных моделей.</p>
<p>Подытоживая вышесказанное, можно сказать, что предложенный способ конвертации 3D-моделей из 3D-редакторов в программу с использованием Opengl имеет некоторые недостатки. Самый существенный из них – описание модели непосредственно в программном коде.  В результате, если моделей много (или они высокополигональные), то компиляция кода может быть очень долгой, что очень сильно затрудняет отладку. Но для небольших студенческих проектов, ориентированных на изучение возможностей визуализации с помощью графической библиотеки Opengl, данный вариант решения эффективен, понятен и удобен в применении.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://technology.snauka.ru/2014/01/2965/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
