Close

Relief for ODA Team in Ukraine

Learn more
ODA Drawings SDK
Example of Working with the Circular Arc

The example demonstrates displaying and modifying the properties of a circular arc object. This example uses a console menu that represents the following operations: getting and setting the center [C], radius [R], normal [N], thickness [T], start angle [S], end angle [E], computing parameters [Z], and displaying the object properties, general properties, computed properties, specific properties [P], and modifying the general entity properties [M].

The PrintCircularArcProperties() function requires a pointer to an existing circular arc object and displays its specific properties. The function gets the specific properties using the center(), normal(), radius(), thickness(), 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 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 PrintCircularArcProperties() function has the following implementation:


void PrintCircularArcProperties(OdDbArc* pArc)
{
  wcout << L"\n  Normal = " << AboutVector3d(pArc->normal())
        << L"\n  Center = " << AboutPoint3d(pArc->center())
        << L"\n  Radius = " << pArc->radius()
        << L"\n  Start angle = " << pArc->startAngle()
        << L"\n  End angle = " << pArc->endAngle()
        << L"\n  Thickness = " << pArc->thickness();
}

The PrintCircularArcFeatures() function requires a pointer to an existing circular arc object and displays the properties computed from the 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 X-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 the parameter. The middle point is calculated at half-length. The first and second derivatives are vectors which are also computed at the parameter in the start, end, and middle point. The circular arc is the planar entity, and the function gets and displays the coefficients of the plane using the AboutPlane() function.

The PrintCircularArcFeatures() function has the following implementation:


void PrintCircularArcFeatures(OdDbArc* pArc)
{
  OdGePlane plane;
  OdGePoint3d point;
  OdGeVector3d vector;
  OdDb::Planarity planarity;
  double value, start, end;

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

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

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

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

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

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

The ModifyCircularArcProperties() function requires a pointer to an existing circular arc 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 if the user does not select the [Q] operation. The function uses the EntryPoint3d() function for entering coordinates of a three-dimensional point and the EntryVector3d() function for entering coordinates of a three-dimensional vector. The EntryPoint3d() and EntryVecto3d() functions require a reference to an instance of the three-dimensional point or three-dimensional vector to be modified as an argument; the functions and 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 circular arc properties using the PrintCircularArcFeatures() function, and specific circular arc properties using the PrintCircularArcProperties() function. When the user selects the [p] operation, the function displays only specific circular arc properties.

When the user selects [C], the function gets the center 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 [N], the function gets the normal to the plane of the circle using the normal() method, calls the EntryVector3d() function for entering its coordinates, and sets the returned vector as a new normal using the setNormal() method if entry is successful.

When the user selects [R], the function gets the current radius using the radius() method and requests a positive double value. If an entered value is incorrect or negative, the function displays an error message and breaks to the console menu. If an entered value is correct, the function sets the new radius using the setRadius() method.

When the user selects [T], the function gets the current thickness using the thickness() method and requests a double value. 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 thickness using the setThickness() 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 [Z], the function gets 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 circular 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 circular arc object for modifying its general entity properties. After modification, the function displays all circular arc properties using the [P] operation.

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

The ModifyCircularArcProperties() function has the following implementation:


#include "..\Common\DemoMain.h"
#include "DbArc.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 ModifyCircularArcProperties(OdDbArc* pArc)
{
  wchar_t ch = L'\0';
  double value, param;
  OdGePoint3d point;
  OdGeVector3d vector;

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

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


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


      case L'p':          // Print the specific properties
        wcout << L"\n  ------ Specific Circular Arc Properties";
        PrintCircularArcProperties(pArc);
        wcout << L"\n";        
        break;


      case L'N':          // Set the normal
      case L'n':
        wcout << L"Entry the normal";
        vector = pArc->normal();

        if(EntryVector3d(vector))
        {
          pArc->setNormal(vector);
          wcout << L"Normal is set to " << AboutVector3d(pArc->normal()) << L"\n";
        }
        break;


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

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


      case L'R':          // Set the radius
      case L'r':
        wcout << L"\nCurrent radius = " << pArc->radius()
              << L"\nEntry a new radius [r>0]:>";
        wcin >> value;

        if(!wcin.fail() && wcin.peek() == 10)
        {
          if(value > 0)
          {
            pArc->setRadius(value);
            wcout << L"Radius is set to: " << pArc->radius() << L"\n";
          }
          else wcout << L"Error: Radius must be a positive non-zero double value\n";
        }
        else { 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 = " << pArc->startAngle()
              << L"\nEntry a new angle [0...2PI]:>";
        wcin >> value;

        if(!wcin.fail() && wcin.peek() == 10)
        {
            pArc->setStartAngle(value);
            wcout << L"Start angle is set to: " << pArc->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 = " << pArc->endAngle()
              << L"\nEntry a new angle [0...2PI]:>";
        wcin >> value;

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


      case L'T':          // Set the thickness
      case L't':
        wcout << L"\nCurrent thickness = " << pArc->thickness()
              << L"\nEntry a new thickness [t>0-along normal|t<0-opposite normal]:>";
        wcin >> value;

        if(!wcin.fail() && wcin.peek() == 10)
        {
            pArc->setThickness(value);
            wcout << L"Thickness is set to: " << pArc->thickness() << 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(pArc->getDistAtParam(param, value) == eOk)
            wcout << L"\nDistance = " << value;
          if(pArc->getPointAtParam(param, point) == eOk)
            wcout << L"\nPoint on = " << AboutPoint3d(point);
          if(pArc->getFirstDeriv(param, vector) == eOk)
            wcout << L"\n1-Derivative = " << AboutVector3d(vector);
          if(pArc->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"\nR. Set the radius";
    wcout << L"\nN. Set the normal";
    wcout << L"\nT. Set the thickness";
    wcout << L"\nE. Set the end angle";
    wcout << L"\nS. Set the start angle";
    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 circular arc properties\n";
}

Testing gives the following results:


Start modifying of the circular arc properties

C. Set the center
R. Set the radius
N. Set the normal
T. Set the thickness
E. Set the end angle
S. Set the start angle
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 Circular Arc Properties
Normal = (0,0,1)
Center = (0,0,0)
Radius = 0
Start angle = 0
End angle = 0
Thickness = 0

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


Entry the center
Current coordinates: (0,0,0)
Entry X-coordinate:>1.1
Entry Y-coordinate:>2.2
Entry Z-coordinate:>3.3
Center is set to (1.1,2.2,3.3)

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


Current radius = 0
Entry a new radius [r>0]:>-3
Error: Radius must be a positive double value

Current radius = 0
Entry a new radius [r>0]:>2.5
Radius is set to: 2.5

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


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

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


Current end angle = 0
Entry a new angle [0...2PI]:>-2.15
End angle is set to: 4.13319

When the operation is N-"Set the normal":


Entry the normal
Current vector directions: (0,0,1)
Entry X-direction:>2.3
Entry Y-direction:>0.6
Entry Z-direction:>1.1
Normal is set to (0.878144,0.229081,0.419982)

When the operation is T-"Set the thickness":


Current thickness = 0
Entry a new thickness [t>0-along normal|t<0-opposite normal]:>1.8
Thickness is set to: 1.8

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


Entry a parameter [0 to 2PI]:>1.96
Compute at (1.96):
Distance = 4.3625
Point on = (0.399482,1.03688,5.39915)
1-Derivative = (0.969365,-2.13756,-0.860912)
2-Derivative = (0.700518,1.16312,-2.09915)
--at--

Entry a parameter [0 to 2PI]:>5.31
Compute at (5.31):                               // errors occur
--at-- 

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


H=40
  ------ Common Object Properties
  Type: AcDbArc
  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 Circular Arc Properties
  Start parameter = 0.215
  End parameter = 4.13319
  Area = 14.4345
  Arc Length = 9.79546
  Parameter at half-length = 2.17409
  Start point = (0.266723,4.5068,3.78405)
  First derivative in start point = (-0.85793,-0.775026,2.21659)
  Second derivative in start point = (0.833277,-2.3068,-0.484049)
  End point = (2.29566,1.09772,1.40122)
  First derivative in end point = (0.0279615,2.16956,-1.24186)
  Second derivative in end point = (-1.19566,1.10228,1.89878)
  Middle point = (0.621427,0.609286,5.16831)
  First derivative in middle point = (1.09607,-1.84164,-1.28724)
  Second derivative in middle point = (0.478573,1.59071,-1.86831)
  Entity Plane = (0.878144 * X + 0.229081 * Y + 0.419982 * Z + -2.85588)  
  ------ Specific Circular Arc Properties
  Normal = (0.878144,0.229081,0.419982)
  Center = (1.1,2.2,3.3)
  Radius = 2.5
  Start angle = 0.215
  End angle = 4.13319
  Thickness = 1.8

Use the Q-"Quit" operation to exit:


Stop modifying of the circular arc properties

See Also

Working with Circular Arcs

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.