procedure TDD31f1.buNorthClick(Sender: TObject); begin image1.canvas.moveto(75,150); image1.canvas.lineto(75,0) end; procedure TDD31f1.buEastClick(Sender: TObject); begin image1.canvas.moveto(150,75); image1.canvas.lineto(0,75) end;(Throughout, you might want to use "kMax" in place of 150, having put 150 into a variable or constant called kMax early in the program. If you adopt this, then you'd use kMax div 2 where ever you see 75, and 0 where ever you see 0.)
procedure buEastClick(Sender: TObject);...add...
procedure buDirClick(Sender: TObject);and, just before the program's terminal "end.", add...
procedure TDD31f1.buDirClick(Sender:TObject); begin if sender=buNorth then begin image1.canvas.moveto(75,150); image1.canvas.lineto(75,0) end; end;Run the program, then stop it again. (Delphi may need this for the Object Inspector to become aware of buDirClick)
procedure TDD31f1.buNorthClick(Sender: TObject); begin end;Run the program again. Try buNorth. You should see what you saw before. When you quit the program, and go back to editing it, all traces of buNorthClcik should have been cleared away by Delphi's wonderful RAD environment.
baX,baY:array[0..15]of byte;... just after the
private { Private declarations }...near the start of the program.
image1.canvas.moveto(0,0); baX[0]:=75;baY[0]:=0; baX[4]:=150;baY[4]:=75; baX[8]:=75;baY[8]:=150; baX[12]:=0;baY[12]:=75;(The first line should clear the previous annoyance of the image not appearing until the first line is drawn.)
if sender=buNorth then begin image1.canvas.moveto(baX[8],baY[8]); image1.canvas.lineto(baX[0],baY[0]) end; if sender=buEast then begin image1.canvas.moveto(baX[12],baY[12]); image1.canvas.lineto(baX[4],baY[4]) end;Make the first three lines of buDirClick...
procedure TDD31f1.buDirClick(Sender:TObject); begin image1.canvas.pen.width:=1; image1.canvas.ellipse(0,0,150,150); image1.canvas.pen.width:=4;This will cause prior lines to be erased before the most recently requested line is drawn. (The two pen.width lines are not essential to the line clearing, but they improve the overall result.)
with image1.canvas do begin brush.color:=clBtnFace; pen.color:=clBtnFace; rectangle(0,0,150,150); brush.color:=clRed; pen.color:=clBlack; ellipse(0,0,150,150); moveto(0,0); end;(*with...*)That covers MOST of the underlying principles involved in this tutorial. Take a break, have a cup of coffee.
procedure TDD31f1.buDirClick(Sender:TObject); var bTmp:byte; begin bTmp:=((sender as tbutton).tag); image1.canvas.pen.width:=1; image1.canvas.ellipse(0,0,150,150); image1.canvas.pen.width:=4; image1.canvas.moveto(baX[bTmp+8],baY[bTmp+8]); image1.canvas.lineto(baX[bTmp],baY[bTmp]) end;(*buDirClick*)... and we're going to extend this program to be able to show 16 directions, with very little extra code in buDirClick!! I said we could be elegant!
baX[2]:=127;bay[2]:=27; baX[10]:=27;bay[10]:=127;Now for "arrowheads"... of a sort...
baX,baY,baX2,baY2:array[0..15]of byte;.. and to FormCreate, add
baX2[0]:=75;baY2[0]:=10; baX2[2]:=122;baY2[2]:=32; baX2[4]:=140;baY2[4]:=75;...and make buDirClick...
procedure TDD31f1.buDirClick(Sender:TObject); var bTmp:byte; begin bTmp:=((sender as tbutton).tag); image1.canvas.pen.width:=1; image1.canvas.ellipse(0,0,150,150); image1.canvas.pen.width:=4; image1.canvas.moveto(baX[bTmp+8],baY[bTmp+8]); image1.canvas.lineto(baX[bTmp],baY[bTmp]); image1.canvas.pen.width:=12; image1.canvas.lineto(baX2[bTmp],baY2[bTmp]); end;(*buDirClick*)(which only means adding 2 lines, if you did the first "pen" lines earlier)
baX2[8]:=75;baY2[8]:=140;Alter buDirClick as follows. Much is unchanged, but I've quoted it all to avoid problems...
procedure TDD31f1.buDirClick(Sender:TObject); var bTmp:byte; begin bTmp:=((sender as tbutton).tag); image1.canvas.pen.width:=1; image1.canvas.ellipse(0,0,150,150); image1.canvas.pen.width:=4; if bTmp<8 then begin image1.canvas.moveto(baX[bTmp+8],baY[bTmp+8]); image1.canvas.lineto(baX[bTmp],baY[bTmp]); image1.canvas.pen.width:=12; image1.canvas.lineto(baX2[bTmp],baY2[bTmp]); end (*no ; here*) else begin image1.canvas.moveto(baX[bTmp-8],baY[bTmp-8]); image1.canvas.lineto(baX[bTmp],baY[bTmp]); image1.canvas.pen.width:=12; image1.canvas.lineto(baX2[bTmp],baY2[bTmp]); end;(*of else*) end;(*buDirClick*)We're really doing little beyond what we were doing before the coffee break... it just looks hard because elements have become abstract.
kArrowLength,kPenFudge,kEighthFudge, bTmpX,bTmpY:byte;kPenFudge is used to slightly shorten the lines, so that the outside edge of the line is still inside the circle drawn.
kWidthHeight:=150;(*This and next: to make doing other sizes easy*) kRadius:=kWidthHeight div 2; kCentX:=kRadius;kCentY:=kRadius; kArrowLength:=10; (*Constants for N,E,S,W*) baX[0]:=kRadius;baY[0]:=0; baX2[0]:=baX[0];baY2[0]:=baY[0]+kArrowLength; baX[4]:=kWidthHeight;baY[4]:=kRadius; baX2[4]:=baX[4]-kArrowLength;baY2[4]:=baY[4]; baX[8]:=kRadius;baY[8]:=kWidthHeight; baX2[8]:=baX[8];baY2[8]:=baY[8]-kArrowLength; baX[12]:=0;baY[12]:=kRadius; baX2[12]:=baX[12]+kArrowLength;baY2[12]:=baY[12]; (*Constants for NE,SE,SW,NW*) kPenFudge:=4; (*If you are using a "fat" pen for the "arrow" part of the line, "ink" spills outside of the circle. Adjust the size of kPenFudge to overcome this. (Increase kPenFudge if you are experiencing overspill after changing the arrow width.)*) bTmpX:=trunc(cos(pi/4)*kRadius)-kPenFudge; bTmpY:=trunc(sin(pi/4)*kRadius)-kPenFudge; (*Yes, we'll need two variables... later*) baX[2]:=kCentX+bTmpX;baY[2]:=kCentY-bTmpY; baX2[2]:=baX[2]-kArrowLength;baY2[2]:=baY[2]+kArrowLength; baX[10]:=kCentX-bTmpX;baY[10]:=kCentY+bTmpY; baX2[10]:=baX[10]+kArrowLength;baY2[10]:=baY[10]-kArrowLength; baX[6]:=kCentX+bTmpX;baY[6]:=kCentY+bTmpY; baX2[6]:=baX[6]-kArrowLength;baY2[6]:=baY[6]-kArrowLength; baX[14]:=kCentX-bTmpX;baY[14]:=kCentY-bTmpY; baX2[14]:=baX[14]+kArrowLength;baY2[14]:=baY[14]+kArrowLength; (*Constants for NNE,ENE,ESE,SSE,SSW,WSW,WNWnNNW*) kPenFudge:=4; (*If you are using a "fat" pen for the "arrow" part of the line, "ink" spills outside of the circle. Adjust the size of kPenFudge to overcome this. (Increase kPenFudge if you are experiencing overspill after changing the arrow width.)*) kEighthFudge:=7; (*This is used to "twist" the arrowheads slightly for directions 1,3,5,7,9,11,13,and 15, i.e. NNE,ENE, etc *) bTmpX:=trunc(cos(pi/8)*kRadius)-kPenFudge; bTmpY:=trunc(sin(pi/8)*kRadius)-kPenFudge; {showmessage(inttostr(bTmpX)+' '+inttostr(bTmpY));} baX[1]:=kCentX+bTmpY;baY[1]:=kCentY-bTmpX; baX2[1]:=baX[1]-kArrowLength+kEighthFudge; baY2[1]:=baY[1]+kArrowLength; baX[9]:=kCentX-bTmpY;baY[9]:=kCentY+bTmpX; baX2[9]:=baX[9]+kArrowLength-kEighthFudge; baY2[9]:=baY[9]-kArrowLength; baX[7]:=kCentX+bTmpY;baY[7]:=kCentY+bTmpX; baX2[7]:=baX[7]-kArrowLength+kEighthFudge; baY2[7]:=baY[7]-kArrowLength; baX[15]:=kCentX-bTmpY;baY[15]:=kCentY-bTmpX; baX2[15]:=baX[15]+kArrowLength-kEighthFudge; baY2[15]:=baY[15]+kArrowLength; baX[3]:=kCentX+bTmpX;baY[3]:=kCentY-bTmpY; baX2[3]:=baX[3]-kArrowLength; baY2[3]:=baY[3]+kArrowLength-kEighthFudge; baX[11]:=kCentX-bTmpX;baY[11]:=kCentY+bTmpY; baX2[11]:=baX[11]+kArrowLength; baY2[11]:=baY[11]-kArrowLength+kEighthFudge; baX[5]:=kCentX+bTmpX;baY[5]:=kCentY+bTmpY; baX2[5]:=baX[5]-kArrowLength; baY2[5]:=baY[5]-kArrowLength+kEighthFudge; baX[13]:=kCentX-bTmpX;baY[13]:=kCentY-bTmpY; baX2[13]:=baX[13]+kArrowLength; baY2[13]:=baY[13]+kArrowLength-kEighthFudge;That's it! The program is done! (There are some lovely symmetries in the block of code just presented. Not "important", but you might enjoy them, if you enjoy mathematical beauties.)
|
Page WILL BE tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org
....... P a g e . . . E n d s .....