0

I want to compute the angle between two edges in a face in 3D space.

I thought I could used the solution in this question: Signed angle between two 3D vectors with same origin within the same plane

However, when I try it out on rectangle with all 90 degree angles I get one angle that's 90 degrees and three that's 270.

I have very little knowledge of math related to geometry, which is why I struggle with this and clearly made the wrong assumption.

So how do you calculate the angle between two edges in a face?

What I tried:

def self.full_angle_between( vector1, vector2, normal )
  angle = vector1.angle_between( vector2 )
  direction = normal % ( vector1 * vector2 )
  angle = 360.degrees - angle if direction < 0.0
  angle
end

normal is the face normal vector1 and vector2 both origins from the same vertex and each points towards the next vertex in either direction

vector1.angle_between( vector2 ) refer to a method in the SketchUp Rubu API: http://code.google.com/apis/sketchup/docs/ourdoc/vector3d.html#angle_between It return an angle between 0-180 in radians.

360.degrees yields the degrees in radians. Also an SketchUp API method.

When I iterate over all the vertices in a rectangle I get three angles reported as 270 degrees. Why?

Community
  • 1
  • 1
thomthom
  • 2,854
  • 1
  • 23
  • 53
  • I found the source of my problems. I had not checked the order which I received the vectors. When I ensured they where given in the same order and the edge loop I got the correct angles. – thomthom Aug 25 '11 at 11:09

4 Answers4

1

I would say your problem lies in this line:

direction = normal % ( vector1 * vector2 )

It's not wrong in itself, but you might be passing in the wrong values.

If you're not fully up to speed on vector maths, the thing you may be missing is that the direction of the vector given by the cross product vector1 * vector2 depends on the order of the operands. If you swap them around you get the same vector pointing in the opposite direction.

So when you're iterating over the rectangle vertices, if you get the "next" and "previous" vertices mixed up you will get the bogus 270 degree results you describe.

Rob Agar
  • 12,337
  • 5
  • 48
  • 63
  • Yes, I'd come to the same conclusion right before you. When I ensured the vectors I used came in the same order as the edge loop I got the correct result. – thomthom Aug 25 '11 at 12:04
0

Since I can't add comments to the previous answer, I started a new answer just to point out that the dot product is only the cosine value of two vectors. To get the actual angle you need to call acos() after that.

0

You do just perform the dot product of the two vectors.

This will give you the angle. For 3d vectors it's:

product = (x1 * x2) + (y1 * y2) + (z1 * z2);

This assumes that the vectors are normalised (their length is one). So in the first instance you'll have to make sure this is so.

You'll have to make sure that you are choosing the right pair of edges each time:

edge1 * edge2
edge2 * edge3
edge3 * edge4
edge4 * edge1

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • I added some further description - using the dot product is what I have done. But I get some incorrect results. – thomthom Aug 25 '11 at 09:32
0

let's say we have two vectors called v1 and v2 (CV3 is a simple datatype with members x,y,z):

double VecAngle (CV3& v1, CV3& v2)
{
   double z = ScalarProd(v1, v2);
   double n = v1.Length() * v2.Length();
   return (acos(z/n));
}

with

const double ScalarProd (const CV3& argl, const CV3& argr)
{
   return (argl.x * argr.x + argl.y * argr.y + argl.z * argr.z);
}
user3677092
  • 31
  • 1
  • 4