Геометрия звезд
Геометрия звездMartianCraft
- Услуги
- Команда
- Карьера
- Блог
Звезда — широко известный символ, используемый для рейтингов. Если вы создаете пользовательский интерфейс для рейтинга в приложении, скорее всего, вы где-то будете использовать звездочку. Есть много разных способов получить звезду на экране в вашем приложении, но лучший способ — нарисовать ее с нуля в коде. Это не только дает вам полную гибкость с точки зрения размера и разрешения экрана, а также возможность создавать удивительные эффекты с помощью основной анимации, но также позволяет вам полный ботаник в геометрии . Вы можете указать на подобные статьи в следующий раз, когда кто-то осмелится спросить, почему вы изучаете все это в школе, потому что «вы никогда не будете использовать это в реальной жизни».
Круги
Начните с классической пятиконечной звезды.
Чтобы вычислить координаты каждой точки по краю круга, я могу использовать Метод UIBezierPath
addArc
. Меня не интересуют сами дуги, но currentPoint
пути, когда вы добавляете каждую дугу, будут представлять интерес. Это расширение на UIBezierPath
дает мне то, что мне нужно:
расширение UIBezierPath { статический пусть двенадцатиоклок: CGFloat = .pi * 1,5 класс func pointsOnCircle( центр: CGPoint, радиус: CGFloat, очки: инт, startAngle: CGFloat = двенадцатиоклок) -> [CGPoint] { пусть pointOffsetAngle = ((.pi * 2.0) / CGFloat (точки)) вар начальный угол = начальный угол вар конечный угол = начальный угол пусть путь = UIBezierPath() path.move (к: . zero) var CirclePoints = [CGPoint]() за _ в 1...баллах { path.addArc (withCenter: центр, радиус: радиус, startAngle: startAngle, endAngle: endAngle, по часовой стрелке: true) CirclePoints.append (путь.currentPoint) начальный угол = конечный угол endAngle += pointOffsetAngle } вернуть кругОчки } }
Как только я наберу очки, я могу нарисовать звезду, соединив точки на круге, как показано здесь, начиная с 1 и заканчивая 5, а затем возвращаясь к 1:
Рисование такой звезды не дает нужного результата. Это нормально, если все, что я хочу сделать, это заполнить путь, но если я хочу иметь пустые или частично заполненные звезды (например, для представления среднего рейтинга в 3,6 звезды), тогда этот путь не будет работать. В середине весь этот беспорядок, который я не хочу видеть. Как я могу рассчитать, где будут эти внутренние точки? Пришло время разобраться с тригонометрией.
Треугольники
Тригонометрия — это прямоугольные треугольники, и на первый взгляд на диаграмме их нет. Но это только потому, что я не нарисовал на нем достаточно лишних линий. Я могу сделать пятиугольник большего размера, соединив все внешние точки звезды, и я могу провести линию из центра круга, которая проходит через внутреннюю точку. Это дает мне что-то вроде этого:
Оранжевая область представляет собой прямоугольный треугольник! Тем не менее, я недостаточно знаю об этом. Для описания прямоугольного треугольника мне нужно хотя бы два числа из:
- Длины сторон
- Неправильные углы
В настоящее время я могу вычислить только длину одной стороны — стороны, которая проходит на полпути вдоль края этого большого пятиугольника. Я могу сделать это, используя это расширение на CGPoint
для расчета средних точек и расстояний. Дистанционный метод использует теорему Пифагора, так что вы чертовски правы, он используется в реальной жизни! :
расширение CGPoint { расстояние функции (до: CGPoint) -> CGFloat { пусть deltaX = Double (to. x - self.x) пусть deltaY = Double (to.y - self.y) пусть расстояние = sqrt((deltaX * deltaX) + (deltaY * deltaY)) вернуть CGFloat(расстояние) } func midPoint(to: CGPoint) -> CGPoint { пусть deltaX = to.x - self.x пусть deltaY = to.y - self.y return self.applying(CGAffineTransform(translationX: deltaX * 0,5, y: deltaY * 0,5)) } }
Что я хочу сделать, так это выяснить, где должны быть внутренние точки звезды, чтобы я мог рисовать прямо к ним, а не полагаться на пересекающиеся линии. Для этого мне нужно узнать расстояние от центра круга до внутренней точки звезды. Внутренняя точка выделена синим цветом на диаграмме выше.
Пентагоны
В центре пятиконечной звезды находится пятиугольник. Это не совпадение. В центре шестиконечной звезды вы найдете шестиугольник и так далее. Вот геометрический факт, который вы, возможно, забыли со школы (я точно забыл): внутренние углы правильного многоугольника, например пятиугольника, можно найти по следующей формуле: ((n — 2) * 𝛑) / n , где n — количество сторон. Вот внутренние углы пятиугольника:
Таким образом, каждый из отмеченных углов равен 3𝛑 / 5 . Почему меня это волнует? Присмотритесь к внутренней точке, где виден пятиугольник:
.Рассмотрим окружность над внутренней точкой. Синяя часть круга соответствует внутреннему углу пятиугольника. Внизу справа это 𝛑 — это значение, потому что именно столько радиан содержится в половине круга. Эти значения отражаются в верхней половине круга, поэтому желтая часть круга совпадает с внутренним углом пятиугольника. Верхний правый желтый участок — это интересующий меня угол — край треугольника проходит через него, и, поскольку край заканчивается в средней точке линии между двумя внешними точками, я знаю, что край пересекает этот желтый угол пополам — так что теперь у меня есть один из внутренних углов моего треугольника! Этой информации мне достаточно, чтобы рассчитать все, что мне нужно знать.
Термины, используемые при описании прямоугольного треугольника:
- Гипотенуза — ребро треугольника, противоположное прямому углу
- 𝜃 (тета) — интересующий вас непрямой угол
- Противоположный
— край треугольника напротив 𝜃 - Смежный — ребро треугольника рядом с 𝜃
Как было сказано ранее, мне нужны любые две из этих частей информации. У меня есть 𝜃, который составляет половину внутреннего угла пятиугольника, или (3𝛑 / 5) / 2 (упрощено до 0,3𝛑 , если хотите), и у меня есть длина стороны напротив . Меня интересует длина стороны , прилегающей к стороне .
На этой диаграмме показаны различные части треугольника:
Есть три формулы тригонометрии, которые вам, возможно, приходилось учить в школе. Тот, который включает противоположные и смежные стороны, таков:
Желто-коричневый 𝜃 = напротив / рядом
Мне нужно поставить две вещи, которые я знаю, на одну сторону, чтобы я мог вычислить вещь, которую я не знаю, а это значит, что формулу нужно изменить так:
рядом = напротив / Желто-коричневый 𝜃
Это дает мне расстояние от внутренней точки до средней точки двух внешних точек. На самом деле мне важно расстояние от центра круга до внутренней точки, но его легко рассчитать с помощью моего расширения CGPoint
.
Теперь у меня есть радиус другого, меньшего круга, у которого есть все внутренние точки по окружности. Это означает, что я могу снова использовать свой метод pointsOnCircle
, передав новый радиус и другой начальный угол (на полпути между первыми двумя внешними точками). Вот внутренний круг:
Объединение двух массивов точек в один путь дает мне идеальную звезду без грязных внутренних линий. ★★★★★ для геометрии!
Код
Это расширение дает новый инициализатор для
, который возвращает звезду с заданным количеством точек внутри заданного прямоугольника. Это зависит от других расширений ранее в статье:
расширение UIBezierPath { удобство инициализации (starIn rect: CGRect, points: Int = 5) { предварительное условие (точки >= 3, «Неверное количество баллов») // Константы, описывающие звезду пусть центр = CGPoint (x: rect.midX, y: rect.midY) пусть радиус = rect. size.width * 0,5 пусть externalPoints = UIBezierPath.pointsOnCircle (центр: центр, радиус: радиус, точки: точки) // Этот расчет вычисляет расстояние от линии между первыми двумя внешними // точки и первая внутренняя точка // Внутренний угол правильного многоугольника в центре звезды пусть внутренний угол: CGFloat = (CGFloat (точки - 2) * .pi) / CGFloat (точки) // Середина линии между двумя внешними точками пусть midPoint = externalPoints[0].midPoint(to: externalPoints[1]) // Длина этой строки пусть opp = externalPoints[0].distance(to: midPoint) пусть тета = внутренний угол * 0,5 пусть DistanceIn = opp / tan (тета) // Это даст нам радиус внутреннего круга пусть внутреннийРадиус: CGFloat точки переключения { случай 3, 4: innerRadius = center.distance(to: midPoint) * 0,5 по умолчанию: innerRadius = center.distance(to: midPoint) - DistanceIn } // Теперь мы можем повторить трюк с дугами окружностей, чтобы получить точки на внутренней окружности. Начальный угол необходимо отрегулировать, так как он будет не в верхней части круга, а на полпути между двумя внешними точками. пусть innerPointOffset = (.pi * 2,0 / CGFloat (точки)) * 0,5 пусть innerPoints = UIBezierPath.pointsOnCircle (центр: центр, радиус: innerRadius, точки: точки, startAngle: UIBezierPath.twelveOClock + innerPointOffset) // Наконец, используем два набора точек для создания пути самостоятельная инициализация() self.move (к: externalPoints [0]) для (внешнего, внутреннего) в zip (outerPoints, innerPoints) { self.addLine (к: внешнему) self.addLine (к: внутренний) } self.close () // Центрируем звезду по вертикали в переданном прямоугольнике пусть starBounds = self.bounds пусть heightAdjustment = (rect.height - starBounds.height) * 0,5 self.apply(CGAffineTransform(translationX: 0, y: heightAdjustment)) } }
Одним из способов использования этого кода было бы нарисовать изображение звезды — вот способ нарисовать частично закрашенную звезду:
расширение UIImage { class func star (размер: CGSize, цвет: UIColor, точки: Int = 5, заполнено: CGFloat = 1. 0) -> UIImage { let renderer = UIGraphicsImageRenderer (размер: размер) пусть изображение = renderer.image { rendererContext в пусть границы = rendererContext.format.bounds пусть starPath = UIBezierPath (starIn: bounds.insetBy (dx: 2, dy: 2), точки: точки) звездный путь.lineWidth = 4 цвет.setStroke() starPath.stroke() starPath.addClip() var fillRect = границы fillRect.size.width *= заполнено цвет.setFill() UIRectFill(fillRect) } вернуть изображение } } UIImage.star (из: CGSize (ширина: 200, высота: 200), цвет: .orange, точки: 5, заполнено: 0,6)
Дает вам:
Звездообразный путь более гибкий и обеспечивает лучшую производительность при использовании вместе с CAShapeLayer
. Эта реализация оставлена в качестве упражнения для читателя.
Заключение
Наличие геометрических форм в виде путей Безье дает вам полную гибкость для дизайна пользовательского интерфейса и упрощает изменение размера, стиля и цвета.
В коде можно создать почти любую геометрическую форму, но для этого вам, возможно, придется стряхнуть пыль со школьной геометрии. И, возможно, вам даже будет весело!
MartianCraft — американское агентство по разработке программного обеспечения для мобильных устройств. На протяжении почти двух десятилетий мы разрабатываем отмеченные наградами мобильные приложения мирового класса для всех видов бизнеса. Мы хотели бы создать индивидуальное программное решение, отвечающее вашим конкретным потребностям. Давайте свяжемся.Предыдущий артикул
по Алекс Репти 6 марта 2017 г.
Следующая статья
по Бен Брукс 3 апреля 2017 г.
Классификационная система в нацистских концентрационных лагерях
Подробнее об этом изображении
- Цитировать
- Делиться
- Распечатать
Жертвы преследований
Среди первых жертв преследований в нацистской Германии были политические оппоненты — прежде всего коммунисты, социал-демократы и профсоюзные деятели. Свидетели Иеговы отказались служить в немецкой армии или принести присягу на верность Адольфу Гитлеру и, следовательно, также подверглись преследованиям. Нацисты преследовали немецких мужчин-гомосексуалистов, чья сексуальная ориентация считалась препятствием для расширения немецкого населения. «Привычных» гомосексуалистов сажали в тюрьмы; многие позже были отправлены в концлагеря после отбытия наказания.
Нацисты преследовали тех, кого они считали расово неполноценными. Нацистская расовая идеология в первую очередь очерняла евреев, но также пропагандировала ненависть к рома (цыганам) и чернокожим. Нацисты считали евреев расовыми врагами и подвергали их произвольным арестам, интернированию и убийствам. Цыгане также подвергались преследованиям по расовому признаку. Нацисты считали поляков и других славян низшими и обрекали их на порабощение, принудительный труд, а иногда и на смерть. Еврейские заключенные подвергались самому жестокому обращению в нацистских концентрационных лагерях.
Идентификация заключенных: система маркировки
С 1938 года евреи в лагерях были идентифицированы по желтой звезде, пришитой к их тюремной форме, извращенной еврейской звезде Давида. После 1939 года и с некоторыми вариациями от лагеря к лагерю категории заключенных легко определялись системой маркировки, сочетающей цветной перевернутый треугольник с буквами. Значки, пришитые к форме заключенных, позволяли охранникам СС определять предполагаемые основания для заключения.
Преступники были отмечены зелеными перевернутыми треугольниками, политзаключенные — красным, «асоциальные» (в том числе цыгане, нонконформисты, бродяги и другие группы) — черными или — в случае цыган в некоторых лагерях — коричневыми треугольниками. Гомосексуалистов обозначали розовыми треугольниками, а Свидетелей Иеговы — фиолетовыми. Пленников-ненемцев можно было идентифицировать по первой букве немецкого названия их родной страны, которая была пришита к их значку. Два треугольника, образующие значок еврейской звезды, были бы желтыми, если бы еврейский заключенный не был включен в одну из других категорий заключенных.