In this post and the next two posts, I will be building a spiral command. In this post we will be dealing with the algorithm. When we are done with this post, we will have a command that draws a spiral that would have 20 loops if it started in the middle, but we also told the algorithm to not draw the innermost 10 loops. We have also hard currently coded the command to draw the spiral with a distance of 10 between each loop.
I will be using the name MYSPIRALM for this temporary command. When finished, this will be the command for the macro version.
Note: There is a naming convention that states if you have both a dialog driven command and a comand that is all command line for macros, the macro version ends with an M.
Hardcoded values:
- Distance Between Loops: 10
- Number of Inner Loops Not Drawn: 10
- Total Number of Loops: 20
- Clockwise/Counter Clockwise: Clockwise
- Growth Between Loops: None
Friday, August 20, 2010MyLine Command (A Complete Example)
We have finally reached the point where we can produce an entire example. In my previous post I explained how, conceptually, this command will work. Now, here is the actual code for the command along with a lot of comments.
I have also copied and commented out the definitions for the relevant elements that we are going to create.
I hope that you fire up Visual Studio and try building this code; if you are impatient though and want to just run it, here
Code Snippet - MySpiralM Command
- ////////////////////////////////////////////////////////////////////////////
- //
- // File Name: MySpiral.cpp
- // Written by: L. Lee Saunders
- // (C)2010 Beer & Pretzel Games
- // All rights reserved
- //
- ////////////////////////////////////////////////////////////////////////////
- #include <windows.h>
- #include <math.h>
- extern "C"
- {
- #include <xp.h>
- #include <Extend/Mysvc.h>
- }
- extern XP MyXP;
- ////////////////////////////////////////////////////////////////////////////
- void XPCALL DrawSpiral (int Result,int Result2,int Result3);
- GPOINT2 CenterPoint;
- FORMST(lpszCenterPoint,"Center Point:\0")
- RDATA PCenterReq =
- { sizeof(RDATA), RD_2DC, NULL, RDF_C, (DWORD*)&CenterPoint,
- (DWORD*)&lpszCenterPoint, RDC_XH, DrawSpiral, NULL, NULL, 0, NULL, 0};
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- void XPCALL MySpiralM (void)
- {
- ReqData(&PCenterReq); //get center point
- }
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- void XPCALL DrawSpiral (int Result,int Result2,int Result3)
- {
- if (Result != X_OK) { CmdEnd(); return; }
- float Growth = 1;
- float LoopDistance = 10;
- int Rotations = 20;
- int InnerLoopsToSkip = 10;
- const char * Direction = "0\0";
- pENTREC pEntRec; //Create a new drawing database entity
- float CenterX = CenterPoint.x;
- float CenterY = CenterPoint.y;
- int iDirection;
- MarkUndo();
- // Insert an empty path into the drawing list
- pEntRec=DLApndE(NULL, ET_PATH2, sizeof(PATH2)+sizeof(GPOINT2));
- // Get the common stuff
- GetCStuff(pEntRec);
- // Set the smoothing to Parabolic Blend (through-point)
- pEntRec->Path.Path.SmType = SM_PB;
- // Set the centerpoint of the spiral
- pEntRec->Path.Path.Nodes[0].x = CenterPoint.x;
- pEntRec->Path.Path.Nodes[0].y = CenterPoint.y;
- // How many points to draw per circle
- const double STEPS_PER_ROTATION = 50;
- // Amount to add to angle at each step
- double increment = M_PI/STEPS_PER_ROTATION; // Splitting up
- double theta = 2*M_PI*InnerLoopsToSkip; // This allows for an open area
- // inside the spiral
- // Determines if the loops rotates clockwise or counter clockwise
- iDirection = strcmp(Direction, "0") == 0 ? 1 : -1;
- while(theta < (Rotations * 2) * M_PI)
- {
- pEntRec=DLResize(pEntRec, pEntRec->Path.CStuff.ERLen +
- sizeof(GPOINT2));
- pEntRec->Path.Path.Nodes[pEntRec->Path.Path.Count].x=(float)
- (CenterX + theta * cos(theta) * (1/(M_PI * 2)) * LoopDistance *
- iDirection);
- pEntRec->Path.Path.Nodes[pEntRec->Path.Path.Count].y=(float)
- (CenterY + theta * sin(theta) * (1/(M_PI * 2)) * LoopDistance);
- pEntRec->Path.Path.EParm=(float)pEntRec->Path.Path.Count;
- pEntRec->Path.Path.Count++;
- LoopDistance = LoopDistance * Growth;
- theta = theta + increment; //If theta grows faster then increment,
- //it will have wider spaces between each loop
- }
- EDraw(pEntRec); //Draw our line
- ShowChanges(); //Needed for CC3 to "Show Changes" to the DB
- CmdEnd();
- return;
- }
- ////////////////////////////////////////////////////////////////////////////