Как стать автором
Обновить

Комментарии 12

Очень рад развитию вашего блога! Продолжайте в том же духе!

Подписывайтесь, у нас еще много интересного в планах!

Спасибо, классная шпаргалка получилась! Пробежался мысленно по этим темам, приятно было по быстрому освежить в памяти. Не поскажите, а какими программами в совокупности вы пользовались, чтобы нарисовать рисунки к вашей статье?

Шпаргалка-шпаргалкой, а очень хороший (понятный) курс линейной алгебры есть у 3Blue1Brown: Essence of linear algebra. Вышел в моём случае, увы, уже после окончания ВУЗа.

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

Простите - я не просто так спросил про редакторы. Не смотря на широкое распространение 3D всё ещё остаётся очень далёким от ежедневного применения типа офисных пакетов Word/Excel. Даже в случае с иллюстрациями к статье. Согласитесь - подобрать рисунки в 3D по многим вопросам к статье потребовало определённого труда, в некоторых случаях даже ручного? Очень подозрительно )))

С стоимостью операций всё не так просто. Деление занимает 1-2 тика, если оно не имеет зависимостей по данным, и 20, если имеет. Т.е. если в цикле делить

while ...
   x = x/something

то это примерно в 10-20 раз медленее, чем если поделить 20 чисел в массиве на указанное значение.

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

https://www.agner.org/optimize/instruction_tables.pdf

Так, например, для ядра Coffe Lake время выполнения команд вещественной арифметики составляет

Сложение, вычитание 4 такта
Умножение 4 такта
Деление 11 тактов
Вычисление квадратного корня 12 тактов
Минимум, максимум двух чисел, внезапно 4 такта
Есть даже аппаратно реализованное скалярное произведение векторов, 13 тактов.

И это довольно значительно отличается от значений. приведенных автором в статье.

Кратко. чотко и по делу. Спасибо.

cross product появляется в 3D-пространстве. Это операция над двумя векторами, результатом которой является вектор, перпендикулярный исходным двум

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

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

vec3 new_dir = dir - normal * dir(dir, normal);

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

https://docs.gl/sl4/reflect

vec3 new_dir = dir - 2 * dot(dir, normal) * normal;

Если хотели сделать направление по плоскости то нужно не забыть нормализовать его, или восстановить скорость/длину вектора.

Спасибо! Исправили.

Очень крутое можно делать с cross product в проективном пространстве: можно найти пересечение двух прямых! Всегда мечтал это сделать, так как изначально cross product выглядит как функция для нахождения пересечения, и по прошествии многих лет после ознакомления с векторным произведением, приобретением некоторых знаний о проективной геометрии, я смог это наконец-то сделать. Cross product стала функцией для поиска пересечения двух прямых в двумерном пространстве!

public static bool isLinesCrossed(Vector3 a1, Vector3 b1, Vector3 a2, Vector3 b2, ref Vector3 itr, float USEEPS) {
  var d1 = b1 - a1;
  var d2 = b2 - a2;
  var n1 = new Vector3(d1.y, -d1.x);
  var n2 = new Vector3(d2.y, -d2.x);
  n1.z = -Vector3.Dot(a1, n1);
  n2.z = -Vector3.Dot(a2, n2);
  itr = Vector3.Cross(n1, n2);
  if(Mathf.Abs(itr.z) < USEEPS) return false;
  itr.x /= itr.z;
  itr.y /= itr.z;
  itr.z = 0f;
  return true;
}

Зарегистрируйтесь на Хабре, чтобы оставить комментарий