Что такое геодезический купол. Мастер-класс «Новогодние шары» из бумаги своими руками

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

В этой статье мы постараемся описать что такое простыми словами. По сути – геодезический купол – это сетка, построенная из множества “граней” (многогранников), максимально близкая к форме сферы.

Если приглядеться, то именно треугольники стали основой сетки, а не ромбы, квадраты или шестигранники. Треугольник был выбран как самая стабильная и прочная геометрическая структура из всех известных. И поэтому, структура из треугольников (в нашем случае геокупол), очень прочная и обладает самонесущими способностями. Она “держит” сама себя, являясь целостной структурой. Чем больше граней мы используем для построения, тем прочнее наша сетка, и более сглажена форма.

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

В основе построения геодезического купола лежат Платоновы Тела, всего которых насчитывается пять, но мы рассмотрим детально только Икосаэдр, как наиболее распространенный вариант. Икосаэдр – это правильный многогранник, состоящий из 30 одинаковых ребер, которые создают 20 равносторонних треугольников.

Итак, рассмотрим построение геодезического купола поэтапно:

1. Для начала мы строим сферу с заданным радиусом


3. Т.к. все треугольники в икосаэдре равны, мы выбираем любой из них и разбиваем его на более мелкие равносторонние треугольники. В нашем случае разбивка происходит в пятой частоте (об этом пойдет речь позже). Выбранный изначальный треугольник икосаэдра делиться на 5 “рядов” более мелких треугольников. Так получается наша “плоская” разбивка сетки.

4. На этом этапе мы строим отрезки исходящие из центра сферы. Эти отрезки должны проходить через точки соединения получившейся сетки и заканчиваться на поверхности сферы.

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


Частота триангуляции геодезического купола

Понятие “частота” или “частота триангуляции” часто встречается в расчетах геокупола. Она подразумевает плотность разбивки купола на треугольники. Т.е. один и тот же купол можно “описать” разным количеством треугольников. К примеру, для менее плотной разбивки потребуется меньше треугольников, но с большей длиной ребра и форма будет более угловатой. Для более плотной разбивки потребуется большее количество треугольников с меньшей длиной ребра, но форма получится боле ровной и близкой к сферической.


В мире используется стандартное обозначение частоты латинской буковкой “V”. Ниже приведены примеры триангуляции до пятого значения. Как Вы заметите, число значения частоты равняется количеству “рядов”, на которые делиться один из треугольников икосаэдра.

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


Сечение сферы

Следующий параметр, который следует знать всем при расчете геодезического купола – это значение сечения сферы. Если мы рассмотрим сферу как целое, мы можем поделить ее на различное количество частей. Т.к. геодезическая “разбивка” состоит из “рядов”, то разбить купола удобнее всего по этим рядам. У куполов с разной частотой “V” – разное количество “рядов”, поэтому сечение для них всегда индивидуальное. Ниже приведены некоторые примеры сечения куполов разной частоты.


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

Надеемся, что статья оказалась для Вас полезной! Желаем Вам приятного Творчества!

Сферический треугольник и его применение.

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

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

Свойства сферического треугольника:

  1. Помимо трёх признаков равенства плоских треугольников, для сферических треугольников верен ещё один: два сферических треугольника равны, если их соответствующие углы равны.
  2. Для сторон сферического треугольника выполняются 3 неравенства треугольника: каждая сторона меньше суммы двух других сторон и больше их разности.
  3. Сумма всех сторон a + b + c всегда меньше 2πR.
  4. Величина 2πR − (a + b + c) называется сферическим дефектом
  5. Сумма углов сферического треугольника s = α + β + γ всегда меньше 3π и больше π
  6. Величина называется сферическим избытком или сферическим эксцессом
  7. Площадь сферического треугольника определяется по формуле.
  8. В отличие от плоского треугольника, у сферического треугольника может быть два, и даже три угла по 90° каждый.

Среди всех сферических многоугольников наибольший интерес представляет сферический треугольник. Три больших окружности, пересекаясь попарно в двух точках, образуют на сфере восемь сферических треугольников. Зная элементы (стороны и углы) одного из них, можно определить элементы все остальных, поэтому рассматривают соотношения между элементами одного из них, того, у которого все стороны меньше половины большой окружности. Стороны треугольника измеряются плоскими углами трехгранного угла ОАВС, углы треугольника – двугранными углами того же трехгранного угла см на рис.

Свойства сферических треугольников во многом отличаются от свойств треугольников на плоскости. Так, к известным трем случаям равенства прямолинейных треугольников добавляется еще и четвертый: два треугольника АВС и А`В`С` равны, если равны соответственно три угла РА = РА`, РВ = РВ`, РС = РС`. Таким образом, на сфере не существует подобных треугольников, более того, в сферической геометрии нет самого понятия подобия, т.к. не существует преобразований, изменяющих все расстояния в одинаковое (не равное 1) число раз. Эти особенности связаны с нарушением евклидовой аксиомы о параллельных прямых и также присущи геометрии Лобачевского. Треугольники, имеющие равные элементы и различную ориентацию, называются симметричными, таковы, например, треугольники АС`С и ВСС`

Сумма углов всякого сферического треугольника всегда больше 180°. Разность РА+РВ +РС – p = d (измеряемая в радианах) – величина положительная и называется сферическим избытком данного сферического треугольника. Площадь сферического треугольника: S = R2 d где R – радиус сферы, а d – сферический избыток. Эта формула впервые была опубликована голландцем А.Жираром в 1629 и названа его именем.

Если рассматривать двуугольник с углом a, то при 226 = 2p/n (n – целое число) сферу можно разрезать ровно на п копий такого двуугольника, а площадь сферы равна 4пR2 = 4p при R = 1, поэтому площадь двуугольника равна 4p/n = 2a. Эта формула верна и при a = 2pт/п и, следовательно, верна для всех a. Если продолжить стороны сферического треугольника АВС и выразить площадь сферы через площади образующихся при этом двуугольников с углами А, В, С и его собственную площадь, то можно прийти к вышеприведенной формуле Жирара.

Под сферическим треугольником подразумевается треугольник на поверхности сферы, составленный из дуг больших кругов – т. е. таких окружностей, центром которых является центр сферы. Углы сферического треугольника – это углы между касательными к его сторонам, проведенными в его вершинах. Как и углы обычного треугольника, они меняются от 0 до 180°. В отличие от плоского треугольника, у сферического сумма углов не равна 180°, а больше: в этом нетрудно убедиться, рассмотрев, например, треугольник, образованный дугами двух меридианов и экватора на глобусе: хотя меридианы сходятся в полюсе, оба они перпендикулярны экватору, а значит, у этого треугольника два прямых угла!

У сферического треугольника может быть два прямых угла

Уже у индийца Варахамихиры (V–VI вв.), у арабских математиков и астрономов начиная с IX в. (Сабит ибн Корра, ал-Баттани), а у западных математиков начиная с Региомонтана (XV в.) встречается в различных формулировках замечательная теорема о сферических треугольниках. Вот как она может быть сформулирована в современных обозначениях:

cosa = cosbcosc + sinbsinccosA. Сферическая теорема косинусов очень важна и для астрономии, и для географии. Эта теорема позволяет по координатам двух городов A и B находить расстояние между ними. Кроме того, математикам стран ислама сферическая теорема косинусов помогала в решении другой практической задачи: в городе с данными координатами находить направление на священный город Мекку (всякий правоверный мусульманин должен пять раз день молится в направлении Мекки). При решении этой задачи, считая город B Меккой, требовалось найти угол A того же треугольника.

Страница из «Собрания правил науки астрономии», XI в., автор неизвестен.

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

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

Купол на парусах Роспись паруса

ДжорджНельсон (George Nelson)

"Дизайнер может несколько расслабиться и развлечься; в результате может возникнуть шутка, забава. Удивительно, как часто это бывает очень значительная забава" Джордж Нельсон

Джордж Нельсон – американский дизайнер, архитектор, критик и теоретик дизайна. (1908, Хартфорд, Коннектикут – 1986, Нью-Йорк)

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

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

Форму своего знаменитого черного стула дизайнер строит на основе сферического треугольника, широко использовавшегося в архитектурных конструкциях купольных сооружений. В частности в византийских и русских храмах такой сферический треугольник назывался «парус». Благодаря «парусу» осуществлялся плавный переход от подкупольной опоры к куполу.

ДжорджНельсон (George Harold Nelson, 1908-1986 гг.)

гравюра Эшера

Концентрические сферы.1935г.Торцовая гравюра 24 на 24 см.

Четыре полые концентрические сферы освещены центральным источником света. Каждая сфера состоит из сетки, образованной девятью большими пересекающимися кольцами; они членят сферическую поверхность на 48 подобных сферических треугольников. Ма́уриц Корне́лис Э́шер (нидерл. Maurits Cornelis 17 июня 1898, Леуварден, Нидерланды - 27 марта 1972, Ларен, Нидерланды) - нидерландский художник-график.

Применение сферического треугольника:

  1. Использование в трехмерной графике сферических треугольников
  2. В астрономии
  3. В географии. Теорема сферического треугольника позволяет по координатам двух городов A и B находить расстояние между ними.
  4. В архитектруе
  5. В дизайне в виде стула от Джорджа Нельсона
  6. В гравюре

Мастер-класс новогодней поделки из бумаги «Новогодние шары»

Новогодние украшения интерьера и ёлки из бумаги

Автор : Погожева Валентина Петровна, воспитатель, МБДОУ «Усть-Сертинский детский сад «Теремок»», с. Усть-Серта, Кемеровской области, Чебулинского района.

Мастер – класс рассчитан на детей старшего дошкольного возраста, школьного возраста, педагогов и родителей.
Назначение : Поделка является украшением для интерьера новогоднего зала, новогодней игрушкой для украшения елки, а также может служить подарком на Новый год.
Цель . Научить детей создавать шар из бумаги, используя разные виды бумаги, отражать новогоднюю тематику.
Задачи:
- Создание условий для творческих проявлений детей, вызывать чувства радости воспитывать эмоционально-эстетические чувства;
- развивать творческие способности детей, воображение;
- проявлять потребность создавать прекрасное и украшать им дом, детский сад, дарить близким;
- воспитывать аккуратность в работе;
- учить делать объемные шары.
Материалы . Картон цветной, старые открытки или обложки глянцевых журналов, ножницы, карандаш, клей, трафарет круга и треугольника, или циркуль.

Приятные новогодние хлопоты – это одна из самых замечательных составляющих зимнего праздника. Среди этих хлопот обязательно присутствует украшение дома и новогодней елки. Игрушки, гирлянды и прочие украшения можно купить в магазине. Ну, а если есть желание и небольшое количество времени, то можно взяться за самостоятельное изготовление оригинальных и удивительных украшений. Например, сделать из цветной бумаги елочные шары.
Такой разноцветный объемный шар украсит не только елку, но и стены, двери и окна.
Новый год - пора игры,
Здесь простор воображенью.
Что за чудо-украшенье
Новогодние шары!
Скажете, шары - привычный,
Вечный елочный наряд?
Это так, но на обычный,
Не совсем глубокий взгляд.
А фантазией заветной
Взгляд вы поменяйте свой:
Это ж - малые планеты
Из галактики иной
Здесь случайно оказались
.
Для работы необходимо приготовить :
Картон цветной, старые открытки, ножницы, карандаш, клей, трафарет круга и треугольника.


Делаем шар :
1. Берем картон (или открытки) и с помощью трафарета рисуем 20 кругов.


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



3. Аккуратно при помощи линейки сгибаем по сторонам ранее нарисованных треугольников.


4. Берем пять кругов и склеиваем их так, чтобы верх треугольников был в одной точке. У нас получился верх шара, который похож на цветок. В самом верху проделываем отверстие, продеваем ленточку и фиксируем ее узлом
Аналогично склеиваем 5 фрагментов. Это будет – дно шара.


5. Теперь делаем середину нашего шара. Склеиваем отдельные фрагменты в полосу и замыкаем ее в кольцо.



6. Теперь все три части нашего шара собираем в одно целое: верх, дно и середину.


Фото10.


7. Ну вот, наш шар готов, можно украшать елку или новогодний зал.



Можно сделать новогодний шар не такой большой, а поменьше используя восемь кругов.
1. Чертим и вырезаем восемь кругов.
2. В каждом круге рисуем равносторонние треугольники, затем отгибаем клапаны.
3. Затем склеиваем первые четыре заготовки вместе, после этого следующие четыре заготовки.


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


Из таких – же заготовок можно сделать и еще такой шар :

Пошаговый процесс выполнения работы:

1. Из цветной бумаги при помощи трафарета вырезаем 8 кругов. И еще нужно вырезать два круга меньшего размера.


2.Берем большой круг, сворачиваем пополам, потом еще раз пополам.


3. Так делаем со всеми большими кругами.
4. Затем берем маленький круг и наклеиваем на него свернутые большие круги.


5.Так наклеиваем все четыре круга на маленький круг. Аналогично делаем вторую половину. У нас получилось две половинки.


6.Склеиваем две половинки, и аккуратно расправляем сложенные «кармашки» кругов.


7.Вот еще и такой у нас получился новогодний шар.


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




Украсьте готовыми игрушками ваш дом, группу, детский сад для создания новогоднего настроения.
Хорошего настроения и веселого праздника!

Сферическая тригонометрия

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

Углы A , B , C сферического треугольника, противолежащие сторонам a , b , c соответственно, представляют собой, по определению, меньшие, чем , углы между дугами больших кругов, соответствующими сторонам треугольника, или углы между плоскостями, определяемыми данными лучами.

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

Свойства сферических треугольников. Каждая сторона и угол сферического треугольника по определению меньше .

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

История этой демки такова: однажды один мой друг сделал для своей игры генератор карт планет и захотел, чтобы созданные таким образом карты показывались в виде вращающейся сферы. Однако, при этом он не хотел использовать 3D-графику, а вместо этого сгенерировал множество кадров с этой самой сферой, повёрнутой на разные углы. Количество используемой памяти было… скажем так, избыточным, ну а скорость генерации кадров (как и качество их исполнения) сильно страдала. Чуть подумав, мне удалось помочь ему оптимизировать этот процесс, но в целом меня не покидало справедливое ощущение того, что это задача для OpenGL, а вовсе не для 2D-графики.

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

И должен сказать, что у меня это получилось. Но обо всём по порядку.

Математика процесса

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

Итак. Переход от сферической системы координат к декартовой задаётся системой уравнений (взято с Википедии):

А обратный переход - такими уравнениями:

Координату Z мы легко можем получить из X и Y , зная радиус, а сам радиус мы можем принять равным единице.
В дальнейшем договоримся о том, что приведённые выше уравнения мы слегка изменим, поменяв местами понятия Y (у нас это будет экранная вертикаль) и Z (это будет глубина сцены).

Техническая часть

Реализация идеи потребует от нас применения квада (я уже о том, как его использовать, поэтому повторяться не буду, тем более что ниже приведена ссылка на полный исходный код проекта), а также двух текстур: собственно карты планеты (я использовал текстуру Земли размера 2048x1024) и карты текстурных координат. Код генерации второй текстуры аккуратно повторяет математику преобразования из декартовых координат в сферические:

Int texSize = 1024; double r = texSize * 0.5; int pixels = new int; for (int row = 0, idx = 0; row < texSize; row++) { double y = (r - row) / r; double sin_theta = Math.sqrt(1 - y*y); double theta = Math.acos(y); long v = Math.round(255 * theta / Math.PI); for (int col = 0; col < texSize; col++) { double x = (r - col) / r; long u = 0, a = 0; if (x >= -sin_theta && x <= sin_theta) { double z = Math.sqrt(1 - y*y - x*x); double phi = Math.atan2(z, x); u = Math.round(255 * phi / (2 * Math.PI)); a = Math.round(255 * z); } pixels = (int) ((a << 24) + (v << 8) + u); } } GLES20.glGenTextures(1, genbuf, 0); offsetTex = genbuf; if (offsetTex != 0) { GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, offsetTex); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_NONE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_NONE); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texSize, texSize, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, IntBuffer.wrap(pixels)); }
Отметим, что координаты X и Y переводятся из диапазона в диапазон [-1..1], а текстурные координаты U и V переводятся из радианов в диапазон , после чего записываются соответственно в красную и зелёную компоненты 32-битной текстуры. Альфа-канал используется для сохранения «глубины» (координаты Z ), а синий пока остаётся незадействованным. Отключение билинейной фильтрации также не случайно: на данном этапе она не даёт какого-либо эффекта (соседние точки в любом случае имеют одни и те же значения, с довольно резкими скачками), а в том, что я собираюсь показать дальше, она и вовсе будет вредна. Но об этом ниже.

Обе текстуры подаются на вход простого пиксельного шейдера (здесь и далее картинки кликабельны):

Private final String quadFS = "precision mediump float;\n" + "uniform sampler2D uTexture0;\n" + "uniform sampler2D uTexture1;\n" + "varying vec4 TexCoord0;\n" + "void main() {\n" + " vec4 vTex = texture2D(uTexture0, TexCoord0.xy);\n" + " vec3 vCol = texture2D(uTexture1, vTex.xy).rgb;\n" + " gl_FragColor = vec4(vCol, (vTex.w >
Код отрисовки сцены я не привожу, т.к. в нём всё довольно тривиально (и, опять же, его можно посмотреть в полном исходнике), да и сам шейдер довольно примитивен. Самое любопытное в нём, пожалуй, то, что альфа-канал пока лишь проверяется на положительность, тогда как можно было бы задействовать его для эффекта освещения.

Получилось уже довольно неплохо, однако как-то плоско, плюс хотелось бы добавить собственно вращение планеты вокруг своей оси.

Включаем в шейдер ещё один параметр (будем менять его в зависимости от времени в диапазоне ), плюс добавляем «глубину» (умножение цвета на значение из альфа-канала):

Private final String quadFS = "precision mediump float;\n" + "uniform sampler2D uTexture0;\n" + "uniform sampler2D uTexture1;\n" + "uniform float uOffset;\n" + "varying vec4 TexCoord0;\n" + "void main() {\n" + " vec4 vTex = texture2D(uTexture0, TexCoord0.xy);\n" + " vTex.x += uOffset;\n" + " vec3 vCol = texture2D(uTexture1, vTex.xy).rgb;\n" + " gl_FragColor = vec4(vCol * vTex.w, (vTex.w > 0.0 ? 1.0: 0.0));\n" + "}\n";
Что ж, к самой сфере претензий нет, однако картинка выглядит как-то… восьмибитно, что ли. И неудивительно: мы же записывали текстурные координаты в диапазоне (максимум, доступный нам в обычных цветовых компонентах), а значит наша текстура может иметь не больше 256 точек в высоту (и 512 в ширину, учитывая вращение). Маловато, нужна как минимум 10-битная точность.

Увеличиваем разрешение

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

Итак, у нас пока задейстованы две из трёх цветовых компоненты, т.е. 16 бит из 24. Ну так упакуем же данные так, чтобы каждая текстурная координата имела размер 12 бит, что позволит нам работать с текстурами размером до 4096 пикселей в высоту! Для этого изменим буквально три строчки в программе:

Long v = Math.round(4095 * theta / Math.PI); ... u = Math.round(4095 * phi / (2 * Math.PI)); ... pixels = (int) ((a << 24) + (v << 12) + ((u & 15) << 8) + (u >> 4)); ...
и напишем новый шейдер, учитывающий 12-битную схему адресации (именно в этом месте необходимо, чтобы билинейная фильтрация была отключена!):

private final String quadFS = "precision mediump float;\n" + "uniform sampler2D uTexture0;\n" + "uniform sampler2D uTexture1;\n" + "uniform float uOffset;\n" + "varying vec4 TexCoord0;\n" + "void main() {\n" + " vec4 vTex = texture2D(uTexture0, TexCoord0.xy);\n" + " vec3 vOff = vTex.xyz * 255.0 + vec3(0.5, 0.5, 0.5);\n" + " float hiY = floor(vOff.y / 16.0);\n" + " float loY = vOff.y - 16.0 * hiY;\n" + " vec2 vCoord = vec2(\n" + " (vOff.x * 16.0 + loY) / 4095.0 + uOffset,\n" + " (vOff.z * 16.0 + hiY) / 4095.0);\n" + " vec3 vCol = texture2D(uTexture1, vCoord).rgb;\n" + " gl_FragColor = vec4(vCol * vTex.w, (vTex.w > 0.0 ? 1.0: 0.0));\n" + "}\n";
Ну это же совсем другое дело! С небольшими изменениями (добавив масштабирование «щипком» и вращение пальцем) я эту программу показывал своим друзьям и колегам, и при этом спрашивал, сколько, по их мнению, в этой сцене треугольников. Результаты варьировались, да и сам вопрос вызывал подозрение в наличии подвоха (в этом случае респонденты шутили «один», что было недалеко от истины), но правильный ответ стабильно удивлял. И все, как один, спрашивали: а почему сферу можно крутить вокруг одной оси, но нельзя наклонять?.. Хм.

Наклон

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

В сущности, задача сводится к тому, чтобы взять смещённую координату V , тогда как координата U не меняется: это происходит потому, что мы добавляем вращение вокруг оси X . План такой: преобразуем текстурные координаты в экранные (в диапазоне [-1..1]), применяем к ним матрицу поворота вокруг горизонтальной оси (для этого заранее запишем в новую константу uTilt синус и косинус угла наклона), а дальше воспользуемся новой координатой Y для выборки в нашей шаблонной текстуре. «Повёрнутая» координата Z нам тоже пригодится, с её помощью мы отзеркалим долготу для обратной стороны шарика). Экранную координату Z придётся посчитать явно, чтобы не делать две текстурных выборки из одной текстуры, заодно это повысит её точность.

private final String quadFS = "precision mediump float;\n" + "uniform sampler2D uTexture0;\n" + "uniform sampler2D uTexture1;\n" + "uniform float uOffset;\n" + "uniform vec2 uTilt;\n" + "varying vec4 TexCoord0;\n" + "void main() {\n" + " float sx = 2.0 * TexCoord0.x - 1.0;\n" + " float sy = 2.0 * TexCoord0.y - 1.0;\n" + " float z2 = 1.0 - sx * sx - sy * sy;\n" + " if (z2 > 0.0) {;\n" + " float sz = sqrt(z2);\n" + " float y = (sy * uTilt.y - sz * uTilt.x + 1.0) * 0.5;\n" + " float z = (sy * uTilt.x + sz * uTilt.y);\n" + " vec4 vTex = texture2D(uTexture0, vec2(TexCoord0.x, y));\n" + " vec3 vOff = vTex.xyz * 255.0 + vec3(0.5, 0.5, 0.5);\n" + " float hiY = floor(vOff.y / 16.0);\n" + " float loY = vOff.y - 16.0 * hiY;\n" + " vec2 vCoord = vec2(\n" + " (vOff.x * 16.0 + loY) / 4095.0,\n" + " (vOff.z * 16.0 + hiY) / 4095.0);\n" + " if (z < 0.0) { vCoord.x = 1.0 - vCoord.x; }\n" + " vCoord.x += uOffset;\n" + " vec3 vCol = texture2D(uTexture1, vCoord).rgb;\n" + " gl_FragColor = vec4(vCol * sz, 1.0);\n" + " } else {\n" + " gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + "}\n";
Ура, наклон удался! Вот только странный шум на границе полушарий немного смущает. Очевидно, проблема кроется в недостаточной точности адресации в граничных точках (точки на самой окружности соответствуют слишком большому диапазону координат, один тексель расползается на интервал довольно заметной длины). В конце концов, мне удалось это победить, используя две сгенерированных текстуры вместо одной.

В итоге, можно приближать и крутить шарик почти так же, как в Google Earth. С тем отличием, что здесь - всего-навсего два треугольника.

Ну и, наконец, обещанное. Исходный код проекта доступен на