BHoM / BHoM_Engine

Internal manipulation of the BHoM
GNU Lesser General Public License v3.0
26 stars 13 forks source link

Environment_Engine: Filter elements by orientation #1976

Closed tg359 closed 3 years ago

tg359 commented 3 years ago

Description:

A filter method to return objects where their normal is oriented in the given direction - ideally by angle from north (with tolerance).

The way I see this method working would be:

tg359 commented 3 years ago

I've just realised there is already an Orientation method in Environment.Engine. That saves us some hassle in getting the angle to Vector(0, 1, 0), but we'd still need to sort out the issue of clockwisedness to return the cardinal angle rather than the local angle.

https://github.com/BHoM/BHoM_Engine/blob/9a0ec1fa260f43c2aa76e3a35af20eae29adca64/Environment_Engine/Query/Orientation.cs#L35-L58

I propose setting defaults such that Vector(0, 1, 0) is the "north" angle in this method, and an option to return the azimuth of the surface normal from that instead of the current xyPlane normalised angle.

tg359 commented 3 years ago

I've played with the Orientation method, and I'm not too happy how it's working - there are a couple of issues in how it calculates angle to north especially when a panel is rotated in the YZ plane: north_0

The other issue is that the azimuth angle isn't returned, instead only the absolute angle between the surface normal and north: north_1

The ideal behaviour of the Orientation component would be:

[Description("Returns the orientation of a given environmental object")]
[Input("environmentObject", "Any object implementing the IEnvironmentObject interface that can have its orientation queried")]
[Input("northAngle", "The angle in degrees for north. Default is 0.0.")]
[Input("northAngle", "Set to true to return the azimuth angle from north instead of the angle between nortah and the object normal. Default is false.")]
[Output("orientation", "The orientation of the Environment Object")]
public static double Orientation(this IEnvironmentObject environmentObject, double northAngle = 0.0, bool azimuthAngle = false)
{
    // Check that the normal vector for the input object doesn't equal (0, 0, -1) or (0, 0, 1). If it does, return a warning that this method cannot successfully evaluate the orientation.
    // Set the base plane about which angles will be computed
    // Get the normal for the object being evaluated (and remove the Z-component to evaluate the angle difference about the base plane)
    // Set the north vector by converting the degrees input into a 2D Vector (default would be Vector(0, 1, 0))
    // Calculate the angle between north and the normal - and if azimuthAngle is true make sure that a west-facing object has an orientation of 270deg instead of 90deg which it would currently.
    // Return the resulting angle
}

Hopefully this won't break any workflows that already exist, or it could be added as an overload of the original method too if it needs to be.

After this is done, then we can start to filter by orientation - but without a robust orientation method it's a bit pointless!