algorithmic modeling for Rhino

Why the "angle between vectors" component is always positive?

I have to know the angle between a lot of vectors, but some times this should be negative, I thought that this component measure the angle in the direction of the clock.

Any idea of how can I get the real angles, negative and positive???

Views: 28894

Replies to This Discussion

Like Fred says this is old, and in Grasshopper Years we are talking decades.

My understanding of Vector Angles has moved on significantly as well, but it was this very thread that moved it on leaps and bounds thanks to Damien.

Read through to the end and try to digest what is here if you still need help I'll post something similar.

In the meantime here is what [Angle] is doing in Grasshopper.

and if you need it the file:


Thank you very much Danny! Appreciate it.

Alright, so let me explain the situation even more and maybe someone can step in a say what they'd like to see. So as I originally wrote, there has to be a defined axis in order to have negitive rotation, so the first order of business is finding a relaible axis to base the rotation on. Two vectors will create a plane, so I figured I'd use that. Essentially, what winds up being the Z vector of the plane is the cross product of the two vectors (provided those vectors are unitized, which they should be). The thing about the plane that's created is that A) it will always be right handed, B) the X vector will always be the actual X vector of the plane, and C) the supplied Y vector will give direction to thw Y vector of the plane, although it won't actually match it.

Well, when you take the angle between the two vectors, it will always give you the angle (in radians) between the two vectors that is less than 180 degrees. If you use the Z vector of the plane created from those two vectors as the axis of rotation, then the rotation from vector A (the x vector of the plane) to vector B will ALWAYS be less then 180 degrees and the result from the Vector Angle component will always lead to the "correct" location.

My assumption as to why some of you would want a "negative" rotation was simply because you were rotating with a static axis which was some times leading to the "wrong" result (ie one that doesn't result in going from vector A to vector B). However, if you create the axis based on each condition that your working with, then you can completely avoid that problem.

So I guess my question is more of where does the situation come up where you NEED the reflex angle between the two vectors. IMHO, that need comes out of using the same axis/plane for each rotation situation as opposed to using the natural axis/plane that is generated from each one. Even if you have a set axis that your trying to use, you could potentially compare it to the natural one to see if you need to generate a negative rotation. Maybe its just me, but if someone can shed more light, then maybe I could help out a bit more.

BTW, I have a definition exploring everything above if someone would like to see it...
Damien wrote: "So I guess my question is more of where does the situation come up where you NEED the reflex angle between the two vectors."

Below is the interpolated vector grid for a river's current velocities, I had to sample some survey data and then interpolate between them along the river to get this grid for use in a maneuvering simulator.

The method I used needed to rotate the vectors and change their magnitude in the space between measuring stations. As these were only small angles the outlined method above worked but it was necessary to determine direction of rotation in order to achieve the results.

The example is only needed in 2D referencing the North direction of a compass and as none of the vectors made it passed south there was no sign of anything amiss with the method used. But I would appreciate a universal method to account for all positions of the compass.


Off the top of my head one example I can think of would be if you were trying to fabricate an undulating surface. There would be the process of panelizing (let's say triangulating) the surface with flat panels and then trying to devise connectors between each panel.

Assuming the surface has a front face and a back face condition (aesthetics or something) the connectors would (in some cases) need to register an obtuse (or reflex?) angle for consistency of construction.

I can dig up an example if that's not clear enough, but I think that would be a pretty generalizable need...
So if you had the option to supply the axis that you were looking to rotate around, then that would be better for you, correct? This is certainly possible, my only issue is that the axis supplied may not necessarily be perpendicular to the plane created by the two vectors. In that case, you'd either need to respect the plane created by the two vectors and use the axis vector as the indication of plane direction/handedness OR respect the axis vector that's supplied, which would lead to the resulting angle being between vector A and a "flattened" version of vector B. Of the two options, I'd prefer the first as it will always return the proper angle between the two. However, I realize that supplying the axis would infer that you were going to then use that same axis for the actual rotation. See the conflict...

I think that's a good example. In that case, there'd need to be some sort of indication of what was inside and what was outside, which, IMHO, is out of the scope of this script/component (since vectors have no sense of where they are). That's not to mean that you wouldn't be able to solve for that, but I just have no idea how it would fit into this context. The only thing that I could really think of in this case would be to have some sort of "normal" direction indicating where the surface was pointing (and therefore inside and outside). Then you could just do a comparion either between the "normal" direction and the second vector or the "normal" direction and the bisector of the two vectors (probably more reliable). If the resulting test vector and the "normal" vector are both pointing the same way, then you'd want the reflex angle. If they're pointing in opposite directions, then you'd be fine with the standard result from the Vector Angle component.
I follow. I guess my general example wasn't quite general enough...
@Damien, I don't think I would need to supply the reference/rotational access because as you say I'm really only interested in the perpendicular to the plane of the two vectors. In my 2D case that will always be Z. I'm only really interested in whether the direction of change is +ve or -ve to my sign convention, for a compass that's clockwise is +ve
I think your some what confused on the actual implications of using the perpendicular vector, because, as I said, if you always use the perpendicular vector, then you will always get the correct rotation between them.

First of all, if you don't know what I mean by right or left handed, then take a look at the following links... bear in mind that Rhino will ALWAYS make/use right handed planes whenever it has a chance...

So lets take a quick example and keep it in 2D, since that's what your working with. If you have vector A be the world X direction (1,0,0), and have vector B be the negative world Y direction (0,-1,0), you'd visually be able to see that the angle between them would be 90 degrees, although the counter clockwise revolution would 270 degress. However, if you create a plane from those two vectors in that order, you will find that the perpendicular vector between them is actually the negative Z axis (0,0,-1) not the positive Z axis. Therefore, the result from the Vector Angle component of 90 degrees (actually pi/2 in radians) is correct because if you rotate using the resulting negative Z axis, you will get the correct location. The only way to make sure that you get the correct rotation is to actually take the cross product of the two vectors in the order in which you're looking to rotate them. If you do that for each and every case as opposed to assuming which vector to use, then you'll be fine and get the proper result.
Ah, I think I got it now.

you don't need those two components to make a plane, then decompose it. Just the Vector Cross Product component respecting the A and B vectors.

BTW, another reference for cross product. My far my most favorite vector math function ever :)






  • Add Photos
  • View All


  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service