Сфера из двух треугольников. Что такое геодезический купол

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

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

Сферическим треугольником называется фигура АВС на поверхности сферы, образованная дугами трех больших кругов (рис. 15).

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

Обычно рассматриваются треугольники, углы и стороны которых меньше 180°. Для таких сферических треугольников сумма углов всегда больше 180°, но меньше 540°, а сумма сторон всегда меньше 360°. Разность между суммой трех углов сферического треугольника и 180° называется сферическим избытком σ , т.е.

σ = DA +DB +DC - 180°.

Площадь сферического треугольника s равна

Где R - радиус сферы, на поверхности которой образован треугольник.

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

Возьмем сферический треугольник АВС (рис. 15), образованный на сфере радиуса R и с центром в точке О.

Из вершины А проведем касательные AD и АЕ к сторонам b и с до пересечения их с продолжениями радиусов ОС и 0В, лежащих в одной плоскости с соответствующей касательной. Соединив прямой точки пересечения D и Е, получим два плоских косоугольных треугольника ADE и ODE с общей стороной DE. Применяя к этим треугольникам теоремы элементарной геометрии, напишем:

DE 2 = OD 2 + ОЕ 2 - 2OD× ОЕ × cos a,

DE 2 = AD 2 + АЕ 2 - 2AD× АЕ× cos A.

Вычитанием второго равенства из первого получим:

2OD × ОЕ× cos a = OD 2 - AD 2 + ОЕ 2 - АЕ 2 + 2AD × АЕ × cos A. (1.31)

Из прямоугольных плоских треугольников ОАЕ и ОАD следует:

OD 2 -AD 2 =R 2 ;OE 2 -AE 2 =R 2 ;

AD = R tg b ; АЕ = R tg с;

Подставив эти соотношения в формулу (1.31) и произведя соответствующие сокращения и переносы, получим

cos а = cos b cos с + sin b sin с cos A , (1.32)

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

Формулу (1.32) можно написать для любой стороны треугольника. Напишем ее, например, для стороны b:

cos b = cos с cos a + sin с sin a cos B

и, подставив в нее cos aиз формулы (1.32), получим

cos b = cos с (cos b cos с + sin b sin с cos A) + sin с sin a cos B.

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

cos b (1 - cos 2 с) = sin b sin с cos с cos A + sin c sin a cos B.

Заменив (1 - cos 2 с) на sin 2 с и сократив все на sin c, окончательно получим

sin a cos В = sinc cos b - cos c sin b cos A, (1.33)

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

Формула (1.33) называется формулой пяти элементов. Ее можно написать по аналогии и для произведений sin a cos С, sin b cos A, sin b cos С, sin с cos A и sin с cos В.

Решим теперь равенство (1.32) относительно cos A:

Возведя обе части последнего равенства в квадрат и вычтя их из 1, получим:

Раскрыв скобки и разделив обе части этого выражения на sin 2 а, получим

Полученное выражение совершенно симметрично относительно a, b и с, и заменяя A на В, а на b или A на С и а на с, напишем

т.е. синусы сторон сферического треугольника пропорциональны синусам противолежащих им углов; или отношение синуса стороны сферического треугольника к синусу противолежащего угла есть величина постоянная.

Три выведенных соотношения (1.32), (1.33), (1.34) между сторонами и углами сферического треугольника являются основными; из них можно получить много других формул сферической тригонометрии. Мы ограничимся выводом одной только формулы для прямоугольного сферического треугольника. Положим А = 90°; тогда sin А = 1, cos A = 0, и из формулы (1.33) получим

sin a cos В = sin с cos b.

Разделив обе части этого равенства на sin b и заменивна, согласно (1.34), будем иметь:

ctg B = sin c ctg b

т.е. отношение тангенса одного катета прямоугольного сферического треугольника к тангенсу противолежащего угла равно синусу другого катета.

История этой демки такова: однажды один мой друг сделал для своей игры генератор карт планет и захотел, чтобы созданные таким образом карты показывались в виде вращающейся сферы. Однако, при этом он не хотел использовать 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. С тем отличием, что здесь - всего-навсего два треугольника.

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

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

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

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

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

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

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

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

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

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

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

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


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


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



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


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


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



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


Фото10.


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



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


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


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

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

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


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


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


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


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


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


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




Украсьте готовыми игрушками ваш дом, группу, детский сад для создания новогоднего настроения.
Хорошего настроения и веселого праздника!
КАТЕГОРИИ

ПОПУЛЯРНЫЕ СТАТЬИ

© 2024 «kingad.ru» — УЗИ исследование органов человека