Problem Description
Write a component to simplify the display of cutting
patterns for lengths of linear material.

Background & Techniques
I have written a version of the Cutting Stock
Problem (there will be a link here once the program is posted).
The problem is to figure out the best way to cut a set of required part
lengths from a set of available stock pieces of specified lengths and costs.
Depending on the application, the stock might be dimensional lumber,
pipe, wire, rolls of material to be slit, etc.
When I got around to display results from the
program I decided that a visual display would be the best, but most complex,
technique. Using the "divide and conquer" problem solving
method, this program defines the required components and a simpler
program to test them
Two new classes were developed,
- TRod is a TImage descendant
which simulate drawing a cylindrical shape divided into given lengths.
- TDisplayPattern is a TPanel
descendant and includes a TRod and two TLabel components.
TRod description
There are 5 public fields which the user may set:
- HWratio: the ratio of rod diameter to length; type
single; default 0.1;
- RodColor: the color of the rod; TColor; set by "Create"
- BGColor: the color for the area inside the control's
boundaries but outside of the rod; TColor;
set by "Create";
- Labels: Show lengths above each subdivision; Boolean; true.
- OpenLeft: Opening on the left end of the rod; Boolean; true.
Also three methods:
- constructor Create (proto:TImage; NewRodColor, NewBGColor:
TColor); Proto is the prototype image which provides left,
top, width, height, parent, and owner field information. NewRodColor
and NewBGColor provide rod color information.
- procedure SetLengths (Val:TRodLengths);{assign a set of rod
segment lengths}
- procedure Draw; Draws the rod.
TDisplayPattern description
The only public variable here is Rod, the TRod component, to
allow user modification of the public variables defined above.
There are two methods
- constructor create( Proto:TPanel); Proto is the
prototype TPanel which must contain a TImage and 2 TLabel controls.
The TImage becomes the prototype for the rod. One of the
TLabels,
which must have a Name or Caption field beginning with 'P', is intended
to display the pattern identification number for the pattern being
displayed. The other must have a name or captioned beginning with 'N',
and specifies the number of stock pieces to be cut including this pattern.
- procedure MakePattern specifies the array of rod segment
lengths and the "Pattern id" and "Number to cut" captions.
TestDrawRods program
The top button on the test program form draws two rods with random
segment pattern just to test the TRod component. The bottom part
of the form contains buttons to "Make a Pattern", "Set Rod color", and
"Clear all Displays". Each pattern created will be added to a
TScrollbox on the right side of the form.
Lessons learned or relearned
- Drawing on a TImage Canvas:
For years I had thought that the Height and Width properties of
Picture.Bitmap must be set before we could draw on an
image's canvas. This is no longer true if you draw on the TImage
Canvas property. References to TImage.canvas call GetCanvas which checks (and sets
if necessary) Picture.Bitmap.Height and Width.
- The arc command: Drawing the rod
uses the Arc procedure of the image's Canvas property.
Arc
requires 8 integer parameters to define the portion of an ellipse to be
drawn. These are four sets of (X,Y) coordinates. Two
sets define top left and bottom right extents of an ellipse. The
other two sets define the end the points of two imaginary line segments
from the center of the ellipse to points on or outside of the ellipse.
The intersection points of these lines with the ellipse define the start
and end points of the arc, always drawn in a counterclockwise direction.
.
- Adding entries to a Scrollbox: This one was new to me. The
TScrollBox control has the ability to vertically expand its virtual size
as necessary accommodate the objects placed on it. In
essence, the scroll box becomes a window into the virtual area which
moves down as you scroll up and up as you scroll down. However
the vertical coordinates for items inserted into a TScrollbox are
relative to the current top of this window (the Position
property of the vertical scroll bar). So, for example, to move a panel to
location 1000, we need to subtract the current VertScrollBar.position
value. (Top := 1000 - vertscrollbar.position;)
- Sorting an array: This is so easy to understand that no research is
needed to write one, and it can be coded from scratch quicker than you
could look one up. Here's the sort algorithm: In a
double loop, compare each element to those above it. If they are
out of order swap them. Search the U_TestRodDisplay
unit for "Sort" to see the 10 or so lines of code in the procedure,
- Memory leak checking: Memory
leaks, not releasing all of the memory allocated, is a common problem
when your code creates and releases objects or other dynamic structures.
Procedure AllocMemSize returns the bytes of memory currently
allocated. By placing the current value on a label or other text
display after key operations, memory leaks can be easily detected.
Fixing them may be a different matter. I noticed atin Delphi
2006, AllocMemSize has be "deprecated" which I assume means that
some improved facility is now available there.
Running/Exploring the Program
Suggestions for Further Explorations
???
| Original Date: March 13, 2007 |
Modified:
November 07, 2008 |
|