diff --git a/src/ACadSharp.Tests/Entities/ArcTests.cs b/src/ACadSharp.Tests/Entities/ArcTests.cs
index 45250e62..ce201169 100644
--- a/src/ACadSharp.Tests/Entities/ArcTests.cs
+++ b/src/ACadSharp.Tests/Entities/ArcTests.cs
@@ -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()
{
diff --git a/src/ACadSharp.Tests/Entities/CircleTests.cs b/src/ACadSharp.Tests/Entities/CircleTests.cs
new file mode 100644
index 00000000..5944f84e
--- /dev/null
+++ b/src/ACadSharp.Tests/Entities/CircleTests.cs
@@ -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);
+ }
+ }
+}
diff --git a/src/ACadSharp.Tests/Entities/EllipseTests.cs b/src/ACadSharp.Tests/Entities/EllipseTests.cs
new file mode 100644
index 00000000..e0f59a7f
--- /dev/null
+++ b/src/ACadSharp.Tests/Entities/EllipseTests.cs
@@ -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);
+ }
+ }
+}
diff --git a/src/ACadSharp.Tests/Entities/HatchTests.cs b/src/ACadSharp.Tests/Entities/HatchTests.cs
index c92b04d1..4ae79b72 100644
--- a/src/ACadSharp.Tests/Entities/HatchTests.cs
+++ b/src/ACadSharp.Tests/Entities/HatchTests.cs
@@ -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);
+ }
}
}
diff --git a/src/ACadSharp.Tests/Entities/LineTests.cs b/src/ACadSharp.Tests/Entities/LineTests.cs
new file mode 100644
index 00000000..572e8ae4
--- /dev/null
+++ b/src/ACadSharp.Tests/Entities/LineTests.cs
@@ -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);
+ }
+ }
+}
diff --git a/src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs b/src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs
index d3c7151b..e0614709 100644
--- a/src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs
+++ b/src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs
@@ -3,6 +3,7 @@
using ACadSharp.Tables;
using CSMath;
using CSUtilities.Extensions;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -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));
@@ -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)));
diff --git a/src/ACadSharp/CadObject.cs b/src/ACadSharp/CadObject.cs
index 612edf04..487cbd84 100644
--- a/src/ACadSharp/CadObject.cs
+++ b/src/ACadSharp/CadObject.cs
@@ -106,7 +106,7 @@ public CadDictionary CreateExtendedDictionary()
/// Creates a new object that is a copy of the current instance.
///
///
- /// The copy will be unatached from the document or any reference
+ /// The copy will be unattached from the document or any reference.
///
/// A new object that is a copy of this instance.
public virtual CadObject Clone()
diff --git a/src/ACadSharp/Entities/Arc.cs b/src/ACadSharp/Entities/Arc.cs
index b6d723ac..4d7c19b8 100644
--- a/src/ACadSharp/Entities/Arc.cs
+++ b/src/ACadSharp/Entities/Arc.cs
@@ -2,6 +2,7 @@
using CSMath;
using System;
using System.Collections.Generic;
+using System.Linq;
namespace ACadSharp.Entities
{
@@ -126,5 +127,13 @@ public List PolygonalVertexes(int precision)
return ocsVertexes;
}
+
+ ///
+ public override BoundingBox GetBoundingBox()
+ {
+ List vertices = this.PolygonalVertexes(256);
+
+ return BoundingBox.FromPoints(vertices.Select(v => (XYZ)v));
+ }
}
}
diff --git a/src/ACadSharp/Entities/Dimension.cs b/src/ACadSharp/Entities/Dimension.cs
index e98fb879..11904f55 100644
--- a/src/ACadSharp/Entities/Dimension.cs
+++ b/src/ACadSharp/Entities/Dimension.cs
@@ -128,8 +128,8 @@ public bool IsTextUserDefinedLocation
/// true if the arrow is to be flipped; otherwise, false.
///
///
- /// 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.
///
[DxfCodeValue(74)]
public bool FlipArrow1 { get; set; }
@@ -142,8 +142,8 @@ public bool IsTextUserDefinedLocation
/// true if the arrow is to be flipped; otherwise, false.
///
///
- /// 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.
///
[DxfCodeValue(75)]
public bool FlipArrow2 { get; set; }
diff --git a/src/ACadSharp/Entities/Ellipse.cs b/src/ACadSharp/Entities/Ellipse.cs
index 32716e56..60751e13 100644
--- a/src/ACadSharp/Entities/Ellipse.cs
+++ b/src/ACadSharp/Entities/Ellipse.cs
@@ -1,6 +1,8 @@
using ACadSharp.Attributes;
using CSMath;
using System;
+using System.Collections.Generic;
+using System.Linq;
namespace ACadSharp.Entities
{
@@ -45,8 +47,11 @@ public class Ellipse : Entity
///
/// Endpoint of major axis, relative to the center (in WCS).
///
+ ///
+ /// Axis X is set as default.
+ ///
[DxfCodeValue(11, 21, 31)]
- public XYZ EndPoint { get; set; } = XYZ.Zero;
+ public XYZ EndPoint { get; set; } = XYZ.AxisX;
///
/// Ratio of minor axis to major axis.
@@ -70,12 +75,120 @@ public class Ellipse : Entity
/// The valid range is 0 to 2 * PI.
///
[DxfCodeValue(42)]
- public double EndParameter { get; set; } = Math.PI * 2;
+ public double EndParameter { get; set; } = MathUtils.TwoPI;
+
+ ///
+ /// Rotation of the major axis from the world X axis.
+ ///
+ public double Rotation
+ {
+ get
+ {
+ return ((XY)this.EndPoint).GetAngle();
+ }
+ }
+
+ ///
+ /// Length of the major axis.
+ ///
+ public double MajorAxis { get { return 2 * this.EndPoint.GetLength(); } }
+
+ ///
+ /// Length of the minor axis.
+ ///
+ public double MinorAxis { get { return this.MajorAxis * this.RadiusRatio; } }
+
+ ///
+ /// Flag that indicates weather this ellipse is closed or not.
+ ///
+ public bool IsFullEllipse { get { return this.StartParameter == 0 && this.EndParameter == MathUtils.TwoPI; } }
+
+ ///
+ /// Calculate the local point on the ellipse for a given angle relative to the center.
+ ///
+ /// Angle in radians.
+ /// A local point on the ellipse for the given angle relative to the center.
+ 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));
+ }
+
+ ///
+ /// Converts the ellipse in a list of vertexes.
+ ///
+ /// Number of vertexes generated.
+ /// A list vertexes that represents the ellipse expressed in object coordinate system.
+ public List PolygonalVertexes(int precision)
+ {
+ if (precision < 2)
+ {
+ throw new ArgumentOutOfRangeException(nameof(precision), precision, "The arc precision must be equal or greater than two.");
+ }
+
+ List points = new List();
+ 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;
+ }
///
public override BoundingBox GetBoundingBox()
{
- return BoundingBox.Null;
+ List pts = this.PolygonalVertexes(100);
+ return BoundingBox.FromPoints(pts.Select(p => (XYZ)p));
}
}
}
diff --git a/src/ACadSharp/Entities/Entity.cs b/src/ACadSharp/Entities/Entity.cs
index 0e1d9f2c..9b2ce7a7 100644
--- a/src/ACadSharp/Entities/Entity.cs
+++ b/src/ACadSharp/Entities/Entity.cs
@@ -92,10 +92,7 @@ public LineType LineType
///
public Entity() : base() { }
- ///
- /// Gets the bounding box aligned with the axis XYZ that ocupies this entity
- ///
- ///
+ ///
public abstract BoundingBox GetBoundingBox();
///
diff --git a/src/ACadSharp/Entities/Hatch.BoundaryPath.Arc.cs b/src/ACadSharp/Entities/Hatch.BoundaryPath.Arc.cs
index 021d6990..a6bd6ba2 100644
--- a/src/ACadSharp/Entities/Hatch.BoundaryPath.Arc.cs
+++ b/src/ACadSharp/Entities/Hatch.BoundaryPath.Arc.cs
@@ -13,37 +13,43 @@ public class Arc : Edge
public override EdgeType Type => EdgeType.CircularArc;
///
- /// Center point (in OCS)
+ /// Center point (in OCS).
///
[DxfCodeValue(10, 20)]
public XY Center { get; set; }
///
- /// Radius
+ /// Radius.
///
///
- /// For the ellispe this is the length of minor axis (percentage of major axis length)
+ /// For the ellipse this is the length of minor axis (percentage of major axis length).
///
[DxfCodeValue(40)]
public double Radius { get; set; }
///
- /// Start angle
+ /// Start angle.
///
[DxfCodeValue(50)]
public double StartAngle { get; set; }
///
- /// End angle
+ /// End angle.
///
[DxfCodeValue(51)]
public double EndAngle { get; set; }
///
- /// Is counterclockwise flag
+ /// Is counterclockwise flag.
///
[DxfCodeValue(73)]
public bool CounterClockWise { get; set; }
+
+ ///
+ public override BoundingBox GetBoundingBox()
+ {
+ throw new System.NotImplementedException();
+ }
}
}
}
diff --git a/src/ACadSharp/Entities/Hatch.BoundaryPath.Edge.cs b/src/ACadSharp/Entities/Hatch.BoundaryPath.Edge.cs
index 5fdb91b8..b5418b20 100644
--- a/src/ACadSharp/Entities/Hatch.BoundaryPath.Edge.cs
+++ b/src/ACadSharp/Entities/Hatch.BoundaryPath.Edge.cs
@@ -1,4 +1,6 @@
-namespace ACadSharp.Entities
+using CSMath;
+
+namespace ACadSharp.Entities
{
public partial class Hatch
{
@@ -10,7 +12,7 @@ public partial class BoundaryPath
public enum EdgeType
{
///
- /// Not included in the documentation
+ /// Not included in the documentation.
///
Polyline = 0,
Line = 1,
@@ -19,12 +21,24 @@ public enum EdgeType
Spline = 4,
}
- public abstract class Edge
+ public abstract class Edge : IGeometricEntity
{
///
- /// Edge type
+ /// Edge type.
///
public abstract EdgeType Type { get; }
+
+ ///
+ /// Creates a new object that is a copy of the current instance.
+ ///
+ ///
+ public Edge Clone()
+ {
+ return (Edge)this.MemberwiseClone();
+ }
+
+ ///
+ public abstract BoundingBox GetBoundingBox();
}
}
}
diff --git a/src/ACadSharp/Entities/Hatch.BoundaryPath.Ellipse.cs b/src/ACadSharp/Entities/Hatch.BoundaryPath.Ellipse.cs
index b538e424..4d0b971d 100644
--- a/src/ACadSharp/Entities/Hatch.BoundaryPath.Ellipse.cs
+++ b/src/ACadSharp/Entities/Hatch.BoundaryPath.Ellipse.cs
@@ -47,6 +47,12 @@ public class Ellipse : Edge
///
[DxfCodeValue(73)]
public bool CounterClockWise { get; set; }
+
+ ///
+ public override BoundingBox GetBoundingBox()
+ {
+ throw new System.NotImplementedException();
+ }
}
}
}
diff --git a/src/ACadSharp/Entities/Hatch.BoundaryPath.Line.cs b/src/ACadSharp/Entities/Hatch.BoundaryPath.Line.cs
index 40ec81e2..ee034be4 100644
--- a/src/ACadSharp/Entities/Hatch.BoundaryPath.Line.cs
+++ b/src/ACadSharp/Entities/Hatch.BoundaryPath.Line.cs
@@ -22,6 +22,13 @@ public class Line : Edge
///
[DxfCodeValue(11, 21)]
public XY End { get; set; }
+
+
+ ///
+ public override BoundingBox GetBoundingBox()
+ {
+ return BoundingBox.FromPoints([(XYZ)this.Start, (XYZ)this.End]);
+ }
}
}
}
diff --git a/src/ACadSharp/Entities/Hatch.BoundaryPath.Polyline.cs b/src/ACadSharp/Entities/Hatch.BoundaryPath.Polyline.cs
index 93298c77..9af200aa 100644
--- a/src/ACadSharp/Entities/Hatch.BoundaryPath.Polyline.cs
+++ b/src/ACadSharp/Entities/Hatch.BoundaryPath.Polyline.cs
@@ -43,6 +43,12 @@ public class Polyline : Edge
///
[DxfCodeValue(DxfReferenceType.Count, 93)]
public List Vertices { get; set; } = new();
+
+ ///
+ public override BoundingBox GetBoundingBox()
+ {
+ return BoundingBox.FromPoints(this.Vertices);
+ }
}
}
}
diff --git a/src/ACadSharp/Entities/Hatch.BoundaryPath.Spline.cs b/src/ACadSharp/Entities/Hatch.BoundaryPath.Spline.cs
index 842a55db..859c3236 100644
--- a/src/ACadSharp/Entities/Hatch.BoundaryPath.Spline.cs
+++ b/src/ACadSharp/Entities/Hatch.BoundaryPath.Spline.cs
@@ -14,53 +14,59 @@ public class Spline : Edge
public override EdgeType Type => EdgeType.Spline;
///
- /// Degree
+ /// Degree.
///
[DxfCodeValue(94)]
public int Degree { get; set; }
///
- /// Rational
+ /// Rational.
///
[DxfCodeValue(73)]
public bool Rational { get; set; }
///
- /// Periodic
+ /// Periodic.
///
[DxfCodeValue(74)]
public bool Periodic { get; set; }
///
- /// Number of knots
+ /// Number of knots.
///
[DxfCodeValue(95)]
public List Knots { get; set; } = new List();
///
- /// Position values are only X and Y, Z represents the weight
+ /// Position values are only X and Y, Z represents the weight.
///
[DxfCodeValue(96)]
//42 Weights(optional, default = 1) ??
public List ControlPoints { get; set; } = new List();
///
- /// Number of fit data
+ /// Number of fit data.
///
[DxfCodeValue(97)]
public List FitPoints { get; set; } = new List();
///
- /// Start tangent
+ /// Start tangent.
///
[DxfCodeValue(12, 22)]
public XY StartTangent { get; set; }
///
- /// End tangent
+ /// End tangent.
///
[DxfCodeValue(13, 23)]
public XY EndTangent { get; set; }
+
+ ///
+ public override BoundingBox GetBoundingBox()
+ {
+ return BoundingBox.FromPoints(this.ControlPoints);
+ }
}
}
}
diff --git a/src/ACadSharp/Entities/Hatch.BoundaryPath.cs b/src/ACadSharp/Entities/Hatch.BoundaryPath.cs
index 084381d9..71ea397e 100644
--- a/src/ACadSharp/Entities/Hatch.BoundaryPath.cs
+++ b/src/ACadSharp/Entities/Hatch.BoundaryPath.cs
@@ -1,4 +1,5 @@
using ACadSharp.Attributes;
+using CSMath;
using CSUtilities.Extensions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -9,8 +10,11 @@ namespace ACadSharp.Entities
{
public partial class Hatch
{
- public partial class BoundaryPath
+ public partial class BoundaryPath : IGeometricEntity
{
+ ///
+ /// Flag that indicates that this boundary path is formed by a polyline.
+ ///
public bool IsPolyline { get { return this.Edges.OfType().Any(); } }
///
@@ -39,30 +43,60 @@ public BoundaryPathFlags Flags
}
///
- /// Number of edges in this boundary path
+ /// Number of edges in this boundary path.
///
///
- /// only if boundary is not a polyline
+ /// Only if boundary is not a polyline.
///
[DxfCodeValue(DxfReferenceType.Count, 93)]
- public ObservableCollection Edges { get; } = new();
+ public ObservableCollection Edges { get; private set; } = new();
///
- /// Source boundary objects
+ /// Source boundary objects.
///
[DxfCodeValue(DxfReferenceType.Count, 97)]
public List Entities { get; set; } = new List();
private BoundaryPathFlags _flags;
+ ///
+ /// Default constructor.
+ ///
public BoundaryPath()
{
- Edges.CollectionChanged += this.onEdgesCollectionChanged;
+ this.Edges.CollectionChanged += this.onEdgesCollectionChanged;
}
+ ///
+ public BoundingBox GetBoundingBox()
+ {
+ BoundingBox box = BoundingBox.Null;
+
+ foreach (Edge edge in this.Edges)
+ {
+ box = box.Merge(edge.GetBoundingBox());
+ }
+
+ foreach (Entity entity in this.Entities)
+ {
+ box = box.Merge(entity.GetBoundingBox());
+ }
+
+ return box;
+ }
+
+ ///
public BoundaryPath Clone()
{
- throw new System.NotImplementedException();
+ BoundaryPath path = (BoundaryPath)this.MemberwiseClone();
+
+ path.Entities = new List();
+ path.Entities.AddRange(this.Entities.Select(e => (Entity)e.Clone()));
+
+ path.Edges = new ObservableCollection(
+ this.Edges.Select(e => e.Clone()));
+
+ return path;
}
private void onEdgesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
@@ -70,7 +104,7 @@ private void onEdgesCollectionChanged(object sender, NotifyCollectionChangedEven
switch (e.Action)
{
case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
- onAdd(e);
+ this.onAdd(e);
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
break;
diff --git a/src/ACadSharp/Entities/Hatch.cs b/src/ACadSharp/Entities/Hatch.cs
index 0772261a..a90c5180 100644
--- a/src/ACadSharp/Entities/Hatch.cs
+++ b/src/ACadSharp/Entities/Hatch.cs
@@ -127,15 +127,20 @@ public partial class Hatch : Entity
[DxfCodeValue(DxfReferenceType.Count, 91)]
public List Paths { get; set; } = new List();
- private HatchPattern _pattern = HatchPattern.Solid;
-
///
public Hatch() : base() { }
///
public override BoundingBox GetBoundingBox()
{
- return BoundingBox.FromPoints(this.SeedPoints.Select(x=>(XYZ)x));
+ BoundingBox box = BoundingBox.Null;
+
+ foreach (BoundaryPath bp in this.Paths)
+ {
+ box = box.Merge(bp.GetBoundingBox());
+ }
+
+ return box;
}
///
diff --git a/src/ACadSharp/Entities/IEntity.cs b/src/ACadSharp/Entities/IEntity.cs
index 70b9a812..13469091 100644
--- a/src/ACadSharp/Entities/IEntity.cs
+++ b/src/ACadSharp/Entities/IEntity.cs
@@ -3,7 +3,7 @@
namespace ACadSharp.Entities
{
- public interface IEntity : IHandledCadObject
+ public interface IEntity : IHandledCadObject, IGeometricEntity
{
///
/// Specifies the layer for an object.
diff --git a/src/ACadSharp/Entities/IGeometricEntity.cs b/src/ACadSharp/Entities/IGeometricEntity.cs
new file mode 100644
index 00000000..82f63970
--- /dev/null
+++ b/src/ACadSharp/Entities/IGeometricEntity.cs
@@ -0,0 +1,16 @@
+using CSMath;
+
+namespace ACadSharp.Entities
+{
+ ///
+ /// Objects with geometric qualities in the drawing.
+ ///
+ public interface IGeometricEntity
+ {
+ ///
+ /// Gets the bounding box aligned with the axis XYZ that occupies this entity.
+ ///
+ /// The bounding box where this entity resides.
+ BoundingBox GetBoundingBox();
+ }
+}
diff --git a/src/ACadSharp/Entities/Viewport.cs b/src/ACadSharp/Entities/Viewport.cs
index 6536e4d8..fbd9c1c5 100644
--- a/src/ACadSharp/Entities/Viewport.cs
+++ b/src/ACadSharp/Entities/Viewport.cs
@@ -32,25 +32,25 @@ public class Viewport : Entity
public override string SubclassMarker => DxfSubclassMarker.Viewport;
///
- /// Center point(in WCS)
+ /// Center point(in WCS).
///
[DxfCodeValue(10, 20, 30)]
public XYZ Center { get; set; }
///
- /// Width in paper space units
+ /// Width in paper space units.
///
[DxfCodeValue(40)]
public double Width { get; set; }
///
- /// Height in paper space units
+ /// Height in paper space units.
///
[DxfCodeValue(41)]
public double Height { get; set; }
///
- /// Viewport ID
+ /// Viewport ID.
///
[DxfCodeValue(69)]
public short Id
@@ -75,7 +75,7 @@ public short Id
}
///
- /// View center point(in DCS)
+ /// View center point(in DCS).
///
[DxfCodeValue(12, 22)]
public XY ViewCenter { get; set; }
@@ -334,9 +334,16 @@ public override CadObject Clone()
///
public override BoundingBox GetBoundingBox()
{
- XYZ min = new XYZ(this.Center.X - this.Width / 2, this.Center.Y - this.Height / 2, this.Center.Z);
- XYZ max = new XYZ(this.Center.X + this.Width / 2, this.Center.Y + this.Height / 2, this.Center.Z);
+ XYZ min = new XYZ(this.Center.X - this.Width, this.Center.Y - this.Height, this.Center.Z);
+ XYZ max = new XYZ(this.Center.X + this.Width, this.Center.Y + this.Height, this.Center.Z);
+ return new BoundingBox(min, max);
+ }
+ ///
+ public BoundingBox GetModelBoundingBox()
+ {
+ XYZ min = new XYZ(this.ViewCenter.X - this.ViewWidth / 2, this.ViewCenter.Y - this.ViewHeight / 2, 0);
+ XYZ max = new XYZ(this.ViewCenter.X + this.ViewWidth / 2, this.ViewCenter.Y + this.ViewHeight / 2, 0);
return new BoundingBox(min, max);
}
}
diff --git a/src/ACadSharp/MathUtils.cs b/src/ACadSharp/MathUtils.cs
index e593616a..134d9de3 100644
--- a/src/ACadSharp/MathUtils.cs
+++ b/src/ACadSharp/MathUtils.cs
@@ -17,6 +17,8 @@ public static class MathUtils
public const double Epsilon = 1e-12;
+ public const double TwoPI = Math.PI * 2;
+
///
/// Checks if a number is close to zero.
///
@@ -38,6 +40,16 @@ public static bool IsZero(double number, double threshold)
return number >= -threshold && number <= threshold;
}
+ public static double FixZero(double number)
+ {
+ return FixZero(number, Epsilon);
+ }
+
+ public static double FixZero(double number, double threshold)
+ {
+ return IsZero(number, threshold) ? 0 : number;
+ }
+
public static double RadToDeg(double value)
{
return value * RadToDegFactor;