prompter: Напиши функцию на языке C без нестандартных зависимостей по аналогии с этим описанием:
matrixFromNormal <point3>
Возвращает матрицу, у которой вектор локальной оси Z (т.е. нормаль) будет совпадать с заданным вектором <point3>. Компонент перемещения матрицы равен [0,0,0]. Величины компонента масштаба обратны значениям, требуемым для нормализации вектора <point3>.
Примеры работы функции (по смыслу):
MatrixFromNormal([0,0,1]) вернёт (matrix3 [1,0,0], [0,1,0], [0,0,1], [0,0,0])
MatrixFromNormal([0,1,1]) вернёт (matrix3 [0,-0.707107,0.707107] [1.41421,0,0] [0,1,1] [0,0,0])
Вот базовая реализация этой функции на языке С:

#include <math.h>

struct matrix3 {
  float x[3][3];
};

struct point3 {
  float x, y, z;
};

struct matrix3 MatrixFromNormal(struct point3 normal) {
  struct matrix3 result;

  float length = sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z);
  float invLength = 1.0f / length;

  result.x[0][0] = normal.x * invLength;
  result.x[0][1] = normal.y * invLength;
  result.x[0][2] = normal.z * invLength;

  result.x[1][0] = -normal.y * invLength;
  result.x[1][1] = normal.x * invLength;
  result.x[1][2] = 0;

  result.x[2][0] = -normal.z * invLength;
  result.x[2][1] = 0;
  result.x[2][2] = normal.x * invLength;

  return result;
}



Обратите внимание, что эта реализация предполагает, что входной вектор нормали не равен нулю и не является нулевым вектором. Вам может потребоваться добавить дополнительный код для обработки этих случаев, если они возможны в вашем случае использования.
#include <math.h>

typedef struct {
  float x;
  float y;
  float z;
} point3;

typedef struct {
  point3 x;
  point3 y;
  point3 z;
  point3 translation;
} matrix3;

matrix3 MatrixFromNormal(point3 normal) {
  matrix3 result;
  float length = sqrtf(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z);
  result.z = (point3){normal.x / length, normal.y / length, normal.z / length};
  if (fabsf(result.z.x) < fabsf(result.z.y)) {
    float a = 1.0f / sqrtf(result.z.y * result.z.y + result.z.z * result.z.z);
    result.x = (point3){result.z.z * a, 0.0f, -result.z.y * a};
  } else {
    float a = 1.0f / sqrtf(result.z.x * result.z.x + result.z.z * result.z.z);
    result.x = (point3){0.0f, result.z.z * a, -result.z.x * a};
  }
  result.y = (point3){result.z.y * result.x.z - result.z.z * result.x.y,
                     result.z.z * result.x.x - result.z.x * result.x.z,
                     result.z.x * result.x.y - result.z.y * result.x.x};
  result.translation = (point3){0.0f, 0.0f, 0.0f};
  return result;
}