2

I am developing a DXF parser by using the dxflib library. I have a problem parsing ellipses.

When I parse an ellipse I receive the following data:

struct DL_EllipseData 
{
    /*! X Coordinate of center point. */
    double cx;
    /*! Y Coordinate of center point. */
    double cy;

    /*! X coordinate of the endpoint of the major axis. */
    double mx;
    /*! Y coordinate of the endpoint of the major axis. */
    double my;

    /*! Ratio of minor axis to major axis. */
    double ratio;
    /*! Startangle of ellipse in rad. */
    double angle1;
    /*! Endangle of ellipse in rad. */
    double angle2;
};

The problem is that when angle1 != 0 AND angle2 != 2* Math.PI the ellipse is open and I am not able to compute the arc path that represents that geometry.

For example considering the following ellipse:

enter image description here

These are its properties:

enter image description here

As you can see the angles are:

angle1 = 0.81855 // 46 degrees
angle2 = 2.38934 // 136 degrees

but the picture of the ellipse (I took from autocad seems to have quite different angles).

Following the section of the DXF file that represents the ellipse:

0
ELLIPSE
  5
A7
330
1F
100
AcDbEntity
  8
DL-Wall
 48
25.0
370
    -3
100
AcDbEllipse
 10
906.6576677029225
 20
906.657675539829
 30
0.0
 11
-641.4561777354752
 21
641.4561777354752
 31
0.0
210
0.0
220
0.0
230
1.0
 40
0.9999999999999978
 41
0.8185500151218715
 42
2.389346341916759

How I have to compute the proper angles (and also start end end point of the arc segment)?

Nick
  • 10,309
  • 21
  • 97
  • 201

1 Answers1

1
    /// <summary>
    ///     Static method to detemine the WPF end point of the arc.
    /// </summary>
    /// <param name="arc">The DXF ArcEntity object to evaluate</param>
    /// <returns>Point with values of the arc end point.</returns>
    public static Point calcEndPoint(Arc arc)
    {
        double x = (Math.Cos(arc.endAngle * (Math.PI / 180)) * arc.radius) + arc.center.X;
        double y = arc.center.Y - (Math.Sin(arc.endAngle * (Math.PI / 180)) * arc.radius);
        return new Point(x, y);
    }

    /// <summary>
    ///     Static method to detemine the WPF start point of the arc.
    /// </summary>
    /// <param name="arc">The DXF ArcEntity object to evaluate</param>
    /// <returns>Point with values of the arc start point.</returns>
    public static Point calcStartPoint(Arc arc)
    {
        double x = (Math.Cos(arc.startAngle * (Math.PI / 180)) * arc.radius) + arc.center.X;
        double y = arc.center.Y - (Math.Sin(arc.startAngle * (Math.PI / 180)) * arc.radius);
        return new Point(x, y);
    }

    public static bool checkArcSize(Arc arc)
    {
        double angleDiff = arc.endAngle - arc.startAngle;
        return !((angleDiff > 0 && angleDiff <= 180) || angleDiff <= -180);
    }

Using System.Windows.Media.Path, PathFigure, ArcSegment:

PathFigure figure = new PathFigure();
figure.StartPoint = calcStartPoint([your arc struct]);
ArcSegment arc = new ArcSegment();
arc.Point = calcEndPoints([your arc struct]);
arc.RotationAngle = Math.Abs(endAngle - startAngle);
arc.Size = new Size(radius, radius);
arc.IsLargeArc = checkArcSize([your arc struct]);
figure.Segments.Add(arc);

You will need to adjust each of the helper functions to use your struct as well as any C++ vs C# differences in syntax.

I believe that these helper functions will bridge the gap between what the DXF spec gives you and what is required to draw the Arc in WPF.

TErenberger
  • 33
  • 1
  • 5