hypar-io / Elements

The smallest useful BIM.
https://www.hypar.io
MIT License
354 stars 74 forks source link

Polyline.TransformAt has inconsistent behavior #392

Closed andrewheumann closed 4 years ago

andrewheumann commented 4 years ago

Describe the bug A transform taken at t=0 will be oriented totally differently from a transform located at t=0.001. The green volumes are all positioned with transforms from Polyline.TransformAt(t) — see how the start and end volumes are flipped relative to the rest.

image

To Reproduce Steps to reproduce the behavior: Create a polyline P take P.TransformAt(0) and P.TransformAt(0.001), compare their Y Axes

Expected behavior These orientations should be consistent along the length of the polyline

var polyline = new Polyline(new[] {
              new Vector3(0,0,0),
              new Vector3(20,0,0),
              new Vector3(20,20,0),
              new Vector3(0, 20,0),
            });

            var rectangle = Polygon.Rectangle(5, 10);

            var t1 = polyline.TransformAt(0);
            var t2 = polyline.TransformAt(0.01);
            var mc1 = new ModelCurve(rectangle, null, t1);
            var mc2 = new ModelCurve(rectangle, null, t2);
            var output = new LayoutRoomTestOutputs();
            output.Model.AddElement(mc1);
            output.Model.AddElement(mc2);
            return output;

results in this:

image

andrewheumann commented 4 years ago

Behavior is ALSO inconsistent between Bezier.TransformAt(0) and Polyline.TransformAt(0)

ikeough commented 4 years ago

Polylines do not follow the same convention as lines where a transform created at a parameter has its Z axis pointing along the curve and the XY plane is perpendicular to the curve. You can see in the image below that the first and last transform are correct in this regard and it's all of the other transforms that are incorrect.

image

ikeough commented 4 years ago

We want transforms to be consistently oriented along all curves with the X axis to the "right", the Y axis "up" and Z axis pointing backwards along the curve. This provides us a natural mapping of profiles defined in XY to be swept along the curve.

The attached image demonstrates a number of problems:

ikeough commented 4 years ago

The solution to the bezier problem is to use FrameType.RoadLike (FrameType.Frenet is the default), which still requires flipping the axes we were doing with cross product: image