context: #region netDxf library, Copyright (C) 2009-2017 Daniel Carvajal (haplokuon@gmail.com)
  
  //                        netDxf library
  // Copyright (C) 2009-2017 Daniel Carvajal (haplokuon@gmail.com)
  // 
  // This library is free software; you can redistribute it and/or
  // modify it under the terms of the GNU Lesser General Public
  // License as published by the Free Software Foundation; either
  // version 2.1 of the License, or (at your option) any later version.
  // 
  // The above copyright notice and this permission notice shall be included in all
  // copies or substantial portions of the Software.
  // 
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  #endregion
  
  using System;
  using System.Collections.Generic;
  using netDxf.Tables;
  
  namespace netDxf.Entities
  {
      /// <summary>
      /// Represents an ellipse <see cref="EntityObject">entity</see>.
      /// </summary>
      public class Ellipse :
          EntityObject
      {
          #region private fields
  
          private Vector3 center;
          private double majorAxis;
          private double minorAxis;
          private double rotation;
          private double startAngle;
          private double endAngle;
          private double thickness;
  
          #endregion
  
          #region constructors
  
          /// <summary>
          /// Initializes a new instance of the <c>Ellipse</c> class.
          /// </summary>
          public Ellipse()
              : this(Vector3.Zero, 1.0, 0.5)
          {
          }
  
          /// <summary>
          /// Initializes a new instance of the <c>Ellipse</c> class.
          /// </summary>
          /// <param name="center">Ellipse <see cref="Vector2">center</see> in object coordinates.</param>
          /// <param name="majorAxis">Ellipse major axis.</param>
          /// <param name="minorAxis">Ellipse minor axis.</param>
          /// <remarks>The center Z coordinate represents the elevation of the arc along the normal.</remarks>
          public Ellipse(Vector2 center, double majorAxis, double minorAxis)
              : this(new Vector3(center.X, center.Y, 0.0), majorAxis, minorAxis)
          {
          }
  
          /// <summary>
          /// Initializes a new instance of the <c>Ellipse</c> class.
          /// </summary>
          /// <param name="center">Ellipse <see cref="Vector3">center</see> in object coordinates.</param>
          /// <param name="majorAxis">Ellipse major axis.</param>
          /// <param name="minorAxis">Ellipse minor axis.</param>
          /// <remarks>The center Z coordinate represents the elevation of the arc along the normal.</remarks>
          public Ellipse(Vector3 center, double majorAxis, double minorAxis)
              : base(EntityType.Ellipse, DxfObjectCode.Ellipse)
          {
              this.center = center;
              if (majorAxis <= 0)
                  throw new ArgumentOutOfRangeException(nameof(majorAxis), majorAxis, "The major axis value must be greater than zero.");
              this.majorAxis = majorAxis;
              if (minorAxis <= 0)
                  throw new ArgumentOutOfRangeException(nameof(minorAxis), minorAxis, "The minor axis value must be greater than zero.");
              this.minorAxis = minorAxis;
              this.startAngle = 0.0;
              this.endAngle = 0.0;
              this.rotation = 0.0;
              this.thickness = 0.0;
          }
  
          #endregion
  
          #region public properties
  
          /// <summary>
          /// Gets or sets the ellipse <see cref="Vector3">center</see>.
          /// </summary>
          /// <remarks>The center Z coordinate represents the elevation of the arc along the normal.</remarks>
          public Vector3 Center
          {
              get { return this.center; }
              set { this.center = value; }
          }
  
          /// <summary>
          /// Gets or sets the ellipse mayor axis.
          /// </summary>
          public double MajorAxis
          {
              get { return this.majorAxis; }
              set
              {
                  if (value <= 0)
                      throw new ArgumentOutOfRangeException(nameof(value), value, "The major axis value must be greater than zero.");
                  this.majorAxis = value;
              }
          }
  
          /// <summary>
          /// Gets or sets the ellipse minor axis.
          /// </summary>
          public double MinorAxis
          {
              get { return this.minorAxis; }
              set
              {
                  if (value <= 0)
                      throw new ArgumentOutOfRangeException(nameof(value), value, "The minor axis value must be greater than zero.");
                  this.minorAxis = value;
              }
          }
  
          /// <summary>
          /// Gets or sets the ellipse local rotation in degrees along its normal.
          /// </summary>
          public double Rotation
          {
              get { return this.rotation; }
              set { this.rotation = MathHelper.NormalizeAngle(value); }
          }
  
          /// <summary>
          /// Gets or sets the ellipse start angle in degrees.
          /// </summary>
          /// <remarks>To get a full ellipse set the start angle equal to the end angle.</remarks>
          public double StartAngle
          {
              get { return this.startAngle; }
              set { this.startAngle = MathHelper.NormalizeAngle(value); }
          }
  
          /// <summary>
          /// Gets or sets the ellipse end angle in degrees.
          /// </summary>
          /// <remarks>To get a full ellipse set the end angle equal to the start angle.</remarks>
          public double EndAngle
          {
              get { return this.endAngle; }
              set { this.endAngle = MathHelper.NormalizeAngle(value); }
          }
  
          /// <summary>
          /// Gets or sets the ellipse thickness.
          /// </summary>
          public double Thickness
          {
              get { return this.thickness; }
              set { this.thickness = value; }
          }
  
          /// <summary>
          /// Checks if the actual instance is a full ellipse.
          /// </summary>
          /// <remarks>An ellipse is considered full when its start and end angles are equal.</remarks>
          public bool IsFullEllipse
          {
              get { return MathHelper.IsEqual(this.startAngle, this.endAngle); }
          }
  
          #endregion
  
          #region public methods
  
          /// <summary>
          /// Calculate the local point on the ellipse for a given angle relative to the center.
          /// </summary>
          /// <param name="angle">Angle in degrees.</param>
          /// <returns>A local point on the ellipse for the given angle relative to the center.</returns>
          public Vector2 PolarCoordinateRelativeToCenter(double angle)
          {
              double a = this.MajorAxis*0.5;
              double b = this.MinorAxis*0.5;
              double radians = angle*MathHelper.DegToRad;
  
              double a1 = a*Math.Sin(radians);
              double b1 = b*Math.Cos(radians);
  
              double radius = (a*b)/Math.Sqrt(b1*b1 + a1*a1);
  
              // convert the radius back to cartesian coordinates
              return new Vector2(radius*Math.Cos(radians), radius*Math.Sin(radians));
          }
  
          /// <summary>
          /// Converts the ellipse in a list of vertexes.
          /// </summary>
          /// <param name="precision">Number of divisions.</param>
          /// <returns>A list vertexes that represents the ellipse expressed in object coordinate system.</returns>
          public List<Vector2> PolygonalVertexes(int precision)
          {
  
gt:             List<Vector2> points = new List<Vector2>();