Skip to content

Commit

Permalink
Merge pull request #1035 from DmytroMuravskyi/dmuravskyi/polycurve-tr…
Browse files Browse the repository at this point in the history
…ansform-at

Fix TransformAt for Polyline (#1035)

Co-Authored-By: Andrew Heumann <[email protected]>
  • Loading branch information
andrewheumann authored Oct 31, 2023
2 parents eb7aef0 + f8d87cb commit 8900409
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 27 deletions.
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

0 comments on commit 8900409

Please sign in to comment.