# Determine Angles

I have a bit of code that does calculate the angle between 2 faces. The 2 faces share a common edge and they are both oriented correctly.

``````          if (edge.faces.length == 2)
angle = edge.faces[0].normal.angle_between(edge.faces[1].normal)
angle = ((angle * 100).round).to_f / 100.0
``````

If the angle === 0 then I ignore it - but if there is an angle I want to figure out the inside angle and the corresponding outside angle.

This example returns 20.3 degrees but I’m looking for inside 200.3 degrees and outside 159.7 degrees. The second example has the inside and outside switched.

You might find it helpful to look at the code for Angular Dimension 2 or even the the original Angular Dimension plugin by @slbaumgartner (Steve Baumgartner). He wrote the code to measure the angle between two edges given three picked vertices, the middle pick being the common vertex. I think you could supply the equivalent from two planes with a common edge.

They are free, from SketchUcation Plugin Store.

I think that SU `angle_between` always returns an angle less than 180 so you have to figure out when to add 180.

And I see that 200.3 = 180 + 20.3.

And also that if you draw the normals in your diagram with a common vertex on the edge, you would expect to get 20.3°, not 159.7°, wouldn’t you?

If you want to get the obtuse angle, try reversing the direction of one normal.

We cannot reproduce the numbers (since we don’t have the model).

Have you tried calculating your math for edge cases? E.g.

• two coplanar faces: normals are parallel (angle 0°) and you probably want to get 180° outside (frontside) / inside (backside)
• right angle: normals are at 90° and you want 270° outside (frontside) or 90° inside (backside)
• coplanar opposed (in theory, SketchUp merges faces): normals at 180°, you want 360° outside (frontside) or 0° inside (backside)

I believe this is correct.

And to figure it out…

Get the ‘.cross’ between those two vectors.
Get the cross’s Z and if it’s +/- determines the angle direction.
I there’s no cross result they are probably co-linear ?

I think this represents graphically what i was trying to say earlier:

Still looks to me that if you reverse one normal, you get 159.7° as the returned angle. Then you have to figure out whether you want that, or its complement (180 + 20.3 = 200.3° or 360 - 159.7 = 200.3°) as the result,

Of course when you look at the model you can immediately determine if you need to add 180 to the angle or subtract the angle from 180.

What I’m trying to figure out is how to do that inside a script I will play around with the cross as Tig suggests and see if that gives me what I want.

I looked at the Angular Dimension code. That part will work but I need to determine the proper vectors.

If I start with the mid point of the common edge and then draw one line on the 2 faces where each line is perpendicular to the common edge then I can get Angular Dimension to produce the correct results.

angles.skp (15.8 KB)

I’ve now got better results. The added lines (vectors) are perpendicular to the common edge and are only there temporarily during the test phase.

I did a cross between the 2 vectors but I really can’t determine from the results when to use the compliment.

Can you describe in words when to use one rather than the other?

For example, if either or both face normals face ‘up’, use (obtuse) angle

If both normals ‘face down’ (back faces are both ‘up’) use complement?

You can test the z value to find ‘which way is up’ (z `>0`).

John,

The 2 faces belonging to the common edge can be facing absolutely any direction.

Essentially I want the angle for the 2 faces but only from the front faces. The one on the left is 141.18 - the one on the right should be 218.82

Then maybe try ‘if the intersection of the normals from the ends of the short lines you have drawn out from the edge is on the face side (of either face), use less than 180°, otherwise use the complement’?

Can you have one face the reverse of the other at the common edge? If so, I think the answer is indeterminate.

All faces are oriented properly.

What I am trying to do right now is this:

1. Create a temporary group
2. inside the group create another group that I will later explode
3. Use the normal from 1 of the 2 faces to create a transformation that will flatten that face and place it at ground level
4. create both faces inside the group that will be exploded
5. Apply the transformation and explode
6. One of the faces will be on the ground plane and the other will have vertices either above or below the ground plane.

This seems like overkill - but I think it will work.

Sounds as though it should. I can’t remember the Ruby method(s) that enable you to tell whether a point is on the plane of a face, [Edit: on the face side, or the reverse side] but I’m sure there is one.

I’ve got it working with the temporary groups

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.