Close

Relief for ODA Team in Ukraine

Learn more
ODA Drawings SDK
Example of Working with the Ellipse Object

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

The PrintEllipseProperties() function requires a pointer to an existing ellipse object and displays its specific properties. The function gets the specific properties using the center(), normal(), radiusRatio(), majorAxis(), and minorAxis() 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 and return a string containing the X,Y,Z coordinates.

The PrintEllipseProperties() function has the following implementation:


void PrintEllipseProperties(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  Major Radius = " << pEllipse->majorAxis().length()
        << L"\n  Minor Radius = " << pEllipse->minorAxis().length()
        << L"\n  Radius Ratio = " << pEllipse->radiusRatio();
}

The PrintEllipseFeatures() 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 start point coincides with the end point for the ellipse. The parameter is the angle measured from major axis and is changed from 0 to 2PI. The circumference is calculated as the distance from the start point to the end point computed at a parameter. The ellipse has four quadrants which are computed through a parameter for angles: 0, PI/2, PI, 3PI/2. The first and second derivatives are vectors which are also computed through a parameter for angles: PI/4 and 3PI/4. The ellipse is a planar entity, and the function gets and displays the coefficients of the plane using the AboutPlane() function.

The PrintEllipseFeatures() function has the following implementation:


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

  pEllipse->getStartPoint(point);
  wcout << L"\n  Start point = " << AboutPoint3d(point);
  pEllipse->getEndPoint(point);
  wcout << L"\n  End point = " << AboutPoint3d(point);
  pEllipse->getStartParam(value);
  wcout << L"\n  Start parameter = " << value;
  pEllipse->getEndParam(value);
  wcout << L"\n  End parameter = " << value;

  pEllipse->getArea(value);
  wcout << L"\n  Area = " << value;
  pEllipse->getDistAtParam(Oda2PI, value);
  wcout << L"\n  Perimeter = " << value;
  pEllipse->getParamAtDist(value/2, value);
  wcout << L"\n  Parameter at half-perimeter = " << value;

  wcout << L"\n  Quadrants:";
  pEllipse->getPointAtParam(0, point);
  wcout << L"\n  Q(0) = " << AboutPoint3d(point);
  pEllipse->getPointAtParam((OdaPI * 0.5), point);
  wcout << L"\n  Q(PI/2) = " << AboutPoint3d(point);
  pEllipse->getPointAtParam(OdaPI, point);
  wcout << L"\n  Q(PI) = " << AboutPoint3d(point);
  pEllipse->getPointAtParam((OdaPI * 1.5), point);
  wcout << L"\n  Q(3PI/2) = " << AboutPoint3d(point);

  wcout << L"\n  Derivatives:";
  pEllipse->getFirstDeriv((OdaPI * 0.25), vector);
  wcout << L"\n  First(PI/4) = " << AboutVector3d(vector);
  pEllipse->getFirstDeriv((OdaPI * 0.75), vector);
  wcout << L"\n  First(3PI/4) = " << AboutVector3d(vector);
  pEllipse->getSecondDeriv((OdaPI * 0.25), vector);
  wcout << L"\n  Second(PI/4) = " << AboutVector3d(vector);
  pEllipse->getSecondDeriv((OdaPI * 0.75), vector);
  wcout << L"\n  Second(3PI/4) = " << 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 ModifyEllipseProperties() 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 ellipse properties using the PrintEllipseFeatures() function, and specific ellipse properties using the PrintEllipseProperties() function. When the user selects the [p] operation, the function displays only specific ellipse properties.

When the user selects [C], the function gets the center of the ellipse using the center() method, calls the EntryPoint3d() function for entering its coordinates, and sets the returned point as the new center using the setCenter() method if entry is successful.

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 [A], the function gets the major axis of the ellipse using the majorAxis() method and calls the EntryVector3d() function for entry of its coordinates. If entry is successful, the function calculates the new normal as a product of the old minor and new major vectors and checks whether the calculated normal is not parallel to the axes, that is, not zero. Then the function gets the current center using the center() method, gets the current radius ratio using the radiusRatio() method, and sets the ellipse geometry using the set() method — passing to it the center point as the first argument, calculated normal as the second argument, the entered major axis vector as the third argument, and the current radius ratio as the fourth argument.

When the user selects [W], the function inquires about the center, major axis, normal, and radius ratio to specify the ellipse 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. 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 the entered values are correct, the function sets the ellipse geometry using the set() method and passes to it the center point as the first argument, normal as the second argument, major axis vector as the third argument, and radius ratio as the fourth argument. When errors occur, the function catches them using the try....catch statement.

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 ellipse 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 ellipse properties using the [P] operation.

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

The ModifyEllipseProperties() 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 ModifyEllipseProperties(OdDbEllipse* pEllipse)
{
  wchar_t ch = L'\0';
  double value, param, ratio;
  OdGePoint3d point;
  OdGeVector3d axis;
  OdGeVector3d vector;

  wcout << L"\n\nStart modifying of the ellipse 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 Ellipse Properties";
        PrintEllipseFeatures(pEllipse);


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


      case L'C':          // Set the center
      case L'c':
        wcout << L"Entry the center";
        point = pEllipse->center();

        if(EntryPoint3d(point))
        {
          pEllipse->setCenter(point);
          wcout << L"Center is set to " << AboutPoint3d(pEllipse->center()) << L"\n";
        }
        break;


      case L'A':          // Set the major axis
      case L'a':
        wcout << L"Entry the major axis";
        axis = pEllipse->majorAxis();

        if(EntryVector3d(axis))
        {
          vector = axis.crossProduct(pEllipse->minorAxis());
          if(!vector.isZeroLength())
          {
            pEllipse->set(pEllipse->center(), vector.normalize(), axis, pEllipse->radiusRatio());
            ch = L'p';
            continue;
          }
          else wcout << L"Error: Major axis cannot be parallel to the minor axis\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'W':          // Set the whole ellipse 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 perpendicularly to the axis";
            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;

                try {
                  pEllipse->set(point, vector, axis, ratio);
                  ch = L'p';
                  continue;
                }
                catch(OdError& e)
                {
                  wcout << L"\nError: " << e.code() << L" - " << e.description() << L"\n";
                  break;
                }
              }
              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"\nC. Set the center";
    wcout << L"\nA. Set the major axis";
    wcout << L"\nR. Set the radius ratio";
    wcout << L"\nW. Set the whole 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 ellipse properties\n";
}

Testing gives the following results:


Start modifying of the ellipse properties

C. Set the center
A. Set the major axis
R. Set the radius ratio
W. Set the whole 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 Ellipse Properties
Normal = (0,0,1)
Center = (0,0,0)
Major Axis = (1,0,0)
Minor Axis = (0,1,0)
Major Radius = 1
Minor Radius = 1
Radius Ratio = 1

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


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

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

Entry the normal perpendicularly to the axis
Current vector directions: (0,0,1)
Entry X-direction:>0
Entry Y-direction:>0
Entry Z-direction:>0.7

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

------ Specific Ellipse Properties
Normal = (0,0,1)
Center = (1.8,1.8,0)
Major Axis = (8.6,2.1,0)
Minor Axis = (-1.575,6.45,0)
Major Radius = 8.85268
Minor Radius = 6.63951
Radius Ratio = 0.75

When the operation is C-"Set the center":


Entry the center
Current coordinates: (1.8,1.8,0)
Entry X-coordinate:>2.4
Entry Y-coordinate:>1.9
Entry Z-coordinate:>1.5
Center is set to (2.4,1.9,1.5)

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 Ellipse Properties
Normal = (0,0,1)
Center = (2.4,1.9,1.5)
Major Axis = (8.6,2.1,0)
Minor Axis = (-1.722,7.052,0)
Major Radius = 8.85268
Minor Radius = 7.2592
Radius Ratio = 0.82

When the operation is A-"Set the major axis":


Entry the major axis
Current vector directions: (8.6,2.1,0)
Entry X-direction:>9.3
Entry Y-direction:>1.9
Entry Z-direction:>2.1

------ Specific Ellipse Properties
Normal = (-0.209992,-0.0512771,0.976358)
Center = (2.4,1.9,1.5)
Major Axis = (9.3,1.9,2.1)
Minor Axis = (-1.60946,7.80731,0.0638717)
Major Radius = 9.72163
Minor Radius = 7.97173
Radius Ratio = 0.82

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


Entry a parameter [0 to 2PI]:>2.34
Compute at (2.34):
Distance = 21.1573
Point on = (-5.22508,6.18771,0.0852066)
1-Derivative = (-5.56224,-6.79556,-1.5532)
2-Derivative = (7.62508,-4.28771,1.41479)
--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 Ellipse Properties
  Start point = (11.7,3.8,3.6)
  End point = (11.7,3.8,3.6)
  Start parameter = 0
  End parameter = 6.28319
  Area = 243.468
  Perimeter = 55.6319
  Parameter at half-perimeter = 3.13599
  Quadrants:
  Q(0) = (11.7,3.8,3.6)
  Q(PI/2) = (0.790536,9.70731,1.56387)
  Q(PI) = (-6.9,9.5612e-016,-0.6)
  Q(3PI/2) = (4.00946,-5.90731,1.43613)
  Derivatives:
  First(PI/4) = (-7.71416,4.1771,-1.43976)
  First(3PI/4) = (-5.43803,-6.8641,-1.53009)
  Second(PI/4) = (-5.43803,-6.8641,-1.53009)
  Second(3PI/4) = (7.71416,-4.1771,1.43976)
  Entity Plane = (-0.209992 * X + -0.0512771 * Y + 0.976358 * Z + -0.863129)
  ------ Specific Ellipse Properties
  Normal = (-0.209992,-0.0512771,0.976358)
  Center = (2.4,1.9,1.5)
  Major Axis = (9.3,1.9,2.1)
  Minor Axis = (-1.60946,7.80731,0.0638717)
  Major Radius = 9.72163
  Minor Radius = 7.97173
  Radius Ratio = 0.82

Use the Q-"Quit" operation to exit:


Stop modifying of the ellipse properties

See Also

Working with Ellipses

Example of Working with the Circle Object

Example of Working with the Elliptical Arc

Example of Entering and Displaying 3D Point Objects

Example of Entering and Displaying 3D Vector Objects

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