Точки C++ вершин в кубоиде (побитовое И)

Я пытаюсь вычислить точки в кубоиде, учитывая его центр (который является вектором 3) и длины сторон вдоль осей x, y и z. На сайте math.stackexchange.com я нашел следующее: https://math.stackexchange.com/questions/107778/simplest-equation-for-drawing-a-cube-based-on-its-center-and-or-other-vertices которых написано, что я могу использовать следующие формулы:

https://math.stackexchange.com/questions/107778/simplest-equation-for-drawing-a-cube-based-on-its-center-and-or-other-verticesКонструктор для мирового класса:

World::World(Vector3 o, float d1, float d2, float d3) : origin(o)
{
  // If we consider an edge length to be d, we need to find r such that
  // 2r = d in order to calculate the positions of each vertex in the world.
  float r1 = d1 / 2,
      r2 = d2 / 2,
      r3 = d3 / 2;

  for (int i = 0; i < 8; i++)
  {
    /* Sets up the vertices of the cube.
     *
     * @see http://bit.ly/1cc2RPG
     */
    float x = o.getX() + (std::pow(-1, i&1) * r1),
          y = o.getY() + (std::pow(-1, i&2) * r2),
          z = o.getZ() + (std::pow(-1, i&4) * r3);

    points[i] = Vector3(x, y, z);
    std::cout << points[i] << "\n";
  }
}

И я передал следующие параметры конструктору:

Vector3 o(0, 0, 0);
World w(o, 100.f, 100.f, 100.f);

Координаты, выводимые для всех 8 вершин:

(50, 50, 50)
(-50, 50, 50)
(50, 50, 50)
(-50, 50, 50)
(50, 50, 50)
(-50, 50, 50)
(50, 50, 50)
(-50, 50, 50)

Что не может быть правильным. Любое руководство будет очень цениться!

2 ответа

Решение

Проблема заключается в побитовом & внутри вашего pow звонки: в y а также z компоненты, они всегда возвращают 0 и 2 или 4 соответственно. -1^2 = -1^4 = 1, поэтому знак этих компонентов всегда положительный. Вы могли бы попробовать (i&2)!=0 или же (i&2) >> 1 для компонента у вместо. То же самое касается компонента z.

Изменить это:

float x = o.getX() + (std::pow(-1, i&1) * r1),
      y = o.getY() + (std::pow(-1, i&2) * r2),
      z = o.getZ() + (std::pow(-1, i&4) * r3);

К этому:

float x = o.getX() + (std::pow(-1, (i     ) & 1) * r1), // pow(-1, 0) == 1, pow(-1, 1) == -1
      y = o.getY() + (std::pow(-1, (i >> 1) & 1) * r2), // pow(-1, 0) == 1, pow(-1, 1) == -1
      z = o.getZ() + (std::pow(-1, (i >> 2) & 1) * r3); // pow(-1, 0) == 1, pow(-1, 1) == -1

Или даже к этому:

float x = o.getX() + (std::pow(-1, (i     )) * r1), // pow(-1, {0, 2, 4, 6}) == 1, pow(-1, {1, 3, 5, 7}) == -1
      y = o.getY() + (std::pow(-1, (i >> 1)) * r2), // pow(-1, {0, 2}) == 1, pow(-1, {1, 3}) == -1
      z = o.getZ() + (std::pow(-1, (i >> 2)) * r3); // pow(-1, 0) == 1, pow(-1, 1) == -1

Проблема в том, что, как написано, даже если значения, которые вы маскируете, идентифицируют погоду или нет, длины должны быть сведены на нет. Они не в правильном значении места, чтобы получить желаемые свойства от возведения в степень -1,

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

Другие вопросы по тегам