Question

I'm trying to calculate the points in a cuboid given its centre (which is a Vector3) and the lengths of the sides along the x, y and z axis. I found the following on math.stackexchange.com: https://math.stackexchange.com/questions/107778/simplest-equation-for-drawing-a-cube-based-on-its-center-and-or-other-vertices which says I can use the following formulae:

https://math.stackexchange.com/questions/107778/simplest-equation-for-drawing-a-cube-based-on-its-center-and-or-other-vertices The constructor for the World class is:

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";
  }
}

And I passing the following parameters to the constructor:

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

The coordinates being output for all 8 vertices are:

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

Which cannot be correct. Any guidance would be very much appreciated!

Was it helpful?

Solution

The problem lies in the bitwise & inside your pow calls: In the y and z components, they always return 0 and 2 or 4, respectively. -1^2 = -1^4 = 1, which is why the sign of these components is always positive. You could try (i&2)!=0 or (i&2) >> 1 for the y component instead. The same goes for the z component.

OTHER TIPS

Change this:

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);

To this:

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

Or even to this:

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

The problem is that as written even though the values you mask out identify weather or not the lengths need to be negated. They are not in the correct place value to get the desired properties from the exponentiation of -1.

Rewriting the code as I have above will solve this issue, however it would be more readable and in general more permanent just to unroll the loop and manually write if each one is an addition or subtraction without using the pow function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top