Drawings SDK Developer Guide > Working with .dwg Files > Working with Entities > Working with Specific Entitites > Working with Ellipses > Example of Working with the Elliptical Arc
Example of Working with the Elliptical Arc

This example demonstrates displaying and modifying the properties of an ellipse object as an unclosed figure, named below as the elliptical arc. This example uses a console menu that represents the following operations: getting and setting the center [C], major axis [A], radius ratio [R], start angle [S], end angle [E], start parameter [B], and end parameter [F]; setting the whole elliptical arc geometry [W]; computing the features at a parameter [Z]; displaying the object properties, general properties, computed properties, specific properties [P], and modifying general entity properties [M].

The PrintEllipticalArcProperties() function requires a pointer to an existing ellipse object and displays its specific properties for the elliptical arc. The function gets the specific properties using the center(), normal(), radiusRatio(), majorAxis(), minorAxis(), startAngle(), and endAngle() methods. The function uses the AboutPoint3d() function for converting the coordinates of the center to a string value and the AboutVector3d() function for converting the coordinates of the normal, major axis, and minor axis to a string value. The AboutPoint3d() and AboutVector3d() functions require an instance of the three-dimensional point or three-dimensional vector to be converted as an argument; the functions return a string containing the X,Y,Z coordinates.

The PrintEllipticalArcProperties() function has the following implementation:


void PrintEllipticalArcProperties(OdDbEllipse* pEllipse)
{
  wcout << L"\n  Normal = " << AboutVector3d(pEllipse->normal())
        << L"\n  Center = " << AboutPoint3d(pEllipse->center())
        << L"\n  Major Axis = " << AboutVector3d(pEllipse->majorAxis())
        << L"\n  Minor Axis = " << AboutVector3d(pEllipse->minorAxis())
        << L"\n  Radius Ratio = " << pEllipse->radiusRatio()
        << L"\n  Start angle = " << pEllipse->startAngle()
        << L"\n  End angle = " << pEllipse->endAngle();
}

The PrintEllipticalArcFeatures() function requires a pointer to an existing ellipse object and displays the properties computed at a parameter (features). The function uses the getStartPoint(), getEndPoint(), getStartParam(), getEndParam(),getArea(), getDistAtParam(), getParamAtDist(), getPointAtParam(), getFirstDeriv(), getSecondDeriv(), and getPlane() methods, and also uses the AboutPoint3d() and AboutVector3d() functions. The parameter is the angle measured from the major axis and is changed from 0 to 2PI. The arc length is calculated as the distance from the start point to the end point computed at a parameter. The middle point is calculated at half-length. The first and second derivatives are vectors which are also computed at a parameter in the start, end, and middle point. The elliptical arc is a planar entity, and the function gets and displays the coefficients of the plane using the AboutPlane() function.

The PrintEllipticalArcFeatures() function has the following implementation:


void PrintEllipticalArcFeatures(OdDbEllipse* pEllipse)
{
  OdGePlane plane;
  OdGePoint3d point;
  OdGeVector3d vector;
  OdDb::Planarity planarity;
  double value, start, end;

  pEllipse->getStartParam(start);
  wcout << L"\n  Start parameter = " << start;
  pEllipse->getEndParam(end);
  wcout << L"\n  End parameter = " << end;

  pEllipse->getArea(value);
  wcout << L"\n  Area = " << value;
  pEllipse->getDistAtParam(end, value);
  wcout << L"\n  Arc Length = " << value;
  pEllipse->getParamAtDist(value/2, value);
  wcout << L"\n  Parameter at half-length = " << value;

  pEllipse->getStartPoint(point);
  wcout << L"\n  Start point = " << AboutPoint3d(point);
  pEllipse->getFirstDeriv(start, vector);
  wcout << L"\n  First derivative in start point = " << AboutVector3d(vector);
  pEllipse->getSecondDeriv(start, vector);
  wcout << L"\n  Second derivative in start point = " << AboutVector3d(vector);

  pEllipse->getEndPoint(point);
  wcout << L"\n  End point = " << AboutPoint3d(point);
  pEllipse->getFirstDeriv(end, vector);
  wcout << L"\n  First derivative in end point = " << AboutVector3d(vector);
  pEllipse->getSecondDeriv(end, vector);
  wcout << L"\n  Second derivative in end point = " << AboutVector3d(vector);

  pEllipse->getPointAtParam((end + start)/2, point);
  wcout << L"\n  Middle point = " << AboutPoint3d(point);
  pEllipse->getFirstDeriv((end + start)/2, vector);
  wcout << L"\n  First derivative in middle point = " << AboutVector3d(vector);
  pEllipse->getSecondDeriv((end + start)/2, vector);
  wcout << L"\n  Second derivative in middle point = " << AboutVector3d(vector);

  if(pEllipse->getPlane(plane, planarity) == eOk)
    wcout << L"\n  " << ((planarity == OdDb::kPlanar) ? L"Entity" : 
                         (planarity == OdDb::kLinear) ? L"Arbitrary" : L"Non")
          << L" Plane = " << AboutPlane(plane);
}

The ModifyEllipticalArcProperties() function requires a pointer to an existing ellipse object and implements the console menu for the listed operations. The function organizes a loop that inquires about the operation code and uses the switch statement to select whether the case must be performed. The function processes user actions in the loop until the user selects the [Q] operation. The function uses the EntryPoint3d() function for entering coordinates for a three-dimensional point and the EntryVector3d() function for entering coordinates of a three-dimensional vector. The EntryPoint3d() and EntryVector3d() functions require a reference to an instance of the three-dimensional point or three-dimensional vector to be modified as an argument; the functions return True when the passed instance is modified successfully or False when the user cancels entry.

When the user selects [P], the function displays the common object properties using the PrintObjectProperties() function, general entity properties using the PrintEntityProperties() function, computed elliptical arc properties using the PrintEllipticalArcFeatures() function, and specific elliptical arc properties using the PrintEllipticalArcProperties() function. When the user selects the [p] operation, the function displays only specific elliptical arc properties.

When the user selects [W], the function inquires about the center, major axis, normal, radius ratio, start angle, and end angle to specify the elliptical arc geometry. The function gets the center using the center() method and calls the EntryPoint3d() function for entry of its coordinates, gets the major axis using the majorAxis() method and calls the EntryVector3d() function for entry of its coordinates, gets the normal using the normal() method and calls the EntryVector3d() function for entry of its coordinates, gets the current radius ratio using the radiusRatio() method and requests a new ratio as a double value, gets the current start angle using the startAngle() method and requests a new start angle as a double value, gets the current end angle using the endAngle() method and requests a new end angle as a double value. The function checks whether the entered major axis vector and entered normal are perpendicular. If the radius ratio is out of the range 1e–6 to 1.0, the function takes it as 1.0. If entered values are correct, the function sets the elliptical arc geometry using the set() method of the ellipse object and passes to it the center point as the first argument, normal as the second argument, major axis vector as the third argument, radius ratio as the fourth argument, start angle as the fifth argument, and end angle as the sixth argument. When errors occur, the function catches them using the try....catch statement.

When the user selects [R], the function gets the current radius ratio using the radiusRatio() method and requests a double value in the range 1e–6 to 1.0. If an entered value is incorrect or out of range, the function displays an error message and breaks to the console menu. If an entered value is correct, the function sets the new radius ratio using the setRadiusRatio() method.

When the user selects [S], the function gets the current start angle using the startAngle() method and requests a double value in the range 0 to 2PI. If an entered value is incorrect, the function displays an error message and breaks to the console menu. If an entered value is correct, the function sets the new start angle using the setStartAngle() method.

When the user selects [E], the function gets the current end angle using the endAngle() method and requests a double value in the range 0 to 2PI. If an entered value is incorrect, the function displays an error message and breaks to the console menu. If an entered value is correct, the function sets the new end angle using the setEndAngle() method.

When the user selects [S], the function gets the current start parameter using the getStartParam() method and requests a double value in the range 0 to 2PI. If an entered value is incorrect, the function displays an error message and breaks to the console menu. If an entered value is correct, the function sets the new start parameter using the setStartParam() method.

When the user selects [E], the function gets the current end parameter using the getEndParam() method and requests a double value in the range 0 to 2PI. If an entered value is incorrect, the function displays an error message and breaks to the console menu. If an entered value is correct, the function sets the new end parameter using the setEndParam() method.

When the user selects [Z], the function requests a parameter as a double value in the range 0 to 2PI. If an entered value is correct, the function computes the coordinates of the point on the elliptical arc corresponding to the specified parameter using the getPointAtParam() method, distance from the start point to the computed point using the getDistAtParam() method, and first and second derivatives in the computed point using the getFirstDeriv() and getSecondDeriv() methods.

When the user selects [M], the function calls the ModifyEntityProperties() function and passes to it the pointer to the ellipse object for modifying its general entity properties. After modifying, the function displays all elliptical arc properties using the [P] operation.

When the user selects [Q], the function ends the loop and returns in the calling function.

The ModifyEllipticalArcProperties() function has the following implementation:


#include "..\Common\DemoMain.h"
#include "DbEllipse.h"
#include <iostream>
using namespace std;

OdString AboutPoint3d(const OdGePoint3d& point);
bool EntryPoint3d(OdGePoint3d& point);

OdString AboutVector3d(const OdGeVector3d& vector);
bool EntryVector3d(OdGeVector3d& vector);

void PrintEntityProperties(OdDbEntity *pEntity);
void ModifyEntityProperties(OdDbEntity *pEntity);

void ModifyEllipticalArcProperties(OdDbEllipse* pEllipse)
{
  wchar_t ch = L'\0';
  double value, param, ratio, start, end;
  OdGePoint3d point;
  OdGeVector3d axis;
  OdGeVector3d vector;

  wcout << L"\n\nStart modifying of the elliptical arc properties";

  do {
    switch(ch)
    {
      case L'M':          // Modify the general properties
      case L'm':
        ModifyEntityProperties(pEllipse);


      case L'P':          // Print the whole properties
        wcout << L"\nH=" << pEllipse->handle().ascii();
        wcout << L"\n  ------ Common Object Properties";
        PrintObjectProperties(pEllipse);
        wcout << L"\n  ------ General Entity Properties";
        PrintEntityProperties(pEllipse);
        wcout << L"\n  ------ Computed Elliptical Arc Properties";
        PrintEllipticalArcFeatures(pEllipse);


      case L'p':          // Print the specific properties
        wcout << L"\n  ------ Specific Elliptical Arc Properties";
        PrintEllipticalArcProperties(pEllipse);
        wcout << L"\n";        
        break;


      case L'W':          // Set the whole elliptical arc geometry
      case L'w':
        wcout << L"\nEntry the center";
        point = pEllipse->center();

        if(EntryPoint3d(point))
        {
          wcout << L"\nEntry the major axis";
          axis = pEllipse->majorAxis();

          if(EntryVector3d(axis))
          {
            wcout << L"\nEntry the normal";
            vector = pEllipse->normal();

            if(EntryVector3d(vector))
            {
              if(vector.isZeroLength())
              {
                wcout << L"Error: Vector has zero length\n";
                break;
              }
              if(!vector.isPerpendicularTo(axis))
              {
                wcout << L"Error: Vector is not perpendicular to the major axis\n";
                break;
              }

              wcout << L"\nEntry the radius ratio [1e-6 to 1]:>";
              wcin >> ratio;

              if(!wcin.fail() && wcin.peek() == 10)
              {
                if(ratio < 0.000001 || ratio > 1.0) ratio = 1.0;

                wcout << L"\nEntry the start angle [0 to 2PI]:>";
                wcin >> start;

                if(!wcin.fail() && wcin.peek() == 10)
                {
                  wcout << L"\nEntry the end angle [0 to 2PI]:>";
                  wcin >> end;

                  if(!wcin.fail() && wcin.peek() == 10)
                  {

                    try {
                      pEllipse->set(point, vector, axis, ratio, start, end);
                      ch = L'p';
                      continue;
                    }
                    catch(OdError& e)
                    {
                      wcout << L"\nError: " << e.code() << L" - " << e.description() << L"\n";
                      break;
                    }
                  }
                }
              }
              wcin.clear();  wcin.sync();  wcout << L"Error: Invalid entered value\n";
            }
          }
        }
        break;


      case L'S':          // Set the start angle
      case L's':
        wcout << L"\nCurrent start angle = " << pEllipse->startAngle()
              << L"\nEntry a new start angle [0 to 2PI]:>";
        wcin >> value;

        if(!wcin.fail() && wcin.peek() == 10)
        {
          pEllipse->setStartAngle(value);
          wcout << L"Start angle is set to: " << pEllipse->startAngle() << L"\n";
        }
        else { wcin.clear();  wcin.sync();  wcout << L"Error: Invalid entered value\n"; }
        break;


      case L'E':          // Set the end angle
      case L'e':
        wcout << L"\nCurrent end angle = " << pEllipse->endAngle()
              << L"\nEntry a new end angle [0 to 2PI]:>";
        wcin >> value;

        if(!wcin.fail() && wcin.peek() == 10)
        {
          pEllipse->setEndAngle(value);
          wcout << L"End angle is set to: " << pEllipse->endAngle() << L"\n";
        }
        else { wcin.clear();  wcin.sync();  wcout << L"Error: Invalid entered value\n"; }
        break;


      case L'R':          // Set the radius ratio
      case L'r':
        wcout << L"\nCurrent radius ratio = " << pEllipse->radiusRatio()
              << L"\nEntry a new radius ratio [1e-6 to 1]:>";
        wcin >> ratio;

        if(!wcin.fail() && wcin.peek() == 10)
        {
          if(ratio > 0.000001 && ratio < 1.0)
          {
            pEllipse->setRadiusRatio(ratio);
            ch = L'p';
            continue;
          }
          else wcout << L"Error: Radius ratio must be a double value in range [1e-6 to 1]\n";
        }
        else { wcin.clear();  wcin.sync();  wcout << L"Error: Invalid entered value\n"; }
        break;


      case L'B':          // Set the start parameter
      case L'b':
        pEllipse->getStartParam(value);
        wcout << L"\nCurrent start parameter = " << value
              << L"\nEntry a new start parameter [0 to 2PI]:>";
        wcin >> value;

        if(!wcin.fail() && wcin.peek() == 10)
        {
          pEllipse->setStartParam(value);
          pEllipse->getStartParam(start);
          wcout << L"Start parameter is set to: " << start 
                << L" (Start angle = " << pEllipse->startAngle() << L")\n";
        }
        else { wcin.clear();  wcin.sync();  wcout << L"Error: Invalid entered value\n"; }
	      break;


      case L'F':          // Set the end parameter
      case L'f':
        pEllipse->getEndParam(value);
        wcout << L"\nCurrent end parameter = " << value
              << L"\nEntry a new end parameter [0 to 2PI]:>";
        wcin >> value;

        if(!wcin.fail() && wcin.peek() == 10)
        {
          pEllipse->setEndParam(value);
          pEllipse->getEndParam(end);
          wcout << L"End parameter is set to: " << end
                << L" (End angle = " << pEllipse->endAngle() << L")\n";
        }
        else { wcin.clear();  wcin.sync();  wcout << L"Error: Invalid entered value\n"; }
        break;


      case L'Z':          // Compute the features at parameter
      case L'z':
        wcout << L"\nEntry a parameter [0 to 2PI]:>";
        wcin >> param;

        if(!wcin.fail() && wcin.peek() == 10)
        {
          wcout << L"Compute at (" << param << L"):";
          if(pEllipse->getDistAtParam(param, value) == eOk)
            wcout << L"\nDistance = " << value;
          if(pEllipse->getPointAtParam(param, point) == eOk)
            wcout << L"\nPoint on = " << AboutPoint3d(point);
          if(pEllipse->getFirstDeriv(param, vector) == eOk)
            wcout << L"\n1-Derivative = " << AboutVector3d(vector);
          if(pEllipse->getSecondDeriv(param, vector) == eOk)
            wcout << L"\n2-Derivative = " << AboutVector3d(vector);
          wcout << L"\n--at--";
        }
        else { wcin.clear();  wcin.sync();  wcout << L"Error: Invalid entered value\n"; }
        break;


      case L'\0':         // Skip an action
        break;

      default:
        wcout << L"Error: Incorrect operation\n";
    }
    wcout << L"\nE. Set the end angle";
    wcout << L"\nS. Set the start angle";
    wcout << L"\nR. Set the radius ratio";
    wcout << L"\nF. Set the end parameter";
    wcout << L"\nB. Set the start parameter";
    wcout << L"\nW. Set the whole arc geometry";
    wcout << L"\nP. Print the whole properties";
    wcout << L"\np. Print the specific properties";
    wcout << L"\nM. Modify the general properties";
    wcout << L"\nZ. Compute the features at parameter";
    wcout << L"\nQ. Quit";
    wcout << L"\nSelect operation:>";
    wcin >> ch;
  }
  while(ch != L'Q' && ch != L'q');

  wcout << L"Stop modifying of the elliptical arc properties\n";
}

Testing gives the following results:


Start modifying of the elliptical arc properties

E. Set the end angle
S. Set the start angle
R. Set the radius ratio
F. Set the end parameter
B. Set the start parameter
W. Set the whole arc geometry
P. Print the whole properties
p. Print the specific properties
M. Modify the general properties
Z. Compute the features at parameter
Q. Quit
Select operation:>

When the operation is p-"Print the specific properties":


------ Specific Elliptical Arc Properties
Normal = (0,0,1)
Center = (0,0,0)
Major Axis = (1,0,0)
Minor Axis = (0,1,0)
Radius Ratio = 1
Start angle = 0
End angle = 6.28319

When the operation is W-"Set the whole arc geometry":


Entry the center
Current coordinates: (0,0,0)
Entry X-coordinate:>2.5
Entry Y-coordinate:>1.5
Entry Z-coordinate:>0

Entry the major axis
Current vector directions: (1,0,0)
Entry X-direction:>8.6
Entry Y-direction:>2.4
Entry Z-direction:>0

Entry the normal
Current vector directions: (0,0,1)
Entry X-direction:>0
Entry Y-direction:>0
Entry Z-direction:>0.5

Entry the radius ratio [1e-6 to 1]:>0.75

Entry the start angle [0 to 2PI]:>0.186

Entry the end angle [0 to 2PI]:>4.123

------ Specific Elliptical Arc Properties
Normal = (0,0,1)
Center = (2.5,1.5,0)
Major Axis = (8.6,2.4,0)
Minor Axis = (-1.8,6.45,0)
Radius Ratio = 0.75
Start angle = 0.186
End angle = 4.123

When the operation is S-"Set the start angle":


Current start angle = 0.186
Entry a new start angle [0 to 2PI]:>0.205
Start angle is set to: 0.205

When the operation is E-"Set the end angle":


Current end angle = 4.123
Entry a new end angle [0 to 2PI]:>-1.96
End angle is set to: 4.32319

When the operation is R-"Set the radius ratio":


Current radius ratio = 0.75
Entry a new radius ratio [1e-6 to 1]:>-2.5
Error: Radius ratio must be a double value in range [1e-6 to 1]

Current radius ratio = 0.75
Entry a new radius ratio [1e-6 to 1]:>0.82

------ Specific Elliptical Arc Properties
Normal = (0,0,1)
Center = (2.5,1.5,0)
Major Axis = (8.6,2.4,0)
Minor Axis = (-1.968,7.052,0)
Radius Ratio = 0.82
Start angle = 0.223528
End angle = 4.35352

When the operation is B-"Set the start parameter":


Current start parameter = 0.270436
Entry a new start parameter [0 to 2PI]:>0.223528
Start parameter is set to: 0.223528 (Start angle = 0.184293)

When the operation is F-"Set the end parameter":


Current end parameter = 4.41398
Entry a new end parameter [0 to 2PI]:>4.35352
End parameter is set to: 4.35352 (End angle = 4.28335)

When the operation is Z-"Compute the features at parameter":


Entry a parameter [0 to 2PI]:>1.96
Compute at (1.96):
Distance = 14.578
Point on = (-2.5841,7.11391,0)
1-Derivative = (-7.21006,-4.8964,0)
2-Derivative = (5.0841,-5.61391,0)
--at--

When the operation is P-"Print all properties":


H=40
  ------ Common Object Properties
  Type: AcDbEllipse
  Status: unerased,resident,modified,forRead,forWrite
  Database: c:\test.dwg
  ------ General Entity Properties
  Block: [1F-"*Model_Space"-Block]
  Layer: [10-"0"-Layer]
  Material: [3C-"ByLayer"-Material]
  Linetype: [15-"ByLayer"-Linetype]
  Lineweight: [kLnWtByLayer]
  Transparency: [byLayer]
  Visual style: [Db:kNull]
  PlotStyleName: ByLayer
  Linetype scale: 1
  Color: [byLayer], Index = 256
  State: Planar, Visible, Cast Shadows, Receive Shadows
  ------ Computed Elliptical Arc Properties
  Start parameter = 0.223528
  End parameter = 4.35352
  Area = 162.287
  Arc Length = 33.5072
  Parameter at half-length = 2.21179
  Start point = (10.4498,5.40352,0)
  First derivative in start point = (-3.82541,6.34455,0)
  Second derivative in start point = (-7.9498,-3.90352,0)
  End point = (1.32217,-5.94567,0)
  First derivative in end point = (8.74333,-0.229664,0)
  Second derivative in end point = (1.17783,7.44567,0)
  Middle point = (-4.63849,5.23388,0)
  First derivative in middle point = (-5.18411,-6.44584,0)
  Second derivative in middle point = (7.13849,-3.73388,0)
  Entity Plane = (0 * X + 0 * Y + 1 * Z + 0)
  ------ Specific Elliptical Arc Properties
  Normal = (0,0,1)
  Center = (2.5,1.5,0)
  Major Axis = (8.6,2.4,0)
  Minor Axis = (-1.968,7.052,0)
  Radius Ratio = 0.82
  Start angle = 0.184293
  End angle = 4.28335

Use the Q-"Quit" operation to exit:


Stop modifying of the elliptical arc properties

See Also

Working with Ellipses

Example of Working with the Ellipse Object

Example of Working with the Circular Arc

Example of Entering and Displaying 3D Point Objects

Example of Entering and Displaying 3D Vector Objects

Copyright © 2002 – 2021. Open Design Alliance. All rights reserved.