2
\$\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\$
2
\$\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\$
6
  • \$\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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .