1
\$\begingroup\$

I need a function that can take a vector as an input and provide a vector that is at a 90-degree angle to the provided vector. I understand that in 3D there is an infinite amount of vectors that could be produced from this calculation, but I only require 1. I have been using GLM and have tried using its built in vector rotation functions but to no avail. I would like to keep the solution compatible with GLM as I wish to have everything standardized.

Here is a basic visualization of what I need. enter image description here

Edit The function's purpose is to pass a direction vector into a function, radius, and an angle and it will create a point around the origin at x angle in space. The reason for this is so I can loop through and create a point cloud in 3D space and then join them together to make shapes such as cylinders (see photo)

Solution Code

glm::vec3 CreateAngledPoint(glm::vec3 rotation_point, float radius, float angle, glm::vec3 normal)
{
    // Normalize the normal (axis to rotate on)
    normal = glm::normalize(normal);
    // Create a vector that will be used for the dot product
    glm::vec3 to_cross = glm::normalize(glm::vec3(0.0f,1.0f,0.0f));
    // Make sure that the normal and cross vector are not the same, if they are change the cross vector
    if (to_cross == normal) to_cross = glm::normalize(glm::vec3(0.0f, 0.0f, 1.0f));
    // Get the cross product
    glm::vec3 to_return = glm::normalize(glm::cross(normal,to_cross));
    // Rotate point around the axis
    to_return = glm::rotate(to_return, angle* RAD_TO_DEG, normal);
    // Scale the point up from the origin
    to_return *= radius;
    // Apply it to the point in space we are rotating around
    return rotation_point + to_return;
}

Example of its usage enter image description here

\$\endgroup\$
0
\$\begingroup\$

Edit:

So the question was for 3D and It isn't very clear whether you're drawing 2 vectors or 3. Use colors for each axis!

To get the perpendicular of a plane you simply need 2 vectors and take the cross product of the two. The two vectors represent the plane. Visualize this by making a right angle between your thumb and index finger. Your fingers represent the vectors, that's your plane.

If GLM doesn't have the cross product function you can simply do it manually:

The cross product can be calculated very quick by applying the following trick: Shift the x component to the bottom, multiply each component with their diagonal and subtract

 [a.y]   [b.y]   [a.y*b.z - b.y*a.z]   [c.x]
 [a.z] x [b.z] = [a.z*b.x - b.z*a.x] = [c.y]
 [a.x]   [b.x]   [a.x*b.y - b.x*a.y]   [c.z]
 [a.y]   [b.y] // It loops around for completion

The c vector is your perpendicular vector to the plane. Provided that both vectors are normalized.

Note: if two vectors are parallel the resulting vector will be [0,0,0].


2d:

The perpendicular ( aka normal )can be found by simply swapping the x and y values and negating one of the two

  [2,5] -> [-5,2]

Depending on which on you negate gives you the directing your vector goes into.

Edit: Geogebra can easily visualize this.

https://ggbm.at/CuaUGr4d

Move point B and you will see that the perp is always the same with the x and y swapped and one negated.

\$\endgroup\$
  • \$\begingroup\$ How would you do it in 3 dimensions? \$\endgroup\$ – 0xen Jul 29 '17 at 19:25
  • \$\begingroup\$ Oh thought you just wanted the 2D one, I misunderstood. The problem is that it's rather impossible to determine it's orientation in 3D. Do you perhaps want the normal to a plane? In that case you can just do the cross product of two vectors. \$\endgroup\$ – Sidar Jul 29 '17 at 19:32
  • \$\begingroup\$ Can you explain your usecase btw? What are you trying to achieve? \$\endgroup\$ – Sidar Jul 29 '17 at 19:32
  • \$\begingroup\$ I have included an explanation of what I needed in the post, as well as a visualization of why I needed it \$\endgroup\$ – 0xen Jul 29 '17 at 21:26
  • \$\begingroup\$ lol for some reason I was thinking of Game Maker instead of the math library GLM. Was a bit confused. \$\endgroup\$ – Sidar Jul 30 '17 at 1:24
1
\$\begingroup\$

You need to calculate the Cross Product ( https://en.wikipedia.org/wiki/Cross_product ) of two vectors normalized.

One is your "provided vector" and the other is a vector perpendicular to the plane you want to rotate 90 degrees over.

template<typename valType >
detail::tvec3< valType > cross (detail::tvec3< valType > const &x, detail::tvec3< valType > const &y)

This will return a vector that is perpendicular (at 90 degrees) to both normals (unit vectors).

glm::cross( glm::normalize(provided_vector), glm::normalize(some_vector) );

some_vector must not point in the same direction nor can be opposite to provided_vector.

You must pick a some_vector depending on what you need.

If you want something "on the floor" at 90 degrees to something else "on the floor" making some_vector point straight upward or downward is a good choice.

What is up or down depends on how your game. Often it's the Y axis (0, 1, 0).

If you want to rotate 90 degrees the opposite way, negate the some_vector.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.