Integer vs. Real Image Rotation

[Home]   [Puzzles & Projects]    [Delphi Techniques]   [Math topics]   [Library]   [Utilities]




Search WWW


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.

Mensa® 365 Puzzlers  Calendar 2017

Mensa® 365 Puzzlers Calendar 2018

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


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

Search 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.


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:

bulletAs 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.
bulletProperties 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.
bulletIndexed 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 

bullet Download source
bullet Download  executable

Suggestions for Further Explorations



Original Date: October 28, 2007

Modified: May 15, 2018


  [Feedback]   [Newsletters (subscribe/view)] [About me]
Copyright © 2000-2018, Gary Darby    All rights reserved.