Обновить
196
0.1

Программист

Отправить сообщение

Реальность в том, что Epic Game Store аж бесплатно игры время от времени раздаёт (причём они не пиратские, а типа легальные),
торренты тоже существуют, но пользователи всё равно сидят в Стиме.

А ещё игра ведьмак 3 когда-то вышла без защиты (в GOG все игры без защиты, это их принципиальная позиция), сразу после выхода она появилась на торрентах, о это не помешало получить рекордные продажи.

"Зачем платить если есть бесплатно" - чтобы поддержать авторов.

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

Нет, не перестанут, есть куча альтернативных способов монетизации.

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

Или например на ютубе деньги авторам из РФ не платят (и вообще Роскомнадзор ютуб блочит ещё и для зрителей). Что, русскоязычный Ютуб умер? Да вроде нет, живёт как-то, авторы используют нативную рекламу, собирают донаты или вообще просто по фану видео выкладывают.

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

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

Смысл есть, это как раз то что связано с перемещением.
Например, бивектор yx описывает скорость вращения (и даёт кватернион как exp(yx * angularVelocity * t), и бивектор wx будет описывать линейную скорость и можно получить транслятор как exp(wx * linearVelocity * t)
И поскольку wx в квадрате это 0, а не -1, экспонента превращается в простую линейную запись (1 + wx * linearVelocity * t), а не в выражение с косинусами и синусами как в случае кватерниона.

И да, алгебра про которую я говорю, Cl(3, 0, 1), и вот эта вырожденность с w * w = 0 критически важна. В Cl(4, 0, 0) фокус с линейным перемещением не пройдёт.

P.S. и ещё в CL(3, 0, 1) будет градация точка-линия-плоскость, плоскость будет либо тривектором, либо 1-вектором в зависимости от выбранных обозначений. Бивектор будет описывать линию в пространстве.

Всё прекрасно комбинируется.
Если я перемножаю кватернион и кватернион - получается кватернион.
Если перемножу кватернион и транслятор - будет мотор.
Если перемножу кватернион с мультивектором - будет мультивектор.

Аналогично, когда мотор двигает плоскость, он даёт новую плоскость, а когда на линию - новую линию, на точку - даёт точку.

Если всё упростить до "мультивектор умножается на мультивектор", вся эта информация потеряется и пользоваться становится неудобно и непрактично - вместо перемножения двух кватернионов из 4 чисел каждый получается геометрическое произведение двух мультивектором из 16 чисел, причём большая часть нули и это всё избыточно.

Вот например как у меня получилось: https://github.com/Kright/ScalaGameMath/blob/master/cpp/pga3d/Motor.h#L91

В 3д графике нет необходимости умножать мультивектор на мультивектор.
Там будет мотор (8 компонент), собранный как комбинация всех трансформаций, который будет двигать точки в модели (3 или 4 компоненты).

Вычислительно это проще на порядок, чем считать sandwich product мультивектора и мультивектора.

Вот тут можно сравнить длину выражений для sandwich product для мультивектора, и, например, для мотора и точки:
https://github.com/Kright/ScalaGameMath/blob/master/cpp/pga3d/opsSandwich.h#L20

В случае транслятора и точки вообще тривиально:

constexpr Point Translator::sandwich(const Point& b) const noexcept { 
    return {.x = (b.x - 2.0 * wx), .y = (b.y - 2.0 * wy), .z = (b.z - 2.0 * wz)}; 
}

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

Условно, я в любом месте могу написать motor.toMultivector().sandwich(point.toMultivector()) и результат будет эквивалентен выражению motor.sandwich(point).toMultivector(), но второе считать намного быстрее.

Я не согласен, что вместо векторов, кватернионов и т.п. в 3д графике стоит использовать один мультивектор.

В мультвекторе 8 элементов (а если добавить ещё четвёртое измерение для перемещений - все 16), и переможение двух мультиветкоров - это куча операций. (Кажется, порядка 16^2)
У меня получилось, что лучше наоборот навыделять подклассов, которые нужны в реальной жизни, как минимум такой список: точки, векторы, обобщённые точки, линии, плоскости, идеальные плоскости, кватернионы, трансляторы, моторы, псевдоскаляр (и можно ещё больше сделать, но количество реализаций для бинарных операций растёт как N^2 и особо не разгуляешься)

И вот эти подклассы получаются простыми (вектор - только 3 числа, обобщённая точка - только 4, линия - 6, идеальная плоскость - 3), бинарные операции тоже радикально упрощаются и система типов языка программирования начинает помогать. А геометрическая основа в виде мультиветкора помогает в том, что все эти классы согласованы друг с другом и ведут себя как мультиветкоры, у которых часть полей нули.

Например, sandwich продукт транслятора и вектора упрощается до трёх сложений и трёх умножений на 0.5

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

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

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

Очень круто! Я на такие низкоуровневые штуки смотрел как тёмную магию, а оказывается не так уж и сложно.

Что мешает поставить редуктор?

d(A^B^C) = A^B - A^C + B^C

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

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

pga3d::Point a{0.0, 0.0, 0.0};
pga3d::Point b{2.0, 0.0, 0.0};
pga3d::Point c{0.0, 1.0, 3.0};

И если вывести d(a^b^c) и саму a^b^c, то получается так:

Bivector{.wx = 0, .wy = -6, .wz = 2, .xy = 0, .xz = 0, .yz = 0}
Plane{.x = 0, .y = 6, .z = -2, .w = 0}

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

Аналитически попытался доказать, но где-то ошибся и не получилось.

это мотор (так в PGA называют роторы), который соответствует операции параллельного переноса, который переносит первую точку во вторую (ну почти, на самом деле это его квадрат).

Оооо, прикольно, я только сейчас это заметил. Т.е., мотор можно описать и как два отражения от плоскостей (что я знал), и ещё как два отражения относительно точек!

Можно. Например, кватернион - это экспонента бивектора.
q = exp(b) = 1 + b + b2/2! + b3/3! + ... = cos(|b|) + b * sin(|b|) / |b|

И например если писать уравнения движения тел вида q y q{-1}, то их можно дифференцировать, единственное важное отличие - из-за некоммутативности производная "слева" и "справа" будут нести разный смысл. Типа переход q -> (1 + db) q это добавление вращения во внейшей системе отсчёта (после примненения q), а переход q -> q (1 + db) это добавление вращения в "локальной" СО, поверх которого применят q, и эти db будут разные

В линейной алгебре, когда вводят векторное произведение для 3д, есть понятие "правого базиса" и "левого базиса", потому что определить его можно и так и сяк. И ещё для чего-то кроме 3д векторное произведение не работает (ни для 2д, ни для 4д), потому что только в 3д у нас три степени свободы перемещения и 3 степени свободы вращения и это позволяет нарисовать "ось вращения". В 2д будет 2 перемещения и 1 вращение, в 4д - 4 перемещения и 6 вращений.

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

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

Ещё если взять кватернионы и сравнить их с матрицами вращения - когда в матрице копятся ошибки вычисления, нужно делать не очень очевидные штуки типа ортогонализации Грамма-Шмидта, а кватернион можно просто привести к единичной длине.
Кватернионы проще интерполировать или возводить в вещественную степень, чем матрицы.

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

Проблема ещё в том, что доллар обесценивается, и если когда-то 10 тысяч долларов это было много, то сейчас топовый макбук может стоить 7.5к. Ещё несколько лет роста цен и даже его придётся декларировать.

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

Моему другу как-то приснилось, что он работал в Яндексе много лет назад и самое забавное, что написание кода в текстовом редакторе "без ничего" там часто попадалось. Типа есть какой-нибудь внутренний сервис и буквально в браузере в текстовое поле надо вставить код с функцией, нажать кнопку запуска (код кастомизирует что именно и как запускается), а потом через несколько минут в браузере же увидеть первые несколько строчек лога ошибки. Потому что сервис, например, ждёт строку на втором питоне вместо третьего.

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

Пользуясь случаем поинтересуюсь - используется ли сейчас где-нибудь внутри Яндекса второй питон?

Вы эту статью читали или сразу пришли в комментарии?

Это будет е1 * е3
e2 свернутся в единицу.
Ещё ei ej = - ej ei для i != j поэтому можно менять порядок элементов

Умножать геометрическим произведением и смотреть на всё вместе как на мультивектор.

Геометрическое произведение бивекторов даст сумму скаляра и бивектора.

Там два в степени количества генераторов.

Информация

В рейтинге
2 843-й
Откуда
Белград, Сербия
Зарегистрирован
Активность

Специализация

Десктоп разработчик, ML разработчик
Kotlin
Scala
Java
Python
Нейронные сети
Алгоритмы и структуры данных
Разработка под Android
OpenGL