//=========================================================================== // TRAVERSE // // This program simulates laying out a traverse, leg by leg. From a // starting point, one moves a given distance on a given bearing to a new // point (hub), and continues traversing a terrain from hub to hub. //=========================================================================== #include #pragma hdrstop #include #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //========================================================= DECLARE VARIABLES float bearing, distance; struct point { float x; float y; } ; point startPoint, oldPoint, newPoint; float deltaBearing, deltaDistance; int loops; //======================================================= PLOT STARTING POINT void plotStartingPoint (void) { Form1->Canvas->Brush->Color = clYellow; Form1->Canvas->Ellipse(oldPoint.x-3, oldPoint.y-3, oldPoint.x+3, oldPoint.y+3); Form1->Canvas->Brush->Color = clRed; } //================================================================ INITIALIZE void initialize (void) { Form1->Canvas->Brush->Color = clRed; startPoint.x = 250; startPoint.y = 250; oldPoint.x = startPoint.x; oldPoint.y = startPoint.y; plotStartingPoint(); } //---------------------------------- PLOT NEXT LEG WITHOUT CALLING A FUNCTION void __fastcall TForm1::ButtonPlotNextLegWOFunctionClick(TObject *Sender) { // grab the bearing from the edit box // we must convert text string to floating point bearing = StrToFloat(EditBearing->Text); // the angle increases counterclockwise; we want it increasing clockwise bearing = 360 - bearing; // the angle zero points down; we want it pointing up bearing = bearing + 180; // convert degrees to radians to satisfy trigonometric functions bearing = (bearing * M_PI) / 180; // grab the distance from the edit box distance = StrToFloat(EditDistance->Text); // calculate the newPoint position newPoint.x = oldPoint.x + distance * sin(bearing); newPoint.y = oldPoint.y + distance * cos(bearing); // render the new leg of the traverse Form1->Canvas->MoveTo(oldPoint.x, oldPoint.y); Form1->Canvas->LineTo(newPoint.x, newPoint.y); Form1->Canvas->Ellipse(newPoint.x-2, newPoint.y-2, newPoint.x+2, newPoint.y+2); // the newPoint becomes the oldPoint oldPoint.x = newPoint.x; oldPoint.y = newPoint.y; } //========================================================= NEXT HUB FUNCTION // notice that it operates on the global variables oldPoint and newPoint void nextHub (float bearing, float distance) { bearing = ((360 + 180 - bearing) * M_PI) / 180; newPoint.x = oldPoint.x + distance * sin(bearing); newPoint.y = oldPoint.y + distance * cos(bearing); } //----------------------------- PLOT NEXT LEG WHILE CALLING A FUNCTION BUTTON void __fastcall TForm1::ButtonPlotNextLegWFunctionClick(TObject *Sender) { // grab the bearing and distance from the edit boxes bearing = StrToFloat(EditBearing->Text); distance = StrToFloat(EditDistance->Text); // call the function with the oldPoint, bearing and distance // the function will update the global variables newPoint nextHub (bearing, distance); // render the line and new point Form1->Canvas->MoveTo(oldPoint.x, oldPoint.y); Form1->Canvas->LineTo(newPoint.x, newPoint.y); Form1->Canvas->Ellipse(newPoint.x-2, newPoint.y-2, newPoint.x+2, newPoint.y+2); // get ready for a new newPoint oldPoint.x = newPoint.x; oldPoint.y = newPoint.y; } //================================================== RECURSIVE LOOPS FUNCTION void recursiveLoops (void) { bearing = StrToFloat(Form1->EditBearing->Text); distance = StrToFloat(Form1->EditDistance->Text); deltaBearing = StrToFloat(Form1->EditDeltaBearing->Text); deltaDistance = StrToFloat(Form1->EditDeltaDistance->Text); loops = StrToInt(Form1->EditLoops->Text); for (int i = 0; i <= loops; i++ ) { bearing = bearing + deltaBearing; distance = distance + deltaDistance; nextHub (bearing, distance); // render the line and new point Form1->Canvas->MoveTo(oldPoint.x, oldPoint.y); Form1->Canvas->LineTo(newPoint.x, newPoint.y); Form1->Canvas->Ellipse(newPoint.x-2, newPoint.y-2, newPoint.x+2, newPoint.y+2); // get ready for a new newPoint oldPoint.x = newPoint.x; oldPoint.y = newPoint.y; } } //------------------------------------------------------------ ON FORM CREATE void __fastcall TForm1::FormCreate(TObject *Sender) { initialize(); } //---------------------------------------------- CENTER STARTING POINT BUTTON void __fastcall TForm1::ButtonCenterClick(TObject *Sender) { initialize(); } //------------------------------------------------------------ REFRESH BUTTON void __fastcall TForm1::ButtonRefreshClick(TObject *Sender) { Refresh(); } //---------------------------------------------------------- RUN LOOPS BUTTON void __fastcall TForm1::ButtonRunLoopsClick(TObject *Sender) { recursiveLoops(); } //------------------------------------------------------------- ON FORM PAINT void __fastcall TForm1::FormPaint(TObject *Sender) { plotStartingPoint(); } //--------------------------------------------------- SET NEW ORIGIN ON CLICK void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { oldPoint.x = X; oldPoint.y = Y; plotStartingPoint(); } //========================================================== THAT'S ALL FOLKS