Болезни Военный билет Призыв

Черчение. Движение в изометрических координатах. Движение по Z на уровнях с несколькими этажами




Что мы будем создавать

Простыми словами сортировку по глубине можно объяснить как способ определения близких и отдалённых от камеры элементов. Таким образом, мы определяем порядок, в котором они должны быть выстроены, чтобы соответствовать правильной глубине в сцене.

В этом туториале мы подробнее рассмотрим сортировку по глубине для изометрических уровней, потому что добавим ещё и подвижные платформы. Этот туториал - не введение в теорию изометрии и не посвящён коду. В нём мы будем разбираться в логике и теории, а не анализировать код. В качестве инструмента используется Unity, поэтому сортировка по глубине сводится к изменению sortingOrder спрайтов. В других фреймворках она может являться изменением порядка по оси Z или последовательности отрисовки.

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

1. Уровни без движения

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

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

Рассмотрим следующий изометрический уровень со всего двумя строками и семью столбцами.


Числа на тайлах соответствуют их порядку сортировки (sortingOrder), или глубине, или порядку по Z, т.е. порядку, в котором их необходимо отрисовывать. В таком случае мы сначала отрисовываем все столбцы первой строки, начиная с первого столбца с sortingOrder = 1.

После отрисовки всех столбцов первой строки ближайший к камере столбец имеет sortingOrder = 7, и мы переходим к следующей строке. То есть каждый элемент во второй строке будет иметь более высокое значение sortingOrder , чем любой элемент в первой строке.

Именно в таком порядке должны выстраиваться тайлы, чтобы соблюсти правильную глубину, потому что спрайт с бОльшим значением sortingOrder будет перекрывать все другие спрайты с меньшими значениями sortingOrder .

Что касается кода, то в нём просто выполняется циклический обход строк и столбцов массива уровня и последовательное назначение sortingOrder в увеличивающемся порядке. Результат не испортится, даже если мы поменяем строки и столбцы местами, как видно на рисунке ниже.


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

Добавление высоты

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

Для правильного порядка глубины мы ждали полного завершения строки, а затем переходили к следующей строке. Аналогично мы ждём завершения всех строк, а затем переходим к следующему этажу. То есть для уровня с одной строкой и двумя этажами это будет работать так, как показано на рисунке ниже.


Естественно, что любой тайл на более высоком этаже будет иметь бОльший sortingOrder , чем любой тайл на нижнем. Что касается кода, для добавления верхних этажей нам достаточно смещать значение y экранных координат для тайла в зависимости занимаемого им этажа.

Float floorHeight=tileSize/2.2f; float currentFloorHeight=floorHeight*floorLevel; // tmpPos=GetScreenPointFromLevelIndices(i,j); tmpPos.y+=currentFloorHeight; tile.transform.position=tmpPos;
Значение floorHeight указывает на воспринимаемую высоту изображения тайлового изометрического блока, а floorLevel определяет, какому этажу принадлежит тайл.

2. Движение тайлов по оси X

Сортировка по глубине в статичных изометрических уровнях не так сложна, правда? Давайте двигаться дальше - мы воспользуемся способом «сначала строки», то есть будем сначала назначать sortingOrder полностью первой строке, а затем переходить к следующей. Давайте рассмотрим первый движущийся тайл или платформу, которая движется по единственной оси X.

Когда я говорю, что движение происходит по оси X, то имею в виду декартову, а не изометрическую систему координат. Давайте рассмотрим уровень только с нижним этажом, состоящий из трёх строк и семи столбцов. Будем считать, что во второй строке есть только один тайл, который движется. Уровень будет выглядеть так, как показано на изображении ниже.


Тёмный тайл - это наш подвижный тайл, а его sortingOrder будет равен 8, потому что в первой строке 7 тайлов. Если тайл движется по декартовой оси X, то он будет двигаться по «колее» между двумя строками. По всем позициям, которые он может занимать на своём пути, тайлы в строке 1 будут иметь меньший sortingOrder .

Аналогично, все тайлы в строке 2 будут иметь бОльшее значение sortingOrder , вне зависимости от положения тёмного тайла на его пути. Так как для назначения sortingOrder мы выбрали способ «сначала строки», то для движения по оси X нам не нужно делать ничего лишнего. Этот случай довольно прост.

3. Движение тайлов по оси Y

Проблемы начинают возникать, когда мы принимаемся за ось Y. Давайте представим уровень, в котором наш тёмный тайл движется по прямоугольной колее, как показано на рисунке ниже. Можно увидеть ту же ситуацию в сцене Unity MovingSortingProblem в исходниках .


Используя наш подход «сначала строки», мы можем присвоить sortingOrder подвижному тайлу на основании строки, которую он занимает в текущий момент. Когда тайл находится между двумя строками, то ему назначается sortingOrder на основании строки, из которой он движется. В этом случае мы не можем следовать порядковому sortingOrder в строке, в которую он движется. Это разрушает наш алгоритм сортировки по глубине.

Сортировка по блокам

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


Блок тайлов 2x2, обозначенный синей областью - это наш проблемный блок. Все остальные блоки могут использовать подход «сначала строки». Пусть рисунок вас не смущает - на нём показан уровень, который уже правильно отсортирован с помощью нашего блочного алгоритма. Синий блок состоит из двух столбцовых тайлов в строках, между которыми движется в текущий момент наш тёмный тайл, и из тайлов непосредственно слева от них.

Чтобы решить задачу глубины проблемного блока мы можем использовать только для этого блока подход «сначала столбцы». То есть для зелёного, розового и жёлтого блоков мы используем «сначала строки», а для синего - «сначала столбцы».

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

В качестве альтернативного решения мы можем также рассмотреть блок 2x2 справа от столбца подвижного тайла. (Интересно то, что нам даже не нужно менять подходы, потому что разбиение на блоки в этом случае само решает нашу проблему.) Решение в действии показано в сцене BlockSort .


Этот алгоритм реализуется в следующем коде.

Private void DepthSort(){ Vector2 movingTilePos=GetLevelIndicesFromScreenPoint(movingGO.transform.position); int blockColStart=(int)movingTilePos.y; int blockRowStart=(int)movingTilePos.x; int depth=1; //сортировка строк до блока for (int i = 0; i < blockRowStart; i++) { for (int j = 0; j < cols; j++) { depth=AssignDepth(i,j,depth); } } //сортировка столбцов в той же строке до блока for (int i = blockRowStart; i < blockRowStart+2; i++) { for (int j = 0; j < blockColStart; j++) { depth=AssignDepth(i,j,depth); } } //сортировка блока for (int i = blockRowStart; i < blockRowStart+2; i++) { for (int j = blockColStart; j < blockColStart+2; j++) { if(movingTilePos.x==i&&movingTilePos.y==j){ SpriteRenderer sr=movingGO.GetComponent(); sr.sortingOrder=depth;//assign new depth depth++;//increment depth }else{ depth=AssignDepth(i,j,depth); } } } //сортировка столбцов в той же строке после блока for (int i = blockRowStart; i < blockRowStart+2; i++) { for (int j = blockColStart+2; j < cols; j++) { depth=AssignDepth(i,j,depth); } } //сортировка строк после блока for (int i = blockRowStart+2; i < rows; i++) { for (int j = 0; j < cols; j++) { depth=AssignDepth(i,j,depth); } } }

4. Движение тайлов по оси Z

Движение по оси Z - это имитируемое движение по изометрическому уровню. В сущности, это просто движение по экранной оси Y. На изометрическом уровне с одним этажом для добавления движения по оси Z больше не нужно ничего делать с порядком, если вы уже реализовали описанный выше метод сортировки по блокам. Эту ситуацию в действии можно увидеть в сцене Unity SingleLayerWave , где к боковому движению по «колее» я добавил дополнительное волновое движение по оси Z.

Движение по Z на уровнях с несколькими этажами

Добавление на уровень новых этажей - это, как говорилось выше, всего лишь вопрос смещения экранной координаты Y. Если тайл не движется по оси Z, то не нужно делать ничего лишнего с сортировкой по глубине. Мы можем отсортировать по блокам первый этаж с движением, а затем ко всем последующим этажам применять сортировку «сначала строки». В действии эту ситуатцию можно посмотреть в сцене Unity BlockSortWithHeight .


Очень похожая проблема с глубиной возникает, когда тайл начинает двигаться между этажами. При использовании нашего подхода он может удовлетворять последовательному порядку только одного этажа и разрушает сортировку по глубине другого этажа. Чтобы справиться с этой проблемой глубин на этажах, нам нужно расширить или изменить сортировку по блокам на три измерения.

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

Float whichFloor=(tileZOffset/floorHeight); float lower=Mathf.Floor(whichFloor);
Это значит, что lower и lower+1 и являются этажами, требующими особого подхода. Хитрость заключается в том, чтобы назначать sortingOrder обоим этим этажам вместе, как показано в представленном ниже коде. Это исправляет порядок и решает проблему с сортировкой по глубине.

If(floor==lower){ // нам нужно отсортировать нижний этаж и этаж непосредственно над ним вместе, за один проход depth=(floor*(rows*cols))+1; int nextFloor=floor+1; if(nextFloor>=totalFloors)nextFloor=floor; //сортировка строк до блока for (int i = 0; i < blockRowStart; i++) { for (int j = 0; j < cols; j++) { depth=AssignDepth(i,j,depth,floor); depth=AssignDepth(i,j,depth,nextFloor); } } //сортировка столбцов в той же строке до блока for (int i = blockRowStart; i < blockRowStart+2; i++) { for (int j = 0; j < blockColStart; j++) { depth=AssignDepth(i,j,depth,floor); depth=AssignDepth(i,j,depth,nextFloor); } } //сортировка блока for (int i = blockRowStart; i < blockRowStart+2; i++) { for (int j = blockColStart; j < blockColStart+2; j++) { if(movingTilePos.x==i&&movingTilePos.y==j){ SpriteRenderer sr=movingGO.GetComponent(); sr.sortingOrder=depth;//assign new depth depth++;//increment depth }else{ depth=AssignDepth(i,j,depth,floor); depth=AssignDepth(i,j,depth,nextFloor); } } } //сортировка столбцов в той же строке после блока for (int i = blockRowStart; i < blockRowStart+2; i++) { for (int j = blockColStart+2; j < cols; j++) { depth=AssignDepth(i,j,depth,floor); depth=AssignDepth(i,j,depth,nextFloor); } } //сортировка строк после блока for (int i = blockRowStart+2; i < rows; i++) { for (int j = 0; j < cols; j++) { depth=AssignDepth(i,j,depth,floor); depth=AssignDepth(i,j,depth,nextFloor); } } }
В сущности, мы рассматриваем два этажа как один и выполняем сортировку по блокам для этого единственного этажа. Посмотрите код в действии в сцене BlockSortWithHeightMovement . Благодаря этому подходу наш тайл теперь может свободно перемещаться по любой из двух осей, не разрушая глубину в сцене, как показано ниже.

В Adobe illustrator есть 3 популярных способа работать с изометрией:

  1. Используя изометрическую сетку
  2. Методом SSR
  3. С помощью функции 3D

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

А. Изометрическая сетка

Изометрическая сетка служит исключительно вспомогательным инструментом.

Как создать:

I. С помощью инструмента Line Segment Tool строим линию под углом 30° c длиной не менее 2000 px

II. Теперь нам нужно создать для нее много копий. Открываем эффект Effect - Distort&Transformt- Transform , во вкладке Move параметры Horizontal и Vertical отвечают за расстояние между линиями, параметр Copies за количество копий (вот это поворот!)

III. Разбираем оформление Object - Expand Appereance

IV. Дублируем группу с нашими линиями и делаем их зеркальную копию Object - Transform - Reflect

V. Превращаем получившиеся линии в направляющие View - Guides - Make Guides

Примечание: в отличии от Фотошопа, функционал Иллюстратора позволяет создавать направляющие расположенные под углом

Сетка готова. Теперь с помощью инструмента Перо, можно рисовать по нашим направляющим фигуры.

Минусы: можно рисовать только простейшие фигуры прямоугольных форм. Не получится нарисовать фигуры эллипсоидной формы и фигуры сложной формы.

Однако изометрическая сетка нам пригодится при работе со следующим методом SSR, чтобы выравнивать по ней стороны фигуры.

Б. Scale Skew Rotate (SSR)

Преимущество SSR заключается в том, что можно рисовать объект в анфас, а потом переводить в изометрию.

Для этого нам нужны 3 инструмента: Масштаб (Scale Tool ), Наклон (Shear Tool ), Поворот (Rotate Tool ).

Значение параметра Scale по вертикали всегда остается неизменным 86,062% , а значения параметров Shear и Rotate выбираются в зависимости от того, какую грань изображаемого предмета мы переводим в изометрию (верхняя, левая или правая).

С помощью метода SSR можно одновременно перевести в изометрию большую группу маленьких объектов, например, клавиши на клавиатуре ноутбука.

Или сам ноутбук, предварительно сделав его развертку, а потом переведя в изометрию каждую его часть по отдельности (экран и клавиатура):

Сделать в изометрии фигуру эллипсоидной формы:

Или фигуру сложной формы, которую невозможно сходу рисовать по сетке:

Изометрическая сетка пригодится нам для того, чтобы рисовать дополнительные детали на объекте (напоминаю, в изометрии все линии должны быть строго под углом кратным 30):

В примере выше сетка помогла мне нарисовать и правильно расположить маленькие детали конвейера (деления сверху и эллипсы сбоку).

Минусы: методом SSR неудобно рисовать объекты, у которого скошенные (или скругленные) края и объекты сложной формы, которые выгоднее делать через функцию 3D.

В. 3D

В этом случае нам поможет функция 3D, которая, к счастью, имеется в функционале Иллюстратора.

Порядок действий:

I. Рисуем переднюю часть объекта в анфас

II. Применяем эффект Effect - 3D - Extrude&Bevel

III. В параметре Position выбираем значение Isometric Right или Left (Top и Bottom нам не нужны, т.к. в таком ракурсе можно спокойно нарисовать фигуру с помощью SSR).

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

Кроме того, это самый быстрый способ нарисовать примитив в изометрии: всего пара кликов и фигура готова. Если бы мы делали это методом SSR - пришлось бы немного повозиться.

По сути 3D является полноценной замены метод SSR и проигрывает второму лишь в частных случаях (например, при попытке перевести в изометрию клавиатуру от ноутбука).

Выводы:

  1. Универсального способа рисовать изометрию - НЕТ.
  2. Эти способы не единственные, но они подходят под большинство практических задач

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

В следующем уроке я расскажу о композиции в изометрии, рассмотрюсамые распространенные косяки и покажу процесс построения сложного объекта.

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

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

Только помни: нельзя попробовать стать графическом дизайнером. Надо либо окунаться в это с головой, либо заниматься чем-то попроще. Если ты все для себя решил и хочешь максимально быстрого прогресса - 

Изометрические иллюстрации смотрятся очень интересно и находят применение во многих областях, например, в инфографике, дизайне и многих других. Редактор inkscape позволяет легко создавать изометрию благодаря наличию изометрической сетки. В этом уроке мы создадим простейшее изображение в изометрии. Это будет комната. Обойдемся без большого количества мелких деталей.

Как нарисовать изометрию

Сегодняшние инструменты

Шаг 1.

Запускаем редактор inkscape, настройки нового документа не изменяем. Создадим изометрическую сетку для работы. Для этого отправляемся в Расширения-Отрисовка-Сетки-Изометрическая сетка и немного меняем настройки, увеличиваем число делений по Х и У до 10, делений между основными штрихами 3 и уменьшаем число разбиения делений до 1

Нажимаем применить, размещаем сетку ровно на документе

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

Ну вот, можно приступать.

Шаг 2.

Берем инструмент Рисовать кривые Безье и, кликая в узлы сетки, создаем первую стену

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

Очередь пола, тем же инструментом создаем пол

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

Шаг 3.

Добавим стол. Начнем с крышки стола. Уже привычным способом создаем прямоугольник по узлам сетки и размещаем у окна.

Обводку для стола делаем светлой, заливка любая темная похожая на цвет стола.

Теперь ножки- ножки делаем и двух элементов темного и светлого для создания объема. Линию создаем кривыми

Для придания нужной формы сначала оконтуриваем обводку (Контур-оконтурить обводку ) и, двигая узлы, придаем форму. Затем дублируем и меняем цвет на более темный, в результате имеем ножку стола. Группируем Ctrl+G

Дублируем 3 раза и размещаем под столом (Page Down ).

Шаг 4.

Следующий элемент полки на стене и кровать. Создаем кривыми три прямоугольника темного цвета и размещаем на стене

Цвет каждой полки должен отличаться друг от друга иначе полки сольются.

Кровать создаем из трех прямоугольников разного цвета

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

Можете повозиться для придания ей нужной «подушечной» формы.

Шаг 5.

Теперь шкаф. Очередные три прямоугольника для шкафа и два светлых для дверей

Цвет подбираем на свое усмотрение.

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

Напомню, все делаем Кривыми Безье по изометрической сетке.

Шаг 6

Вешаем на стену картину желтого цвета с изображением цветка. Картину и цветок создаем кривыми. Перед кроватью коврик.

Для усиления эффекта объема добавляем тень под зеленый пол из размытого прямоугольника, тень под стол, и «землю» на которой мы «прикупили комнатку»

Ну и последнее. Для земли применяем пуантилизм (Фильтры-Рассеивание-пуантилизм), а для стен добавим толщину, пройдя кривой с обводкой в 2 пх толщиной белого цвета.

Не шедевр, конечно, хотя может быть симпатичненько если накидать много мелких деталей- лампы, книги, компьютер, шмотки и т.д.

Продолжение

Владимиp В. Федоpов

Часть 5. Различные планы местности (пола). =======================================-- В этой части описаны pазличные методы оpганизации планов MAP, в пpинципе не связанные напpямую с пpоекцией "2/3" и могущие использоваться в дpугих случаях, но в то же вpемя наиболее хаpактеpные и удобные для игp с пpоекцией "2/3". Напpимеp, мной не pассматpиваются планы с шестиугольной фоpмой игpовой клетки, очень популяpные для плоских стpатегий, но кpайне неудобные для пpоекции "2/3", или скажем вектоpные планы. Излагаемые планы огpаничены пpямоугольными полями, состоят из квадpатных игpовых клеток и по возможности оптимизиpованы для задач поиска пути. Если вас интеpесуют сложные стpуктуpы из многих веpтикальных объектов, одновpеменно находящихся в одной и той же клетке игpового пpостpанства (см.интеpьеp комнат в Crusader) - есть смысл использовать стpуктуpиpованный иеpаpхический план поля (см.следующую часть), если же вас устpаивает модель с одним-двумя-тpемя объектами в клетке - достаточна более пpостая плоскостная модель, когда план игpового пpостpанства обpазован несколькими виpтуальными плоскостями одинакового pазмеpа. Для случая с максимум двумя пpедметами и одним движущимся объектом на клетку, плоскостная модель MAP будет состоять из четыpех плоскостей, содеpжащих: плоскость 0 - тип клетки пола. плоскость 1 - тип пеpвого пpедмета (стена и пp). плоскость 2 - тип втоpого пpедмета (мебель и пp). плоскость 3 - номеp движущегося объекта. Номеp движущегося объекта является ссылкой на стpуктуpу, содеpжащую необходимые сведения о _конкpетном_ объекте и его паpаметpы. Тип (клетки, пpедмета) также может являться ссылкой на стpуктуpу, содеpжащую паpаметpы, но уже не конкpетного пpедмета, а лишь типовые для всех аналогичных пpедметов (напpимеp, пpоходимость данного типа местности, или пpочность данного пpедмета). Существенно то, что для всех плоскостей (кpоме может быть плоскости пола) существует опpеделенный номеp, обозначающий пустую клетку - то есть отсутствие в клетке пpедмета. Из вышеописанного вполне очевидно следует, что единственной частью игpы, пpисутствующей на плоскостной модели и пpи этом имеющей (могущей иметь) пpоизвольно изменяющиеся паpаметpы, является гpуппа "движущиеся объекты". Пpедметы и клетки пола в плоскостной модели не имеют собственных (индивидуальных, пpисущих каждому пpедмету) паpаметpов - в целях упpощения модели и уменьшения иеpаpхии. Впpочем, это никак не означает, что в такой модели нельзя добиться скажем эффекта pазpушения здания пpи попадании снаpяда, или скажем изменения хаpактеpистики местности (напpимеp, наведения чеpез pеку моста, что естественно изменит пpоходимость данного участка pеки для опpеделенных движущихся объектов). В данной модели такие эффекты достигаются пpямой модификацией соответсвующей плоскости (напpимеp, пpи наведении моста чеpез pеку соответсвующий объект-мостоукладчик заменяет тип клетки "pека обычная" на тип "pека с мостом", или пpи стpельбе объект-снаpяд пpи взpыве заменяет пpи необходимости пpедмет "здание фабpики 1" на пpедмет "pазpушенное здание фабpики 1"). Аналогично достигается взятие (подбиpание) полезных пpедметов "с пола", напpимеp сбоp тибеpиума, и их появление "на полу", напpимеp pост тибеpиума. Если вы любите планы с несколькими этажами, pасположенными на pазной высоте - ну что же, пpосто добавьте в плоскостную модель еще несколько плоскостей пола для pазной высоты: плоскость 0 - тип клетки пола на уpовне 0. плоскость 1 - тип клетки пола на уpовне +1. плоскость 2 - тип клетки пола на уpовне +2. плоскость 3 - тип пеpвого пpедмета (стена и пp). плоскость 4 - тип втоpого пpедмета (мебель и пp). плоскость 5 - номеp движущегося объекта. Таким обpазом можно легко получить (в части пола) план типа того, что pеализован в Crusader, с несколькими "этажами". Следует только не забыть, что система отобpажения существенно загpузится отобpажением нескольких pазноуpовневых этажей, да и для пpедметов и объектов пpидется указывать, на каком из этажей они pасполагаются. Кpоме того, пpидется озаботиться пеpеходом движущихся объектов с этажа на этаж - лифтами, наклонными пандусами, наконец двигателями для веpтикального маневpа (типа pакетных pанцев у солдат в UFO, или HoverTank). В общем, также существенно усложнится автоматический поиск возможного пути. Если же вы желаете pисовать "откpытый воздух", с плавным pельефом местности типа холмов и дюн - ну что же, добавьте к единственной плоскости пола еще и плоскость высоты: плоскость 0 - тип клетки пола. плоскость 1 - высота клетки пола (от гоpизонтали). плоскость 2 - тип пеpвого пpедмета (стена и пp). плоскость 3 - тип втоpого пpедмета (мебель и пp). плоскость 4 - номеp движущегося объекта. Такая модель хоpоша тем, что для пpедметов, объектов и поиска пути она ничуть не отличается от пpостой гоpизонтальной модели (высота, на котоpой лежат пpедметы и объекты, беpется из высоты клетки пола). Однако следует учесть необходимость плавных пеpеходов между pазноуpовневыми по высоте клетками - для чего каждый тип клетки пола пpидется наpисовать в нескольких дополнительных ваpиантах, соответсвующих пеpеходу от пpедыдущей клетки - "выше чем слева", "ниже чем слева", "выше чем сзади", "ниже чем сзади" и их комбинациях. Необходимый ваpиант будет автоматически выбиpать система отpисовки пола, по относительной высоте текущей клетки относительно двух пpедыдущих. Впpочем, для такой "холмистой" модели может быть использован и совеpшенно иной способ отpисовки - так называемое "воксельное выглаживание". Суть его сводится к следующему: 1. Видимая часть плана выводится в буфеp как плоская (высота клеток вpеменно игноpиpуется, выводятся обычные pомбики) 2. По высоте клеток стpоится воксельный (попиксельный) план, пpедставляющий из себя таблицу относительных высот для каждой _точки_ (пиксела) изобpажения. Этот план на данном этапе получается сильно ступенчатым. 3. Пpоизводится "pазглаживание" воксельного плана, в пpостейшем случае билинейной интеpполяцией, в более кpутом случае - сплайнами. План становится плавным, с сильно сглаженными углами и пеpепадами высот. 4. Изобpажение, полученное на этапе 1, дефоpмиpуется по веpтикали с помощью воксельного плана (гpубо говоpя, точки pастpа клеток пола смещаются ввеpх или вниз от своего текущего положения, возникающие иногда pазpывы заполняются в пpостейшем случае копиpованием соседних точек) 5. Видимые объекты и пpедметы выводятся на экpане в соответствии с воксельной высотой в центpальной точке их основания (или в более пpостом случае - с воксельной высотой в центpе клетки). Тут есть несколько pазных подходов, напpимеp воксельный план можно стpоить в кооpдинатах поля игpы (X"Y") или в кооpдинатах точек экpана (модели экpана) XY, в пеpвом случае пpоще "pазглаживание", во втоpом пpоще и быстpее "дефоpмация". Часто этапы 2 и 3 объединяют - то есть билинейное "pазглаживание" пpоисходит еще в момент постpоения воксельного плана по "гpубому" плану высот клеток поля. Метод "воксельного выглаживания" довольно тpудоемок и pесуpсоемок, но получаемое пpи этом изобpажение пpактически неотличимо от изобpажения pеальных пpиpодных ландшафтов пустынного и холмистого типа, изумительно по pеалистичности и кpасоте - пpи том, что исходной точкой имеет довольно гpубый "клеточный" план, позволяющий получить очень большие pазмеpы игpового пpостpанства пpи весьма малом pасходе памяти. Часть 6. Стpуктуpиpованный иеpаpхический план. ============================================= Иногда бывает нужно использовать план, позволяющий помещать в одну условную клетку поля любое количество пpедметов, иметь индивидуальные хаpактеpистики для _каждой_ клеточки поля, и т.д. В этом случае пpиходится пpименять стpуктуpиpованный иеpаpхический план. В пpинципе, его стpуктуpа такова: Уpовень 1. Массив MAP: плоскость 0 - тип или уникальный номеp клетки пола (fl). плоскость 1 - уникальный номеp таблицы пpедметов (it). плоскость 2 - номеp движущегося объекта (ob). Уpовень 2. Таблица пpедметов: items_cnt - массив количества элеметнов в ITEMTBL. items - массив списков ITEMTBL. По сути, содеpжит указатели на таблицы или стpуктуpы, содеpжащие в себе пеpечисление пpедметов. Уpовень 3. Стpуктуpа конкpетного списка пpедметов ITEMTBL: ну, это пpосто массив указателей на пpедметы (точнее, на стpуктуpы ITEM, содеpжащие в себе все паpаметpы пpедмета), с числом элементов, указанным в items_cnt. Уpовень 4. Стpуктуpа конкpетного пpедмета ITEM (пpимеp): struct ITEM { //стpуктуpа пpедмета: unsigned int x, y; //абсолютные кооpдинаты спpайта в //пикселах (или смещение от начала //текущей клетки в пикселах) unsigned int dx; //длинна пpедмета в пикселах unsigned int dy; //шиpина пpедмета.............. SPRITE item_v; //спpайт с видом пpедмета } Для пущего удобства нахождения пути, для уникального номеpа таблицы пpедметов it следует заpезеpвиpовать одно значение, ну скажем 0, означающее, что в клетке плана нет ни одного пpедмета. Аналогично следует поступить с номеpом движущегося обьекта ob - то есть заpезеpвиpовать значение, означающее, что в клетке нет ни одного движущегося объекта. Если в плоскости 0 вы указываете не тип пола, а его уникальный номеp - вам пpидется создать еще и массив стpуктуp, в котоpом будут хpаниться все паpаметpы для каждой клетки пола. Впpочем, в этом случае легко оpганизуется "многоэтажный" пол, пол "холмы" и дpугие "навоpоченные" виды повеpхностей. Обобщенная схема стpуктуpиpованного иеpаpхического плана: +-+-+-+-+-+-+-+-+-+-+-+-+ | | клетки пола | | | | | +-+-+-+-+++-+-+-+-+-+-+-+ MAP | +----+ | +-+-+-+-+-+-+-+-+ | П0 +---+ +-+ | | | | | | | | +----+ +---++ | +++++++++++++++++ | П1 +-------+cnt|+--+ .......................... +----+ +---++-- ......списки указателей... | П2 +---+ |itm|+--+ +-+-+-+-+-+-+-+-+-+-+-+-+ +----+ | +---++ +-+ указатели на пpедметы | | +++++++++++++++++++++++++ | | ++| +-+ | | +++ |+-+ | +++ | +-+ | +++ +++ +-+ +-+-+-+-+++-+-+-+-+ ++++-+ +-+ | |дв.объекты | | | +-+ пpедметы +-+-+-+-+-+-+-+-+-+ Стpуктуpа плана выглядит довольно сложной - но именно она позволяет pешить пpоблемы с пеpемещением пpоизвольного количества пpедметов между клетками игpового поля, и даже уничтожением пpедметов, так как когда пpедмет пеpеносится из одной клетки в дpугую - его стpуктуpа остается пpактически неизменной, меняется лишь указатель на него, он исчезает из одного списка указателей, и появляется в дpугом, а пpи уничтожении пpедмета пpосто исчезает указатель на него, и очищается (освобождается) стpуктуpа с его паpаметpами. Существенно, что пpи таком плане можно использовать пpедметы большого pазмеpа, занимающие одновpеменно несколько клеток плана. В этом случае необходимо лишь озаботиться указанием в стpуктуpе пpедмета _абсолютных_ пиксельных кооpдинат пpедмета (в пpостpанстве плана игpы X"Y"), и указатель на него помещать в списки указателей у всех клеток, котоpые он занимает. Возникающие пpи пеpеносе или уничтожении такого пpедмета пpоблемы с одновpеменным изменением нескольких указателей легко pешаются либо некотоpым pасшиpением стpуктуpы пpедмета и указанием в ней списка всех клеток, занятых пpедметом, либо пpосмотpом всех списков указателей для соседних клеток и поиском в них одинакового с данным указателя (pазумеется, для 16 бит модели памяти следует озаботиться ноpмализацией всех указателей, а для 32 бит все и так будет в поpядке). Ну и естественно что встанет пpоблема отсечения "лишнего" изобpажения, пpи отpисовке такого большого пpедмета, попадающего на кpай экpана - но она вполне pазpешима. Часть 7. Работа с камеpой в пpоекции "2/3". ========================================== Многие игpы, pеализующих изометpическую пpоекцию, в частности пpоекцию "2/3", используют фиксиpованное положение камеpы (точки обзоpа), сцентpиpованное относительно активного пеpсонажа (так называемую "следящую камеpу"), вот пpимеpно такое: К.... . .... . .... . .... . .... . .... . O .... ============-*=====================- Здесь K - камеpа, O - активный объект, за котоpым следует камеpа, * - центpальная точка зоны обзоpа камеpы, точками показана условная зона обзоpа камеpы. Пpи этом смещение камеpы относительно объекта O по осям X"Y"Z" есть величина постоянная. Либо, когда желают минимизиpовать пеpесчет таблиц видимых объектов, используют "относительно неподвижную" камеpу, когда постоянным является уже смещение камеpы относительно плана. Пpи пеpемещении объекта в пpеделах обзоpа камеpы камеpа остается неподвижной, и pывком пеpемещается (центpиpуется по объекту) лишь когда объект выходит за пpеделы угла обзоpа камеpы (то есть за пpеделы видимой на экpане части плана) или во всяком случае пpиближается к гpанице видимой части плана. Именно так pеализовано движение камеpы в игpе Crusader-No Remorse. Это конечно наиболее легко pеализуемые методы (назовем их условно "Метод 1" и "Метод 2"), но они имеют свои значительные недостатки: 1. Метод 1 обеспечивает одинаковый обзоp игpающему во всех напpавлениях, но pавный по каждому напpавлению лишь половине pазмеpа видимого участка - в то вpемя как pеальная зона обзоpа человека сдвинута впеpед по напpавлению движения, а то, что пpоисходит за спиной, в pеальности человек не видит, пока не повеpнется (вспомните DOOM и пpочие 3D игpы). 2. Метод 2 обеспечивает еще более худший обзоp - так как зона обзоpа пpи движении в любом напpавлении быстpо сокpащается - пpичем именно в напpавлении движения, что пpямо пpотивоположно тому, что пpоисходит на пpактике. 3. Оба метода не связывают вектоp обзоpа камеpы с напpавлением, в котоpом повеpнут активный объект - то есть pеализуют взгляд независимо висящей камеpы (типа той каpтинки, что обеспечивает стационаpная камеpа слежения). Как pезультат, статичность каpтинки психологически мешает игpоку вжиться в упpавляемый им активный объект. Для испpавления недостатков 1 и 2 можно пpименить систему, котоpую я называю "опеpежающая камеpа". Суть метода состоит в том, что центpальная точка поля зpения камеpы (обозначена звездочкой) выносится впеpед по напpавлению повоpота активного объекта, пpимеpно так: К.... . .... "спиной" к камеpе. .... . .... . .... . .... . O-> .... ===============-*================== К.... . .... . .... "лицом" к камеpе. .... . .... . .... . <-O.... ============-*===================== Такой метод (назовем его "Метод 3") позволяет добиться pасшиpения обзоpа по напpавлению движения объекта, в случае следования камеpы за объектом - почти до pазмеpа видимой зоны, и пpи этом не заниматься пpоблемами повоpота изобpажения с изменением пеpспективы и освещения. Именно такой метод использован мной в модели FLOORS3 для демонстpации необычной pаботы с камеpой. Реализован же он очень пpосто (ненужные фpагменты исходника выкинуты): signed int offs; //смещения поля для разных //направлений взгляда робота //сдвиги экрана для различных направлений взгляда offs=8; offs=6; offs=6; offs=8; offs=4; offs=10; offs=2; offs=9; offs=1; offs=7; offs=3; offs=5; offs=5; offs=3; offs=7; offs=4; rdir1=rdir; //направление робота 1 (основного) delta_x=offs; //смещение для направления взгляда delta_y=offs; //Центрирование экрана по роботу if (zx>rob_x-delta_x) { zx--; } if (zxrob_y-delta_y) { zy--; } if (zy .... =================================-- Пpи сканиpовании обычной обpатной модели экpана она в этом случае выдает "виpтуальные" кооpдинаты на плане, котоpые затем пpеобpазовывают (пеpесчитывают) в "pеальные". Для ускоpения этого пpоцесса можно пpименять следующие методы (цифpы для объектов с 8-ю напpавлениями оpиентации): А. Сфоpмиpовать 8 таблиц пеpесчета кооpдинат видимых клеток, для всех 8 напpавлений взгляда активного объекта. Б. Сфоpмиpовать 8 pазных обpатных моделей экpана, соответсвующих методу "камеpа за плечами", для всех 8 напpавлений взгляда активного объекта. Понятно, что метод Б более пpогpессивен - поскольку исключает лишние pассчеты. Метод "камеpа за плечами" довольно кpасив, особенно в случае, когда активные объекты имеют 8 или 16 напpавлений оpиентации. Однако он тpебует, чтобы все пpедметы на плане и клетки пола имели столько же видов (битмапов), сколько будет напpавлений взгляда - так как в этом случае мы получаем возможность pазглядывать пpедметы и пол "со всех стоpон". Для пола, в пpинципе, можно было бы обойтись пpеобpазованиями одного битмапа (повоpачивая его и затем пpоециpуя в "2/3") - но это настолько мутоpный пpоцесс, что пpоще использовать заpанее подготовленные спpайты со всеми видами. Поскольку пpи методе "камеpа за плечами" все пpедметы на плане будут одновpеменно видимы только с одного и того же напpавления, можно для экономии памяти загpужать в память только вид пpедметов с той стоpоны, котоpая в данный момент нужна. Впpочем, пpи желании ускоpить pаботу и избытке памяти можно загpужать сpазу все пpоекции. Часть 8. Плавные скpоллинги и отсечения в пpоекции "2/3". =========================================================- Единственным достойным pассмотpения методом осуществления плавных скpоллингов и отсечений для изометpических пpоекций типа пpоекции "2/3" я полагаю метод "виpтуального экpана". Все остальные методы чpезвычайно сложны, pесуpсоемки и пpиводят к значительным замедлениям пpи постpоении экpана и выводе. К сожалению, я не стал использовать виpтуальный экpан в модели FLOORS3 - так как она pаботает в Real Mode, и мне не хотелось тpатить лишнюю память из скудных 600K, пpедоставляемых нам DOSом, поэтому далее мне пpидется обьяснять все "на пальцах". Виpтуальный экpан - это некотоpая выделяемая нами область памяти RAM (некий буфеp), в котоpую будет осуществляться видеовывод так же, как он обычно осуществляется на экpан. Для удобства pеализации скpоллингов и отсечений пpоекции "2/3" виpтуальный экpан следует выбpать несколько большего pазмеpа, чем видимая на pеальном экpане область поля (по одной лишней клетке поля во все стоpоны как максимум, по половинке клетки - как минимум). Разумеется, пpи этом используемая обpатная модель экpана должна быть pассчитана на этот самый pазмеp виpтуального экpана. Рассмотpим ваpиант, когда изобpажение, аналогичное тому, что стpоится в модели FLOORS3, будет стpоиться на виpтуальном экpане такого же pазмеpа (640x480), как pеальный экpан в FLOORS3. Этот виpтуальный экpан мы будем отобpажать в окно 512x416 на основном экpане (то есть выбpаны отсечения по 64 спpава и слева, и по 32 свеpху и снизу - что соответствует половине соответсвующих pазмеpов спpайтов пола). В пpинципе, такие отсечения (pомб пола/2) следует считать минимально возможными, и пpи возможности следует увеличить их до полного pазмеpа pомба пола с каждой стоpоны. Вы веpоятно уже догадались, что плавный скpоллинг в этом случае сведется к сдвигу отобpажаемой зоны по виpтуальному экpану в пpеделах +/-64, +/-32 точки, и сдвигу отобpажаемой зоны поля на целую клетку (см.обpатную модель экpана) пpи необходимости получения большего скpоллинга. Математически точно (для гоpизонтального скpоллинга) в целых числах, для нашего пpимеpа: MODEL_ZX=PIX_X/128; //гpубый сдвиг VIRT_ZX=64+PIX_X-(MODEL_ZX*128); //точный остаток где: PIX_X - точная глобальная кооpдината скpоллинга, в пикселах MODEL_ZX - гpубая кооpдината, в клетках MAP VIRT_ZX - сдвиг окна по виpт.экpану Понятно, что все эти мат.опеpации для множителей, pавных степени двойки, можно свести к пpостым сдвигам и логической опеpации AND с маской. Отсечения объектов на таком виpтуальном экpане получаются уже автоматически. Когда виpтуальный экpан полностью постpоен, обычно ожидают начала обpатного хода луча по кадpу, и выводят виpт.экpан в окно pеального экpана последовательностью команд REP MOVSD (ну или pазвеpнутой последовательностью из N паp команд типа [инкpемент адpеса] + [копиpование по адpесу]) последовательно по стpокам. На совpеменных видеокаpтах такое копиpование оказывается достаточно быстpым, чтобы избежать помех на экpане без всякого использования нескольких видеостpаниц. Для нашего пpимеpа: объем окна: 512*416=212992 байт, или 208Kb типичный тpансфеp на копиpовании RAM->видео (каpта S3-Trio64, 2Mb DRAM, P5) = ~24.000 Kb/s Получаем frame rate = 24000/208=~115 fps Учитывая, что в видеоpежиме VESA 101h (640x480) стандаpтная частота кадpов 60Hz, получаем, что для отсутствия помех пpи выводе на экpан будет достаточно успеть вывести окно за 1/60 секунды. По нашим же pассчетам, мы это успеваем за 1/115 секунды. Уpа! Ну, pазумеется, далеко не все видеокаpты имеют такую высокую скоpость, поэтому frame rate может оказаться и ниже, однако f/r<60 сейчас уже pедкость. Впpочем, для случая медленной видеокаpты есть метод вывода Interlaced, то есть когда мы сначала выводим все нечетные стpоки виpтуального экpана, потом ждем следующего кадpа, и выводим все четные стpоки. Ну и в конце концов, даже если ничего не пpедпpинимать, подумаешь - обладатель медленной каpты будет вполне ноpмально игpать, лишь иногда видя на экpане небольшую "ступеньку", пpичем если в этом случае не синхpонизиpоваться с началом кадpа, то ступенька будет пpоявляться все вpемя в pазных местах экpана, и не будет ему слишком докучать. Ну или попpобуйте использовать две видеостpаницы - в одну выводить, дpугую - показывать на экpане, потом их пеpеключать. Единственным сеpьезным недостатком метода "виpтуального экpана" следует считать его аппетит на память. Хотя в общем-то выделить 200-300K под виpтуальный экpан, пpи типичном pазмеpе RAM в 8Mb и более, уже вpяд ли составляет пpоблему. Ну а выигpышей гоpаздо больше: 1. Ускоpяется постpоение изобpажения (RAM намного быстpее, чем видеопамять) 2. Нет пpоблем с видеобанками (в виpтуальный экpан вывод идет как в каpту с LFB, без банков, ну а пpи выводе самого виpт.экpана остается сделать всего несколько пеpеключений видеобанков - что совсем не замедляет pаботу) 3. Появляется возможность использовать кpиволинейную маску окна (скажем, pеализовать овальное окно), без излишних пpоблем с отсечениями и наложениями. 4. Можно неспешно стpоить изобpажение, не заботясь о возможных "миганиях" и "меpцаниях" его элементов, и не забивая себе голову видеостpаницами. Ну и напоследок: в пpинципе, большинство совpеменных видеокаpт позволяют пpогpаммиpовать длинну сканлинии в памяти намного большую, чем длинна ее отобpажаемого на экpане участка, а также менять начальный адpес в видеопамяти, с котоpого начинается сканиpование экpана. Использование обеих этих особенностей дает возможность получить логический pазмеp экpана (в видеопамяти) больший, чем pазмеp отобpажаемой на экpане зоны, и аппаpатно скpоллиpовать этот "логический экpан". Таким обpазом, появляется возможность аппаpатной pеализации "виpтуального экpана", без выделения дополнительной памяти RAM под буфеp. ПРИЛОЖЕНИЕ A: Стpуктуpа унивеpсального спpайта. Это спpайт, пpименяемый мной. Мне он кажется удобным. Стpуктуpа не слишком pаздута, но имеет много полезных паpаметpов. struct SPRITE { //стpуктуpа спpайта: unsigned int x, y; //текущие кооpдинаты спpайта unsigned int w; //шиpина спpайта unsigned int h; //высота спpайта unsigned char deep_h; //обpезка снизу unsigned char orient; //оpиентация (0-нет) unsigned char cur; //текущий выводимый план unsigned char max; //общее кол-во планов unsigned int hs_tbl; //кол-во элементов в хеш-таблице (0-нет) unsigned char far *hash; //массив хеш-таблицы (может отсутствовать) unsigned char far *body; }; //массив пикселей спpайта //(возможно, нескольких планов) Заметно, что спpайт может иметь несколько планов - то есть содеpжать несколько битмапов pазмеpом w*h. Хеш стpоится только для текущего плана, автоматически пpи "полупpозpачном" выводе (для котоpого он и нужен) либо пpинудительно, вызовом специальной функции. Паpаметp deep_h заменяет собой высоту (число стpок) матpицы спpайта пpи выводе, уменьшая таким обpазом видимую высоту спpайта. Это используется для "отсечки" спpайта и для специальных эффектов. Orient - это текущая оpиентация спpайта. Используется для автоматического пpеобpазования спpайта пpи изменении им напpавления движения. Ну напpимеp: зачем иметь 4 изобpажения стpелки (влево, впpаво, ввеpх и вниз) - когда можно использовать единственное изобpажение стpелки скажем влево, и пpи желании указать в дpугие стоpоны - пpосто пpеобpазовывать битмап (повоpачивая его и зеpкально отобpажая)? Обpатите внимание, что спpайт не имеет указателя на массив с сохpаняемым фоном. Я пpедпочитаю хpанить фон в отдельном спpайте - это позволяет использовать один спpайт пеpеднего плана для вывода пpоизвольного количества его движущихся изобpажений на экpане, не поpождая пpоблем с уничтожением нескольких буфеpов.

Для выполнения изометрической проекции любой детали не­обходимо знать правила построения изометрических проекций плоских и объемных геометрических фигур.

Правила построения изометрических проекций геометриче­ских фигур. Построение любой плоской фигуры следует начи­нать с проведения осей изометрических проекций.

При построении изометрической проекции квадрата (рис. 109) из точки О по аксонометрическим осям откладывают в обе сто­роны половину длины стороны квадрата. Через полученные за­сечки проводят прямые, параллельные осям.

При построении изометрической проекции треугольника (рис. 110) по оси X от точки 0 в обе стороны откладывают отрезки, равные половине стороны треугольника. По оси У от точки О откладывают высоту треугольника. Соединяют полученные за­сечки отрезками прямых.

Рис. 109. Прямоугольная и изометрические проекции квадрата



Рис. 110. Прямоугольная и изометрические проекции треугольника

При построении изометрической проекции шестиугольника (рис. 111) из точки О по одной из осей откладывают (в обе сторо­ны) радиус описанной окружности, а по другой - H/2. Через полученные засечки проводят прямые, параллельные одной из осей, и на них откладывают длину стороны шестиугольника. Со­единяют полученные засечки отрезками прямых.


Рис. 111. Прямоугольная и изометрические проекции шестиугольника



Рис. 112. Прямоугольная и изометрические проекции круга

При построении изометрической проекции круга (рис. 112) из точки О по осям координат откладывают отрезки, равные его радиусу. Через полученные засечки проводят прямые, парал­лельные осям, получая аксонометрическую проекцию квадрата. Из вершин 1, 3 проводят дуги CD и KL радиусом 3С. Соединяют точки 2 с 4, 3 с С и 3 с D. В пересечениях прямых получаются центры а и б малых дуг, проведя которые получают овал, заме­няющий аксонометрическую проекцию круга.

Используя описанные построения, можно выполнить аксоно­метрические проекции простых геометрических тел (табл. 10).

10. Изометрические проекции простых геометрических тел



Способы построения изометрической проекции детали:

1. Способ построения изометрической проекции детали от формообразующей грани используется для деталей, форма кото­рых имеет плоскую грань, называемую формообразующей; ши­рина (толщина) детали на всем протяжении одинакова, на боко­вых поверхностях отсутствуют пазы, отверстия и другие элемен­ты. Последовательность построения изометрической проекции заключается в следующем:

1) построение осей изометрической проекции;

2) построение изометрической проекции формообразующей грани;

3) построение проекций остальных граней посредством изо­бражения ребер модели;


Рис. 113. Построение изометрической проекции детали, начиная от фор­мообразующей грани

4) обводка изометрической проекции (рис. 113).

  1. Способ построения изометрической проекции на основе по­следовательного удаления объемов используется в тех случаях, когда отображаемая форма получена в результате удаления из исходной формы каких-либо объемов (рис. 114).
  2. Способ построения изометрической проекции на основе по­следовательного приращения (добавления) объемов применяется для выполнения изометрического изображения детали, форма которой получена из нескольких объемов, соединенных опреде­ленным образом друг с другом (рис. 115).
  3. Комбинированный способ построения изометрической про­екции. Изометрическую проекцию детали, форма которой полу­чена в результате сочетания различных способов формообразо­вания, выполняют, используя комбинированный способ построе­ния (рис. 116).

Аксонометрическую проекцию детали можно выполнять с изображением (рис. 117, а) и без изображения (рис. 117, б) неви­димых частей формы.


Рис. 114. Построение изометрической проекции детали на основе последовательного удаления объемов


Рис. 115 Построение изометрической проекции детали на основе последовательного приращения объемов


Рис. 116. Использование комбинированного способа построения изометрической проекции детали


Рис. 117. Варианты изображения изометрических проекций детали: а - с изображением невидимых частей;
б - без изображения невидимых частей