### Search

 Search WWW Search DelphiForFun.org

As of October, 2016, Embarcadero is offering a free release of Delphi (Delphi 10.1 Berlin Starter Edition ).     There are a few restrictions, but it is a welcome step toward making more programmers aware of the joys of Delphi.  They do say "Offer may be withdrawn at any time", so don't delay if you want to check it out.  Please use the feedback link to let me know if the link stops working.

Support DFF - Shop

If you shop at Amazon anyway,  consider using this link.

We receive a few cents from each purchase.  Thanks

### Support DFF - Donate

If you benefit from the website,  in terms of knowledge, entertainment value, or something otherwise useful, consider making a donation via PayPal  to help defray the costs.  (No PayPal account necessary to donate via credit card.)  Transaction is secure.

Mensa® Daily Puzzlers

For over 15 years Mensa Page-A-Day calendars have provided several puzzles a year for my programming pleasure.  Coding "solvers" is most fun, but many programs also allow user solving, convenient for "fill in the blanks" type.  Below are Amazon  links to the two most recent years.

(Hint: If you can wait, current year calendars are usually on sale in January.)

### Contact

Feedback:  Send an e-mail with your comments about this program (or anything else).

 Search DelphiForFun.org only

### Problem Description

Here's program illustrating how to rotate a figure defined by an array of points without losing accuracy.

### Background & Techniques

Joe W. wrote and sent a program illustrating a problem he was having with distortions introduced as a figure was rotated.   The problem is that points with integer coordinates will generally have non-integer coordinates after they are rotated by an arbitrary angle.   The trick is to maintain the coordinate values in floating point format and only round them to integer values when canvas drawing routines require integers.

 Original Integer rotate 360°in 10° steps Real rotate 360°    in 10° steps

The program below allows the user to draw an arbitrary figure in either integer or real format, copy it to a TPaintbox descendent of the the other format, and rotate both to observe the  result.

Two TPaintbox descendent classes, TIntegerRotate and TRealRotate handle the mechanics of capturing data as the mouse is used to drag draw (moving the mouse with the left button held down) any design you choose.  Each of the classes keeps two copies of the data, one retains the original data for comparison (FDataOrig) and one to hold the rotated points (FData).

The original code used a TList control to hold pointers to TPoint records which are dynamically allocated as they are added.   Current practices and compiler features make the explicit use of pointers largely unnecessary.  In TRealRotate I replaced the Fdata and FDateOrig Tlists with dynamic arrays.    Compare the two AddItem methods to see the difference.   For some reason, the original AddItem also checked to make sure that no two matching points were added.  That seemed like a bug to me, so I eliminated that code also.

There are few other points related to creating visual controls that might be worth mentioning:

 As longtime viewers know, I am not a fan of adding registering user written components to Delphi since maintaining their presence across new computers, Windows versions, and Delphi versions is not likely to happen.  Installed visual components have the advantage though of allowing properties to be set through mouse movements and the Object Inspector at design time.   My solution is to use a standard component (a TPaintBox in this case) as a prototype which is passed to my control's Create procedure to provide the visual aspects.   You can see how that works in this program for the two rotate classes. Properties can be defined in classes to allow users indirect access to some of the data fields.  Properties can protect the fields by taking read access through a function (the Read parameter of the property definition) for retrieving a value, and through a procedure (the Write parameter) when the user is allowed to modify  a private variable.   You can see examples here for the FShowOriginal Boolean variable which the user accesses via the ShowOriginal property and the FNumberPoints variable accessed via the Count property. Indexed access to a list or array is also available via an indexed property, for example the Strings property of a TStringlist or the Items property of a TListBox.  .  In our case, the RData property provide access to the rotated point coordinates.  Check the Copy buttons on the main form to see this in use. By adding the Default parameter to the definition, the  instance name can be used as a synonym for the indexed property. For example, if we define  MyReal:TRealData; then MyReal[i] references the same point as RData[i].

### Running/Exploring the Program

 Download source Download  executable

### Suggestions for Further Explorations

???

 Original Date: October 28, 2007 Modified: May 15, 2018