Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix TransformAt for Polyline #1035

Merged
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@
- `IndexedPolycurve.GetSubdivisionParameters` now works correctly with `startSetbackDistance` and `endSetbackDistance` parameters.
- `Polyline.Frames` now works correctly with `startSetbackDistance` and `endSetbackDistance` parameters.
- `Polygon.Frames` now works correctly with `startSetbackDistance` and `endSetbackDistance` parameters.
- `Polyline.TransformAt` returns correct transformations when parameter on domain is provided.
- `IndexedPolycurve` constructor that takes list of `BoundedCurve` now produces `CurveIndices` that share vertices and are withing index range. This means `IndexedPolyline.TransformedPolyline` preserves `CurveIndicies` on new `IndexedPolyline`.
- `BoundedCurve.ToPolyline` now works correctly for `EllipticalArc` class.


### Changed
- `GltfExtensions.UseReferencedContentExtension` is now true by default.
- `GeometricElement.Intersects` method now supports multiple representations.
Expand Down
4 changes: 2 additions & 2 deletions Elements/src/Geometry/IndexedPolycurve.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,15 @@ private static (List<IList<int>>, List<Vector3>) CreateVerticesAndCurveIndices(I
vertices.Add(curve.Start);
last = curve.End;
curveIndices.Add(new[] { index, index + 1 });
index += 2;
index += 1;
}
else if (curve is Arc)
{
vertices.Add(curve.Start);
vertices.Add(curve.Mid());
last = curve.End;
curveIndices.Add(new[] { index, index + 1, index + 2 });
index += 3;
index += 2;
}
else
{
Expand Down
34 changes: 10 additions & 24 deletions Elements/src/Geometry/Polyline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,7 @@ public override Transform TransformAt(double u)
throw new Exception($"The parameter {u} is not on the trimmed portion of the basis curve. The parameter must be between {Domain.Min} and {Domain.Max}.");
}

var segmentIndex = 0;
var o = PointAtInternal(u, out segmentIndex);
Vector3 x = Vector3.XAxis; // Vector3: Convert to XAxis
var o = PointAtInternal(u, out var segmentIndex);

// Check if the provided parameter is equal
// to one of the vertices.
Expand All @@ -119,7 +117,7 @@ public override Transform TransformAt(double u)
{
var idx = this.Vertices.IndexOf(a);

if (idx == 0 || idx == this.Vertices.Count - 1)
if (!(this is Polygon) && (idx == 0 || idx == this.Vertices.Count - 1))
{
return CreateOrthogonalTransform(idx, a, normals[idx]);
}
Expand All @@ -129,26 +127,14 @@ public override Transform TransformAt(double u)
}
}

var d = this.Length() * u;
var totalLength = 0.0;
var segments = Segments();
var normal = new Vector3();
for (var i = 0; i < segments.Length; i++)
{
var s = segments[i];
var currLength = s.Length();
if (totalLength <= d && totalLength + currLength >= d)
{
var parameterOnSegment = d - totalLength;
o = s.PointAt(parameterOnSegment);
var previousNormal = normals[i];
var nextNormal = normals[(i + 1) % this.Vertices.Count];
normal = ((nextNormal - previousNormal) * parameterOnSegment + previousNormal).Unitized();
x = s.Direction().Cross(normal);
break;
}
totalLength += currLength;
}
var nextIndex = (segmentIndex + 1) % this.Vertices.Count;
var segment = new Line(Vertices[segmentIndex], Vertices[nextIndex]);
var parameterOnSegment = u - segmentIndex;
var previousNormal = normals[segmentIndex];
var nextNormal = normals[nextIndex];
var normal = ((nextNormal - previousNormal) * parameterOnSegment + previousNormal).Unitized();
var x = segment.Direction().Cross(normal);

return new Transform(o, x, normal, x.Cross(normal));
}

Expand Down
18 changes: 18 additions & 0 deletions Elements/test/IndexedPolyCurveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,24 @@ public void Intersects()
Assert.Contains(new Vector3(2.5, 7.5), results);
}

[Fact]
public void PreservesIndicesTransformed()
{
var pc = CreateTestPolycurve();
var indices = pc.CurveIndices;
var copy = pc.TransformedPolycurve(new Transform(10, 0, 0));
var newIndicies = copy.CurveIndices;
Assert.Equal(indices.Count, newIndicies.Count);
for (int i = 0; i < indices.Count; i++)
{
Assert.Equal(indices[i].Count, newIndicies[i].Count);
for (int j = 0; j < indices[i].Count; j++)
{
Assert.Equal(indices[i][j], newIndicies[i][j]);
}
}
}

[Fact]
public void GetSubdivisionParameters()
{
Expand Down
30 changes: 30 additions & 0 deletions Elements/test/PolylineTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,36 @@ public void PolylineForceAngleComplianceWithZeroAngle()
Assert.True(CheckPolylineAngles(angles, normalizedPathEndYAxisReferenceVector));
}

[Fact]
public void PolylineTransformAt()
{
var polyline = new Polyline((0, 0), (5, 0), (5, 10), (-5, 10));

var transform = polyline.TransformAt(0);
Assert.Equal((0, 0), transform.Origin);
Assert.Equal(Vector3.XAxis.Negate(), transform.ZAxis);

transform = polyline.TransformAt(0.5);
Assert.Equal((2.5, 0), transform.Origin);
Assert.Equal(Vector3.XAxis.Negate(), transform.ZAxis);

transform = polyline.TransformAt(1);
Assert.Equal((5, 0), transform.Origin);
Assert.Equal((Vector3.XAxis + Vector3.YAxis).Unitized().Negate(), transform.ZAxis);

transform = polyline.TransformAt(1.25);
Assert.Equal((5, 2.5), transform.Origin);
Assert.Equal(Vector3.YAxis.Negate(), transform.ZAxis);

transform = polyline.TransformAt(2);
Assert.Equal((5, 10), transform.Origin);
Assert.Equal((Vector3.YAxis - Vector3.XAxis).Unitized().Negate(), transform.ZAxis);

transform = polyline.TransformAt(2.75);
Assert.Equal((-2.5, 10), transform.Origin);
Assert.Equal(Vector3.XAxis, transform.ZAxis);
}

[Fact]
public void Frames()
{
Expand Down
Loading