Drawings SDK Developer Guide > Working with .dwg Files > Working with Entities > Working with Specific Entitites > Working with Helixes > Example of Working with the Helix Object
Example of Working with the Helix Object

This example demonstrates displaying and modifying the properties of a helix object. This example uses a console menu that represents the following operations: getting and setting the start point [S], axis point [C], axis vector [V], base radius [B], top radius [T], number of turns (revolutions) [R], total height [H], turn height [F], twist direction [W], constrain [C], computing parameters [Z], and displaying the object properties, general properties, computed properties, specific properties [P], and modifying the general entity properties [M].

The example uses the following header files, examples, and functions implemented in them:


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

// Example of Entering and Displaying for Helix Constrain Type
bool EntryHelixConstrain(OdInt16& refType);
OdString AboutHelixConstrain(OdDbHelix::ConstrainType type);

// Example of Entering and Displaying for 3D Point Objects
bool EntryPoint3d(OdGePoint3d& point);
OdString AboutPoint3d(const OdGePoint3d& point);

// Example of Entering and Displaying for 3D Vector Objects
bool EntryVector3d(OdGeVector3d& vector);
OdString AboutVector3d(const OdGeVector3d& vector);

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

The PrintHelixProperties() function requires a pointer to an existing helix object and displays its specific properties. The function gets the specific properties using the startPoint(), axisPoint(), axisVector(), turns(), baseRadius(), topRadius(), height(), turnHeight(), turnSlope(), totalLength(), twist(), and constrain() methods. The function uses the AboutPoint3d() function for converting the coordinates of the start and axis points to a string value and uses the AboutVector3d() function for converting the coordinates of the axis vector 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 PrintHelixProperties() function has the following implementation:


void PrintHelixProperties(OdDbHelix* pHelix)
{
  wcout << L"\n  Start point = " << AboutPoint3d(pHelix->startPoint())
        << L"\n  Axis point = " << AboutPoint3d(pHelix->axisPoint())
        << L"\n  Axis vector = " << AboutVector3d(pHelix->axisVector())
        << L"\n  Top radius = " << pHelix->topRadius()
        << L"\n  Base radius = " << pHelix->baseRadius()
        << L"\n  Total length = " << pHelix->totalLength()
        << L"\n  Total height = " << pHelix->height()
        << L"\n  Turn height = " << pHelix->turnHeight()
        << L"\n  Turn slope = " << pHelix->turnSlope()
        << L"\n  Turns = " << pHelix->turns()
        << L"\n  Twist = " << ((pHelix->twist()) ? L"counter-clockwise" : L"clockwise")
        << L"\n  Constrain type = " << AboutHelixConstrain(pHelix->constrain());
}

The PrintHelixFeatures() function requires a pointer to an existing helix object and displays the properties computed from the parameter (features). The function uses the getStartPoint(), getEndPoint(), getStartParam(), getEndParam(), getArea(), getDistAtParam(), getParamAtDist(), getPointAtParam(), getFirstDeriv(), and getSecondDeriv() methods, and uses the AboutEntityPlane(), AboutPoint3d() and AboutVector3d() functions. The parameter is the angle measured from the X-axis and is changed from 0 to 2*PI*turns. The first and second derivatives are vectors which are computed at the parameter in the start and end points.

The PrintHelixFeatures() function has the following implementation:


void PrintHelixFeatures(OdDbHelix* pHelix)
{
  OdGePoint3d point;
  OdGeVector3d vector;
  double value, start, end;

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

  pHelix->getArea(value);
  wcout << L"\n  Area = " << value;
  pHelix->getDistAtParam((end + start)/2, value);
  wcout << L"\n  Half-length = " << value;

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

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

  wcout << L"\n  " << AboutEntityPlane(pHelix);
}

The ModifyHelixProperties() function requires a pointer to an existing helix object and implements a 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 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 helix properties using the PrintHelixFeatures() function, and specific helix properties using the PrintHelixProperties() function. When the user selects the [p] operation, the function displays only specific helix properties.

When the user selects [S] or [A], the function gets the start point or axis point using the corresponding StartPoint() or axisPoint() method, calls the EntryPoint3d() function for entering its coordinates, and sets the returned point as the new start point or axis point using the corresponding setStartPoint() or setAxisPoint() method if entry is successful.

When the user selects [V], the function gets the axis vector to the base plane using the axisVector() method, calls the EntryVector3d() function for entering its coordinates, and sets the returned vector as a new axis vector using the setAxisVector() method if entry is successful.

When the user selects [B] or [T], the function gets the current base or top radius using the corresponding baseRadius() or topRadius() 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 base or top radius using the corresponding setBaseRadius() or setTopRadius() method.

When the user selects [R], the function gets the current number of turns using the turns() 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 number of turns using the setTurns() method.

When the user selects [H] or [F], the function gets the current total height or the turn height using the corresponding height() or turnHeight() 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 total height or turn height using the corresponding setHeight() or setTurnHeight() method.

When the user selects [Z], the function gets a parameter as a double value in the range 0 to 2*PI*turns radians. If an entered value is correct, the function computes the coordinates of the point on the spiral curve 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 helix object for modifying its general entity properties. After modification, the function displays all helix properties using the [P] operation.

The ModifyHelixProperties() function has the following implementation:


void ModifyHelixProperties(OdDbHelix* pHelix)
{
  wchar_t ch = L'\0';
  double value, param;
  OdInt16 type;
  OdGePoint3d point;
  OdGeVector3d vector;

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

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


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


      case L'p':          // Print the specific properties
        wcout << L"\n  ------ Specific Helix Properties";
        PrintHelixProperties(pHelix);
        wcout << L"\n";        
        break;


      case L'S':          // Set the start point
      case L's':
        wcout << L"Entry the start point";
        point = pHelix->startPoint();
        if(EntryPoint3d(point))
        {
          pHelix->setStartPoint(point);
          wcout << L"Start point is set to: " << AboutPoint3d(pHelix->startPoint())
                << L"\nBase radius is set to: " << pHelix->baseRadius() << L"\n";
        }
        break;


      case L'A':          // Set the axis point
      case L'a':
        wcout << L"Entry the axis point";
        point = pHelix->axisPoint();
        if(EntryPoint3d(point))
        {
          pHelix->setAxisPoint(point);
          wcout << L"Axis point is set to: " << AboutPoint3d(pHelix->axisPoint())
                << L"\nStart point is set to: " << AboutPoint3d(pHelix->startPoint()) << L"\n";
        }
        break;


      case L'V':          // Set the axis vector
      case L'v':
        wcout << L"Entry the axis vector";
        vector = pHelix->axisVector();
        if(EntryVector3d(vector))
        {
          pHelix->setAxisVector(vector);
          wcout << L"Axis vector is set to: " << AboutVector3d(pHelix->axisVector()) << L"\n";
        }
        break;


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

        if(!wcin.fail() && wcin.peek() == 10)
        {
          if(value > 0)
          {
            pHelix->setTopRadius(value);
            wcout << L"Top radius is set to: " << pHelix->topRadius() 
                  << L"\nTurn slope is set to: " << pHelix->turnSlope() << L"\n";
          }
          else wcout << L"Error: Top 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'B':          // Set the base radius
      case L'b':
        wcout << L"\nCurrent base radius = " << pHelix->baseRadius()
              << L"\nEntry a new radius [R>0]:>";
        wcin >> value;

        if(!wcin.fail() && wcin.peek() == 10)
        {
          if(value > 0)
          {
            pHelix->setBaseRadius(value);
            wcout << L"Base radius is set to: " << pHelix->baseRadius()
                  << L"\nTurn slope is set to: " << pHelix->turnSlope()
                  << L"\nStart point is set to: " << AboutPoint3d(pHelix->startPoint()) << L"\n";
          }
          else wcout << L"Error: Base 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'H':          // Set the total height
      case L'h':
        wcout << L"\nCurrent total height = " << pHelix->height()
              << L"\nEntry a new height [H>0]:>";
        wcin >> value;

        if(!wcin.fail() && wcin.peek() == 10)
        {
          if(value > 0)
          {
            pHelix->setHeight(value);
            wcout << L"Turns is set to: " << pHelix->turns()
                  << L"\nTurn height is set to: " << pHelix->turnHeight()
                  << L"\nTotal height is set to: " << pHelix->height() << L"\n";
          }
          else wcout << L"Error: Height must be a positive non-zero double value\n";
        }
        else { wcin.clear();  wcin.sync();  wcout << L"Error: Invalid entered value\n"; }
        break;


      case L'F':          // Set the turn height
      case L'f':
        wcout << L"\nCurrent turn height = " << pHelix->turnHeight()
              << L"\nEntry a new height [H>0]:>";
        wcin >> value;

        if(!wcin.fail() && wcin.peek() == 10)
        {
          if(value > 0)
          {
            pHelix->setTurnHeight(value);
            wcout << L"Turns is set to: " << pHelix->turns()
                  << L"\nTurn height is set to: " << pHelix->turnHeight()
                  << L"\nTotal height is set to: " << pHelix->height() << L"\n";
          }
          else wcout << L"Error: Turn Height must be a positive non-zero double value\n";
        }
        else { wcin.clear();  wcin.sync();  wcout << L"Error: Invalid entered value\n"; }
        break;


      case L'R':          // Set the number of turns (revolutions)
      case L'r':
        wcout << L"\nCurrent turns (revolutions) = " << pHelix->turns()
              << L"\nEntry a new turns (revolutions) [T>0]:>";
        wcin >> value;

        if(!wcin.fail() && wcin.peek() == 10)
        {
          if(value > 0)
          {
            pHelix->setTurns(value);
            wcout << L"Turns is set to: " << pHelix->turns()
                  << L"\nTurn height is set to: " << pHelix->turnHeight()
                  << L"\nTotal height is set to: " << pHelix->height() << L"\n";
          }
          else wcout << L"Error: Turns must be a positive non-zero double value\n";
        }
        else { wcin.clear();  wcin.sync();  wcout << L"Error: Invalid entered value\n"; }
        break;


      case L'C':          // Set the constrain type
      case L'c':
        wcout << L"\nCurrent constrain type = " << (type = pHelix->constrain());

        if(EntryHelixConstrain(type))
        {
          pHelix->setConstrain((OdDbHelix::ConstrainType) type);
          wcout << L"Constrain type is set to: " << AboutHelixConstrain(pHelix->constrain()) << L"\n";
        }
        break;


      case L'W':          // Switch the twist direction
      case L'w':
        wcout << "\nSwitch the twist direction [L-counterclockwise|R-clockwise]:>";
        wcin >> ch;

        if(ch == L'L' || ch == L'l') pHelix->setTwist(true);
        else if(ch == L'R' || ch == L'r') pHelix->setTwist(false);

        wcout << L"Twist direction is set to: " << ((pHelix->twist()) ? L"Counter-clockwise" : L"Clockwise") << L"\n";
        break;


      case L'Z':          // Compute the features at parameter
      case L'z':
        wcout << L"\nEntry a parameter [0 to " << Oda2PI * pHelix->turns() << "]:>";
        wcin >> param;

        if(!wcin.fail() && wcin.peek() == 10)
        {
          wcout << L"Compute at (" << param << L"):";
          if(pHelix->getDistAtParam(param, value) == eOk)
            wcout << L"\nDistance = " << value;
          if(pHelix->getPointAtParam(param, point) == eOk)
            wcout << L"\nPoint on = " << AboutPoint3d(point);
          if(pHelix->getFirstDeriv(param, vector) == eOk)
            wcout << L"\n1-Derivative = " << AboutVector3d(vector);
          if(pHelix->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"\nA. Set the axis point";
    wcout << L"\nV. Set the axis vector";
    wcout << L"\nS. Set the start point";
    wcout << L"\nT. Set the top radius";
    wcout << L"\nB. Set the base radius";
    wcout << L"\nF. Set the turn height";
    wcout << L"\nH. Set the helix height";
    wcout << L"\nC. Set the constrain type";
    wcout << L"\nR. Set the turns (revolutions)";
    wcout << L"\nW. Switch the twist direction";
    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 helix properties\n";
}

Testing gives the following results:


Start modifying of the helix properties

A. Set the axis point
V. Set the axis vector
S. Set the start point
T. Set the top radius
B. Set the base radius
F. Set the turn height
H. Set the helix height
C. Set the constrain type
R. Set the turns (revolutions)
W. Switch the twist direction
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 Helix Properties
Start point = (0,0,0)
Axis point = (0,0,0)
Axis vector = (0,0,1)
Top radius = 1
Base radius = 0
Total length = 1
Total height = 1
Turn height = 1
Turn slope = 0.785398
Turns = 1
Twist = counter-clockwise
Constrain type = [0-TurnHeight]

When the operation is B-"Set the base radius":


Current base radius = 0
Entry a new radius [R>0]:>2
Base radius is set to: 2
Turn slope is set to: -0.785398
Start point is set to: (2,0,0)

When the operation is T-"Set the top radius":


Current top radius = 1
Entry a new top radius [R>0]:>3
Top radius is set to: 3
Turn slope is set to: 0.785398

When the operation is R-"Set the turns (revolutions)":


Current turns (revolutions) = 1
Entry a new turns (revolutions) [T>0]:>3
Turns is set to: 3
Turn height is set to: 1
Total height is set to: 3

When the operation is F-"Set the turn height":


Current turn height = 1
Entry a new height [H>0]:>0.5
Turns is set to: 6
Turn height is set to: 0.5
Total height is set to: 3

When the operation is H-"Set the total height":


Current total height = 3
Entry a new height [H>0]:>1.5
Turns is set to: 3
Turn height is set to: 0.5
Total height is set to: 1.5

When the operation is C-"Set the constrain type":


Current constrain type = 0
0. Turn Height
1. Revolutions
2. Total Height
3. Quit
Entry the constrain:>1
Constrain type is set to: [1-Revolutions]

When the operation is R-"Set the turns (revolutions)":


Current turns (revolutions) = 3
Entry a new turns (revolutions) [T>0]:>6
Turns is set to: 6
Turn height is set to: 0.25
Total height is set to: 1.5

When the operation is F-"Set the turn height":


Current turn height = 0.25
Entry a new height [H>0]:>0.75
Turns is set to: 6
Turn height is set to: 0.75
Total height is set to: 4.5

When the operation is H-"Set the total height":


Current total height = 4.5
Entry a new height [H>0]:>7.5
Turns is set to: 6
Turn height is set to: 1.25
Total height is set to: 7.5

When the operation is C-"Set the constrain type":


Current constrain type = 1
0. Turn Height
1. Revolutions
2. Total Height
3. Quit
Entry the constrain:>2
Constrain type is set to: [2-TotalHeight]

When the operation is R-"Set the turns (revolutions)":


Current turns (revolutions) = 6
Entry a new turns (revolutions) [T>0]:>3
Turns is set to: 3
Turn height is set to: 2.5
Total height is set to: 7.5

When the operation is F-"Set the turn height":


Current turn height = 2.5
Entry a new height [H>0]:>1.5
Turns is set to: 5
Turn height is set to: 1.5
Total height is set to: 7.5

When the operation is H-"Set the total height":


Current total height = 7.5
Entry a new height [H>0]:>4
Turns is set to: 5
Turn height is set to: 0.8
Total height is set to: 4.5

When the operation is W-"Switch the twist direction":


Switch the twist direction [L-counterclockwise|R-clockwise]:>R
Twist direction is set to: Clockwise

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


Entry the start point
Current coordinates: (2,0,0)
Entry X-coordinate:>4
Entry Y-coordinate:>2
Entry Z-coordinate:>0
Start point is set to: (4,2,0)
Base radius is set to: 4.47214

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


Entry the axis point
Current coordinates: (0,0,0)
Entry X-coordinate:>3
Entry Y-coordinate:>3
Entry Z-coordinate:>0
Axis point is set to: (3,3,0)
Start point is set to: (7,5,0)

When the operation is V-"Set the axis vector":


Entry the axis vector
Current directions: (0,0,1)
Entry X-direction:>2.5
Entry Y-direction:>-2.5
Entry Z-direction:>1.8
Axis vector is set to: (0.630141,-0.630141,0.453701)

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


Entry a parameter [0 to 31.4159]:>6.28
Compute at (6.28):
Distance = 26.0797
Point on = (6.5007,5.1175,-0.158733)
1-Derivative = (0.887835,-1.82006,-3.48034)
2-Derivative = (-2.88755,-2.48426,0.560123)
--at--

Entry a parameter [0 to 31.4159]:>15.7
Compute at (15.7):
Distance = 62.1741
Point on = (1.55514,-0.635438,1.36349)
1-Derivative = (-0.670019,1.47676,3.26227)
2-Derivative = (2.58763,2.23075,-0.495669)
--at--

Entry a parameter [0 to 31.4159]:>32
Compute at (32):                                // errors occur
Distance = 114.311
--at--

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


H=40
  ------ Common Object Properties
  Type: AcDbHelix
  Status: unerased,resident,modified,forRead,forWrite
  Database: c:\test.dwg
  ------ General Entity Properties
  Block: [1F-"*Model_Space"-Block]
  Layer: [10-"0"-Layer]
  Material: [44-"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 Helix Properties
  Start parameter = 0
  End parameter = 31.4159
  Area = 3.58143e-302
  Half-length = 62.2031
  Start point = (6.20518,5.79358,-0.571674)
  First derivative in start point = (0.956769,-1.9214,-3.71683)
  Second derivative in start point = (-3.58033,-2.93177,0.90078)
  End point = (7.76195,2.43299,1.41503)
  First derivative in end point = (0.68397,-1.3758,-2.58016)
  Second derivative in end point = (-2.42425,-2.11984,0.422788)
  ------ Specific Helix Properties
  Start point = (6.20518,5.79358,-0.571674)
  Axis point = (3,3,0)
  Axis vector = (0.630141,-0.630141,0.453701)
  Top radius = 3
  Base radius = 4.29
  Total length = 114.311
  Total height = 4
  Turn height = 0.8
  Turn slope = -0.311969
  Turns = 5
  Twist = clockwise
  Constrain type = [2-TotalHeight]

Use the Q-"Quit" operation to exit:


Stop modifying of the helix properties

See Also

Working with Helixes

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