Skip to content

Commit a217359

Browse files
committed
storing transformationmatrix inelliptical arc
1 parent 8437c50 commit a217359

2 files changed

Lines changed: 17 additions & 25 deletions

File tree

src/ImageSharp.Drawing/Shapes/EllipticalArcLineSegment.cs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public sealed class EllipticalArcLineSegment : ILineSegment
2121
private readonly float rotation;
2222
private readonly float startAngle;
2323
private readonly float sweepAngle;
24+
private readonly Matrix3x2 transformation;
2425

2526
/// <summary>
2627
/// Initializes a new instance of the <see cref="EllipticalArcLineSegment"/> class.
@@ -31,7 +32,8 @@ public sealed class EllipticalArcLineSegment : ILineSegment
3132
/// <param name="rotation">The rotation of First radius to the X-Axis</param>
3233
/// <param name="startAngle">The Start angle of the ellipsis</param>
3334
/// <param name="sweepAngle"> The sweeping angle of the arc</param>
34-
public EllipticalArcLineSegment(PointF center, float firstRadius, float secondRadius, float rotation, float startAngle, float sweepAngle)
35+
/// <param name="transformation">The TRanformation matrix, that should be used on the arc</param>
36+
public EllipticalArcLineSegment(PointF center, float firstRadius, float secondRadius, float rotation, float startAngle, float sweepAngle, Matrix3x2 transformation)
3537
{
3638
Guard.MustBeGreaterThan(firstRadius, 0, nameof(firstRadius));
3739
Guard.MustBeGreaterThan(secondRadius, 0, nameof(secondRadius));
@@ -51,6 +53,7 @@ public EllipticalArcLineSegment(PointF center, float firstRadius, float secondRa
5153

5254
this.linePoints = this.GetDrawingPoints();
5355
this.EndPoint = this.linePoints[this.linePoints.Length - 1];
56+
this.transformation = transformation;
5457
}
5558

5659
/// <summary>
@@ -64,7 +67,7 @@ public EllipticalArcLineSegment(PointF center, float firstRadius, float secondRa
6467
/// <summary>
6568
/// Transforms the current LineSegment using specified matrix.
6669
/// </summary>
67-
/// <param name="matrix">The matrix.</param>
70+
/// <param name="matrix">The transformation matrix.</param>
6871
/// <returns>A line segment with the matrix applied to it.</returns>
6972
public EllipticalArcLineSegment Transform(Matrix3x2 matrix)
7073
{
@@ -73,15 +76,7 @@ public EllipticalArcLineSegment Transform(Matrix3x2 matrix)
7376
return this;
7477
}
7578

76-
PointF center = PointF.Transform(this.center, matrix);
77-
PointF helpFirstRadius = PointF.Transform(CalculatePoint(90, this.firstRadius, this.secondRadius, this.rotation, this.center), matrix);
78-
PointF helpSecondRadius = PointF.Transform(CalculatePoint(0, this.firstRadius, this.secondRadius, this.rotation, this.center), matrix);
79-
float firstRadius = new Vector2(center.X - helpFirstRadius.X, center.Y - helpFirstRadius.Y).Length();
80-
float secondRadius = new Vector2(center.X - helpSecondRadius.X, center.Y - helpSecondRadius.Y).Length();
81-
Vector2 helperRotation1 = new Vector2(helpFirstRadius.X - center.X, helpFirstRadius.Y - center.Y);
82-
Vector2 helperRotation2 = new Vector2(firstRadius, 0);
83-
float rotatation = (float)Math.Acos(Vector2.Dot(helperRotation1, helperRotation2) / (helperRotation1.Length() * helperRotation2.Length()));
84-
return new EllipticalArcLineSegment(center, firstRadius, secondRadius, rotation,);
79+
return new EllipticalArcLineSegment(this.center, this.firstRadius, this.secondRadius, this.rotation, this.startAngle, this.sweepAngle, Matrix3x2.Multiply(this.transformation, matrix));
8580
}
8681

8782
/// <summary>
@@ -93,8 +88,9 @@ public EllipticalArcLineSegment Transform(Matrix3x2 matrix)
9388

9489
private PointF[] GetDrawingPoints()
9590
{
96-
var points = new List<PointF>() {
97-
CalculatePoint(this.startAngle, this.firstRadius, this.secondRadius, this.rotation, this.center)
91+
var points = new List<PointF>()
92+
{
93+
this.CalculatePoint(this.startAngle)
9894
};
9995

10096
for (float i = this.startAngle; i < this.startAngle + this.sweepAngle; i++)
@@ -120,8 +116,8 @@ private List<PointF> GetDrawingPoints(float start, float end, int depth)
120116

121117
var points = new List<PointF>();
122118

123-
PointF startP = CalculatePoint(start, this.firstRadius, this.secondRadius, this.rotation, this.center);
124-
PointF endP = CalculatePoint(end, this.firstRadius, this.secondRadius, this.rotation, this.center);
119+
PointF startP = this.CalculatePoint(start);
120+
PointF endP = this.CalculatePoint(end);
125121
if ((new Vector2(endP.X, endP.Y) - new Vector2(startP.X, startP.Y)).LengthSquared() < MinimumSqrDistance)
126122
{
127123
points.Add(endP);
@@ -136,11 +132,11 @@ private List<PointF> GetDrawingPoints(float start, float end, int depth)
136132
return points;
137133
}
138134

139-
private static PointF CalculatePoint(float angle, float firstRadius, float secondRadius, float rotation, PointF center)
135+
private PointF CalculatePoint(float angle)
140136
{
141-
float x = (float)((firstRadius * Math.Sin(Math.PI * angle / 180) * Math.Cos(Math.PI * rotation / 180)) - (secondRadius * Math.Cos(Math.PI * angle / 180) * Math.Sin(Math.PI * rotation / 180)) + center.X);
142-
float y = (float)((firstRadius * Math.Sin(Math.PI * angle / 180) * Math.Sin(Math.PI * rotation / 180)) + (secondRadius * Math.Cos(Math.PI * angle / 180) * Math.Cos(Math.PI * rotation / 180)) + center.Y);
143-
return new PointF(x, y);
137+
float x = (float)((this.firstRadius * Math.Sin(Math.PI * angle / 180) * Math.Cos(Math.PI * this.rotation / 180)) - (this.secondRadius * Math.Cos(Math.PI * angle / 180) * Math.Sin(Math.PI * this.rotation / 180)) + this.center.X);
138+
float y = (float)((this.firstRadius * Math.Sin(Math.PI * angle / 180) * Math.Sin(Math.PI * this.rotation / 180)) + (this.secondRadius * Math.Cos(Math.PI * angle / 180) * Math.Cos(Math.PI * this.rotation / 180)) + this.center.Y);
139+
return PointF.Transform(new PointF(x, y), this.transformation);
144140
}
145141

146142
/// <summary>
@@ -149,9 +145,6 @@ private static PointF CalculatePoint(float angle, float firstRadius, float secon
149145
/// <returns>
150146
/// Returns the current <see cref="ILineSegment" /> as simple linear path.
151147
/// </returns>
152-
public ReadOnlyMemory<PointF> Flatten()
153-
{
154-
return this.linePoints;
155-
}
148+
public ReadOnlyMemory<PointF> Flatten() => this.linePoints;
156149
}
157150
}

src/ImageSharp.Drawing/Shapes/PathBuilder.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,7 @@ public PathBuilder AddBezier(PointF startPoint, PointF controlPoint1, PointF con
211211
/// <returns>The <see cref="PathBuilder"/></returns>
212212
public PathBuilder AddEllipticalArc(PointF center, float firstRadius, float secondRadius, float rotation, float startAngle, float sweepAngle)
213213
{
214-
EllipticalArcLineSegment arc = new EllipticalArcLineSegment(center, firstRadius, secondRadius, rotation, startAngle, sweepAngle);
215-
arc.Transform(this.currentTransform);
214+
EllipticalArcLineSegment arc = new EllipticalArcLineSegment(center, firstRadius, secondRadius, rotation, startAngle, sweepAngle, this.currentTransform);
216215
this.currentFigure.AddSegment(arc);
217216
return this;
218217
}

0 commit comments

Comments
 (0)