Skip to content

Commit

Permalink
Merge pull request #422 from DomCR/dedicated-boundingbox-tests
Browse files Browse the repository at this point in the history
Dedicated boundingbox tests
  • Loading branch information
DomCR authored Oct 3, 2024
2 parents eb4b2d5 + 74418da commit d2e0092
Show file tree
Hide file tree
Showing 23 changed files with 402 additions and 49 deletions.
13 changes: 13 additions & 0 deletions src/ACadSharp.Tests/Entities/ArcTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ public void CreateFromBulgeTest()
Assert.Equal(Math.PI / 2, arc.EndAngle);
}

[Fact]
public void GetBoundingBoxTest()
{
Arc arc = new Arc();
arc.Radius = 5;
arc.EndAngle = Math.PI / 2;

BoundingBox boundingBox = arc.GetBoundingBox();

Assert.Equal(new XYZ(0, 0, 0), boundingBox.Min);
Assert.Equal(new XYZ(5, 5, 0), boundingBox.Max);
}

[Fact]
public void GetCenter()
{
Expand Down
21 changes: 21 additions & 0 deletions src/ACadSharp.Tests/Entities/CircleTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using ACadSharp.Entities;
using CSMath;
using Xunit;

namespace ACadSharp.Tests.Entities
{
public class CircleTests
{
[Fact]
public void GetBoundingBoxTest()
{
Circle circle = new Circle();
circle.Radius = 5;

BoundingBox boundingBox = circle.GetBoundingBox();

Assert.Equal(new XYZ(-5, -5, 0), boundingBox.Min);
Assert.Equal(new XYZ(5, 5, 0), boundingBox.Max);
}
}
}
23 changes: 23 additions & 0 deletions src/ACadSharp.Tests/Entities/EllipseTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using ACadSharp.Entities;
using CSMath;
using System;
using Xunit;

namespace ACadSharp.Tests.Entities
{
public class EllipseTests
{
[Fact]
public void GetBoundingBoxTest()
{
//Ellipse size: x = 1, y = 0.5
Ellipse ellipse = new();
ellipse.RadiusRatio = 0.5d;

BoundingBox boundingBox = ellipse.GetBoundingBox();

Assert.Equal(new XYZ(-1, -0.5, 0), boundingBox.Min);
Assert.Equal(new XYZ(1, 0.5, 0), boundingBox.Max);
}
}
}
25 changes: 25 additions & 0 deletions src/ACadSharp.Tests/Entities/HatchTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,30 @@ public void PolylineHatchNotAllowMoreEdges()
}
);
}

[Fact]
public void GetBoundingBoxTest()
{
Hatch hatch = new Hatch();
hatch.IsSolid = true;

Hatch.BoundaryPath path = new Hatch.BoundaryPath();

Hatch.BoundaryPath.Polyline pline = new Hatch.BoundaryPath.Polyline();
pline.Vertices.Add(new XYZ(0, 0, 0));
pline.Vertices.Add(new XYZ(1, 0, 0));
pline.Vertices.Add(new XYZ(1, 1, 0));
pline.Vertices.Add(new XYZ(0, 1, 0));
pline.Vertices.Add(new XYZ(0, 0, 0));

path.Edges.Add(pline);

hatch.Paths.Add(path);

var box = hatch.GetBoundingBox();

Assert.Equal(new XYZ(0, 0, 0), box.Min);
Assert.Equal(new XYZ(1, 1, 0), box.Max);
}
}
}
21 changes: 21 additions & 0 deletions src/ACadSharp.Tests/Entities/LineTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using ACadSharp.Entities;
using CSMath;
using Xunit;

namespace ACadSharp.Tests.Entities
{
public class LineTests
{
[Fact]
public void GetBoundingBoxTest()
{
Line line = new Line();
line.EndPoint = new XYZ(10, 10, 0);

BoundingBox boundingBox = line.GetBoundingBox();

Assert.Equal(new XYZ(0, 0, 0), boundingBox.Min);
Assert.Equal(new XYZ(10, 10, 0), boundingBox.Max);
}
}
}
12 changes: 12 additions & 0 deletions src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using ACadSharp.Tables;
using CSMath;
using CSUtilities.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -107,6 +108,16 @@ public void CurrentEntityByBlock()
this.Document.Header.CurrentEntityColor = Color.ByBlock;
}

public void SingleEllipse()
{
Ellipse ellipse = new Ellipse();
ellipse.RadiusRatio = 0.5d;
ellipse.StartParameter = 0.0d;
ellipse.EndParameter = Math.PI * 2;

this.Document.Entities.Add(ellipse);
}

public void SingleLine()
{
Line line = new Line(XYZ.Zero, new XYZ(100, 100, 0));
Expand Down Expand Up @@ -452,6 +463,7 @@ static WriterSingleObjectTests()
}

Data.Add(new(nameof(SingleCaseGenerator.Empty)));
Data.Add(new(nameof(SingleCaseGenerator.SingleEllipse)));
Data.Add(new(nameof(SingleCaseGenerator.SingleLine)));
Data.Add(new(nameof(SingleCaseGenerator.SingleMLine)));
Data.Add(new(nameof(SingleCaseGenerator.EntityColorByLayer)));
Expand Down
2 changes: 1 addition & 1 deletion src/ACadSharp/CadObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public CadDictionary CreateExtendedDictionary()
/// Creates a new object that is a copy of the current instance.
/// </summary>
/// <remarks>
/// The copy will be unatached from the document or any reference
/// The copy will be unattached from the document or any reference.
/// </remarks>
/// <returns>A new object that is a copy of this instance.</returns>
public virtual CadObject Clone()
Expand Down
9 changes: 9 additions & 0 deletions src/ACadSharp/Entities/Arc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using CSMath;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ACadSharp.Entities
{
Expand Down Expand Up @@ -126,5 +127,13 @@ public List<XY> PolygonalVertexes(int precision)

return ocsVertexes;
}

/// <inheritdoc/>
public override BoundingBox GetBoundingBox()
{
List<XY> vertices = this.PolygonalVertexes(256);

return BoundingBox.FromPoints(vertices.Select(v => (XYZ)v));
}
}
}
8 changes: 4 additions & 4 deletions src/ACadSharp/Entities/Dimension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ public bool IsTextUserDefinedLocation
/// <b>true</b> if the arrow is to be flipped; otherwise, <b>false</b>.
/// </value>
/// <remarks>
/// Arrows are by default drawn inside the extension lines if there is enaugh
/// space; otherwise, outside. This flag overrules the standard behaviour.
/// Arrows are by default drawn inside the extension lines if there is enough
/// space; otherwise, outside. This flag overrules the standard behavior.
/// </remarks>
[DxfCodeValue(74)]
public bool FlipArrow1 { get; set; }
Expand All @@ -142,8 +142,8 @@ public bool IsTextUserDefinedLocation
/// <b>true</b> if the arrow is to be flipped; otherwise, <b>false</b>.
/// </value>
/// <remarks>
/// Arrows are by default drawn inside the extension lines if there is enaugh
/// space; otherwise, outside. This flag overrules the standard behaviour.
/// Arrows are by default drawn inside the extension lines if there is enough
/// space; otherwise, outside. This flag overrules the standard behavior.
/// </remarks>
[DxfCodeValue(75)]
public bool FlipArrow2 { get; set; }
Expand Down
119 changes: 116 additions & 3 deletions src/ACadSharp/Entities/Ellipse.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using ACadSharp.Attributes;
using CSMath;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ACadSharp.Entities
{
Expand Down Expand Up @@ -45,8 +47,11 @@ public class Ellipse : Entity
/// <summary>
/// Endpoint of major axis, relative to the center (in WCS).
/// </summary>
/// <remarks>
/// Axis X is set as default.
/// </remarks>
[DxfCodeValue(11, 21, 31)]
public XYZ EndPoint { get; set; } = XYZ.Zero;
public XYZ EndPoint { get; set; } = XYZ.AxisX;

/// <summary>
/// Ratio of minor axis to major axis.
Expand All @@ -70,12 +75,120 @@ public class Ellipse : Entity
/// The valid range is 0 to 2 * PI.
/// </value>
[DxfCodeValue(42)]
public double EndParameter { get; set; } = Math.PI * 2;
public double EndParameter { get; set; } = MathUtils.TwoPI;

/// <summary>
/// Rotation of the major axis from the world X axis.
/// </summary>
public double Rotation
{
get
{
return ((XY)this.EndPoint).GetAngle();
}
}

/// <summary>
/// Length of the major axis.
/// </summary>
public double MajorAxis { get { return 2 * this.EndPoint.GetLength(); } }

/// <summary>
/// Length of the minor axis.
/// </summary>
public double MinorAxis { get { return this.MajorAxis * this.RadiusRatio; } }

/// <summary>
/// Flag that indicates weather this ellipse is closed or not.
/// </summary>
public bool IsFullEllipse { get { return this.StartParameter == 0 && this.EndParameter == MathUtils.TwoPI; } }

/// <summary>
/// Calculate the local point on the ellipse for a given angle relative to the center.
/// </summary>
/// <param name="angle">Angle in radians.</param>
/// <returns>A local point on the ellipse for the given angle relative to the center.</returns>
public XY PolarCoordinateRelativeToCenter(double angle)
{
double a = this.MajorAxis * 0.5;
double b = this.MinorAxis * 0.5;

double a1 = a * Math.Sin((double)angle);
double b1 = b * Math.Cos((double)angle);

double radius = a * b / Math.Sqrt(b1 * b1 + a1 * a1);

// convert the radius back to Cartesian coordinates
return new XY(radius * Math.Cos((double)angle), radius * Math.Sin((double)angle));
}

/// <summary>
/// Converts the ellipse in a list of vertexes.
/// </summary>
/// <param name="precision">Number of vertexes generated.</param>
/// <returns>A list vertexes that represents the ellipse expressed in object coordinate system.</returns>
public List<XY> PolygonalVertexes(int precision)
{
if (precision < 2)
{
throw new ArgumentOutOfRangeException(nameof(precision), precision, "The arc precision must be equal or greater than two.");
}

List<XY> points = new List<XY>();
double beta = this.Rotation;
double sinBeta = Math.Sin(beta);
double cosBeta = Math.Cos(beta);
double start;
double end;
double steps;

if (this.IsFullEllipse)
{
start = 0;
end = MathUtils.TwoPI;
steps = precision;
}
else
{
XY startPoint = this.PolarCoordinateRelativeToCenter(this.StartParameter);
XY endPoint = this.PolarCoordinateRelativeToCenter(this.EndParameter);
double a = 1 / (0.5 * this.MajorAxis);
double b = 1 / (0.5 * this.MinorAxis);
start = Math.Atan2(startPoint.Y * b, startPoint.X * a);
end = Math.Atan2(endPoint.Y * b, endPoint.X * a);

if (end < start)
{
end += MathUtils.TwoPI;
}
steps = precision - 1;
}

double delta = (end - start) / steps;

for (int i = 0; i < precision; i++)
{
double angle = start + delta * i;
double sinAlpha = Math.Sin(angle);
double cosAlpha = Math.Cos(angle);

double pointX = 0.5 * (this.MajorAxis * cosAlpha * cosBeta - this.MinorAxis * sinAlpha * sinBeta);
double pointY = 0.5 * (this.MajorAxis * cosAlpha * sinBeta + this.MinorAxis * sinAlpha * cosBeta);

pointX = MathUtils.FixZero(pointX);
pointY = MathUtils.FixZero(pointY);

points.Add(new XY(pointX, pointY));
}

return points;
}

/// <inheritdoc/>
public override BoundingBox GetBoundingBox()
{
return BoundingBox.Null;
List<XY> pts = this.PolygonalVertexes(100);
return BoundingBox.FromPoints(pts.Select(p => (XYZ)p));
}
}
}
5 changes: 1 addition & 4 deletions src/ACadSharp/Entities/Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,7 @@ public LineType LineType
/// <inheritdoc/>
public Entity() : base() { }

/// <summary>
/// Gets the bounding box aligned with the axis XYZ that ocupies this entity
/// </summary>
/// <returns></returns>
/// <inheritdoc/>
public abstract BoundingBox GetBoundingBox();

/// <inheritdoc/>
Expand Down
Loading

0 comments on commit d2e0092

Please sign in to comment.