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

 


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