• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DomCR / ACadSharp / 14432853472

13 Apr 2025 08:02PM UTC coverage: 75.253% (-0.01%) from 75.265%
14432853472

Pull #614

github

web-flow
Merge b54b762a3 into 0a8954d60
Pull Request #614: Issue 612 dxf to dwg

5663 of 8245 branches covered (68.68%)

Branch coverage included in aggregate %.

20 of 23 new or added lines in 6 files covered. (86.96%)

14 existing lines in 3 files now uncovered.

22499 of 29178 relevant lines covered (77.11%)

83278.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.73
/src/ACadSharp/Entities/Ellipse.cs
1
using ACadSharp.Attributes;
2
using CSMath;
3
using System;
4
using System.Collections.Generic;
5
using System.Linq;
6

7
namespace ACadSharp.Entities
8
{
9
        /// <summary>
10
        /// Represents a <see cref="Ellipse"/> entity.
11
        /// </summary>
12
        /// <remarks>
13
        /// Object name <see cref="DxfFileToken.EntityEllipse"/> <br/>
14
        /// Dxf class name <see cref="DxfSubclassMarker.Ellipse"/>
15
        /// </remarks>
16
        [DxfName(DxfFileToken.EntityEllipse)]
17
        [DxfSubClass(DxfSubclassMarker.Ellipse)]
18
        public class Ellipse : Entity
19
        {
20
                /// <inheritdoc/>
21
                public override ObjectType ObjectType => ObjectType.ELLIPSE;
17✔
22

23
                /// <inheritdoc/>
24
                public override string ObjectName => DxfFileToken.EntityEllipse;
39✔
25

26
                /// <inheritdoc/>
27
                public override string SubclassMarker => DxfSubclassMarker.Ellipse;
3,878✔
28

29
                /// <summary>
30
                /// Specifies the distance a 2D object is extruded above or below its elevation.
31
                /// </summary>
32
                [DxfCodeValue(39)]
33
                public double Thickness { get; set; } = 0.0;
424✔
34

35
                /// <summary>
36
                /// Extrusion direction.
37
                /// </summary>
38
                [DxfCodeValue(210, 220, 230)]
39
                public XYZ Normal { get; set; } = XYZ.AxisZ;
1,942✔
40

41
                /// <summary>
42
                /// Center point (in WCS).
43
                /// </summary>
44
                [DxfCodeValue(10, 20, 30)]
45
                public XYZ Center { get; set; } = XYZ.Zero;
2,598✔
46

47
                /// <summary>
48
                /// Endpoint of major axis, relative to the center (in WCS).
49
                /// </summary>
50
                /// <remarks>
51
                /// Axis X is set as default.
52
                /// </remarks>
53
                [DxfCodeValue(11, 21, 31)]
54
                public XYZ EndPoint { get; set; } = XYZ.AxisX;
4,577✔
55

56
                /// <summary>
57
                /// Ratio of minor axis to major axis.
58
                /// </summary>
59
                [DxfCodeValue(40)]
60
                public double RadiusRatio { get; set; } = 0.0;
2,118✔
61

62
                /// <summary>
63
                /// Start parameter.
64
                /// </summary>
65
                /// <value>
66
                /// The valid range is 0 to 2 * PI.
67
                /// </value>
68
                [DxfCodeValue(41)]
69
                public double StartParameter { get; set; } = 0.0;
808✔
70

71
                /// <summary>
72
                /// End parameter.
73
                /// </summary>
74
                /// <value>
75
                /// The valid range is 0 to 2 * PI.
76
                /// </value>
77
                [DxfCodeValue(42)]
78
                public double EndParameter { get; set; } = MathHelper.TwoPI;
807✔
79

80
                /// <summary>
81
                /// Rotation of the major axis from the world X axis.
82
                /// </summary>
83
                public double Rotation
84
                {
85
                        get
86
                        {
5✔
87
                                return ((XY)this.EndPoint).GetAngle();
5✔
88
                        }
5✔
89
                }
90

91
                /// <summary>
92
                /// Length of the major axis.
93
                /// </summary>
94
                public double MajorAxis { get { return 2 * this.EndPoint.GetLength(); } }
7,890✔
95

96
                /// <summary>
97
                /// Length of the minor axis.
98
                /// </summary>
99
                public double MinorAxis { get { return this.MajorAxis * this.RadiusRatio; } }
3,945✔
100

101
                /// <summary>
102
                /// Flag that indicates weather this ellipse is closed or not.
103
                /// </summary>
104
                public bool IsFullEllipse { get { return this.StartParameter == 0 && this.EndParameter == MathHelper.TwoPI; } }
15✔
105

106
                /// <summary>
107
                /// Calculate the local point on the ellipse for a given angle relative to the center.
108
                /// </summary>
109
                /// <param name="angle">Angle in radians.</param>
110
                /// <returns>A local point on the ellipse for the given angle relative to the center.</returns>
111
                public XY PolarCoordinateRelativeToCenter(double angle)
112
                {
2✔
113
                        double a = this.MajorAxis * 0.5;
2✔
114
                        double b = this.MinorAxis * 0.5;
2✔
115

116
                        double a1 = a * Math.Sin((double)angle);
2✔
117
                        double b1 = b * Math.Cos((double)angle);
2✔
118

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

121
                        // convert the radius back to Cartesian coordinates
122
                        return new XY(radius * Math.Cos((double)angle), radius * Math.Sin((double)angle));
2✔
123
                }
2✔
124

125
                /// <summary>
126
                /// Converts the ellipse in a list of vertexes.
127
                /// </summary>
128
                /// <param name="precision">Number of vertexes generated.</param>
129
                /// <returns>A list vertexes that represents the ellipse expressed in object coordinate system.</returns>
130
                public List<XY> PolygonalVertexes(int precision)
131
                {
5✔
132
                        if (precision < 2)
5!
133
                        {
×
134
                                throw new ArgumentOutOfRangeException(nameof(precision), precision, "The arc precision must be equal or greater than two.");
×
135
                        }
136

137
                        List<XY> points = new List<XY>();
5✔
138
                        double beta = this.Rotation;
5✔
139
                        double sinBeta = Math.Sin(beta);
5✔
140
                        double cosBeta = Math.Cos(beta);
5✔
141
                        double start;
142
                        double end;
143
                        double steps;
144

145
                        if (this.IsFullEllipse)
5✔
146
                        {
4✔
147
                                start = 0;
4✔
148
                                end = MathHelper.TwoPI;
4✔
149
                                steps = precision;
4✔
150
                        }
4✔
151
                        else
152
                        {
1✔
153
                                XY startPoint = this.PolarCoordinateRelativeToCenter(this.StartParameter);
1✔
154
                                XY endPoint = this.PolarCoordinateRelativeToCenter(this.EndParameter);
1✔
155
                                double a = 1 / (0.5 * this.MajorAxis);
1✔
156
                                double b = 1 / (0.5 * this.MinorAxis);
1✔
157
                                start = Math.Atan2(startPoint.Y * b, startPoint.X * a);
1✔
158
                                end = Math.Atan2(endPoint.Y * b, endPoint.X * a);
1✔
159

160
                                if (end < start)
1!
UNCOV
161
                                {
×
UNCOV
162
                                        end += MathHelper.TwoPI;
×
UNCOV
163
                                }
×
164
                                steps = precision - 1;
1✔
165
                        }
1✔
166

167
                        double delta = (end - start) / steps;
5✔
168

169
                        for (int i = 0; i < precision; i++)
1,322✔
170
                        {
656✔
171
                                double angle = start + delta * i;
656✔
172
                                double sinAlpha = Math.Sin(angle);
656✔
173
                                double cosAlpha = Math.Cos(angle);
656✔
174

175
                                double pointX = 0.5 * (this.MajorAxis * cosAlpha * cosBeta - this.MinorAxis * sinAlpha * sinBeta);
656✔
176
                                double pointY = 0.5 * (this.MajorAxis * cosAlpha * sinBeta + this.MinorAxis * sinAlpha * cosBeta);
656✔
177

178
                                pointX = MathHelper.FixZero(pointX);
656✔
179
                                pointY = MathHelper.FixZero(pointY);
656✔
180

181
                                points.Add(new XY(pointX, pointY) + this.Center.Convert<XY>());
656✔
182
                        }
656✔
183

184
                        return points;
5✔
185
                }
5✔
186

187
                /// <inheritdoc/>
188
                public override void ApplyTransform(Transform transform)
189
                {
×
190
                        XYZ perp = XYZ.Cross(this.Normal, this.EndPoint);
×
191
                        perp.Normalize();
×
192
                        perp *= this.EndPoint.GetLength() * this.RadiusRatio;
×
193

194
                        this.Center = transform.ApplyTransform(this.Center);
×
195
                        this.EndPoint = transform.ApplyTransform(this.EndPoint);
×
196
                        XYZ newPrep = transform.ApplyTransform(perp);
×
197
                        if (newPrep != XYZ.Zero && this.EndPoint != XYZ.Zero)
×
198
                        {
×
199
                                this.RadiusRatio = newPrep.GetLength() / this.EndPoint.GetLength();
×
200
                                this.Normal = XYZ.Cross(this.EndPoint, newPrep);
×
201
                        }
×
202
                        else
203
                        {
×
204
                                this.Normal = transform.ApplyTransform(this.Normal);
×
205
                        }
×
206
                }
×
207

208
                /// <inheritdoc/>
209
                public override BoundingBox GetBoundingBox()
210
                {
4✔
211
                        List<XY> pts = this.PolygonalVertexes(100);
4✔
212
                        return BoundingBox.FromPoints(pts.Select(p => (XYZ)p));
404✔
213
                }
4✔
214
        }
215
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc