https://trans.onionmixer.net/mediawiki/index.php?title=Smalltalk80LanguageImplementation:Chapter_19&feed=atom&action=historySmalltalk80LanguageImplementation:Chapter 19 - Revision history2024-03-28T15:57:04ZRevision history for this page on the wikiMediaWiki 1.38.1https://trans.onionmixer.net/mediawiki/index.php?title=Smalltalk80LanguageImplementation:Chapter_19&diff=4893&oldid=prevOnionmixer: 오타수정2015-07-13T02:30:54Z<p>오타수정</p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 02:30, 13 July 2015</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l525">Line 525:</td>
<td colspan="2" class="diff-lineno">Line 525:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td class="diff-marker" data-marker="−"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>❏ Additional Protocol for Commander Pen An expanded description of Commander adds to Commander each message of the protocol of class Pen whose behavior changes position or orientation. This additional protocol supports the ability to send messages that are part of Pen's protocol to the Commander. Each such message is implemented as broadcasting the message to the elements of the collection. In this way, messages to Commander take the same form as messages to any Pen, rather than that of a do: message. With the class defined in this way, drawing sequences to a Commander appear more like drawing sequences to a Pen. Moreover, all the Pens commanded by a Commander draw in parallel; for example, all the spirals of Figures 19.6 or 19.7 would grow at once.</div></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> </div></td></tr>
<tr><td colspan="2" class="diff-side-deleted"></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>❏ Additional Protocol for Commander Pen</div></td></tr>
<tr><td colspan="2" class="diff-side-deleted"></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> </div></td></tr>
<tr><td colspan="2" class="diff-side-deleted"></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> </div></td></tr>
<tr><td colspan="2" class="diff-side-deleted"></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>An expanded description of Commander adds to Commander each message of the protocol of class Pen whose behavior changes position or orientation. This additional protocol supports the ability to send messages that are part of Pen's protocol to the Commander. Each such message is implemented as broadcasting the message to the elements of the collection. In this way, messages to Commander take the same form as messages to any Pen, rather than that of a do: message. With the class defined in this way, drawing sequences to a Commander appear more like drawing sequences to a Pen. Moreover, all the Pens commanded by a Commander draw in parallel; for example, all the spirals of Figures 19.6 or 19.7 would grow at once.</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>[[image:Smalltalk80LanguageImplementation_19-7.png|그림 19-7]]</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>[[image:Smalltalk80LanguageImplementation_19-7.png|그림 19-7]]</div></td></tr>
</table>Onionmixerhttps://trans.onionmixer.net/mediawiki/index.php?title=Smalltalk80LanguageImplementation:Chapter_19&diff=4892&oldid=prevOnionmixer: 정오표 수정2014-05-09T09:36:00Z<p>정오표 수정</p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 09:36, 9 May 2014</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l492">Line 492:</td>
<td colspan="2" class="diff-lineno">Line 492:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> [ :index |</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> [ :index |</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> (self at: index) turn: (index -1) * (360 / self size)]</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> (self at: index) turn: (index -1) * (360 / self size)]</div></td></tr>
<tr><td class="diff-marker" data-marker="−"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div> lineUpFrom: startPoint to: <del style="font-weight: bold; text-decoration: none;">endPotint</del></div></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div> lineUpFrom: startPoint to: <ins style="font-weight: bold; text-decoration: none;">endPoint</ins></div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> 1 to: self size do:</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> 1 to: self size do:</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> [ :index |</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> [ :index |</div></td></tr>
</table>Onionmixerhttps://trans.onionmixer.net/mediawiki/index.php?title=Smalltalk80LanguageImplementation:Chapter_19&diff=4891&oldid=prevOnionmixer: SMALLTALK80 Chapter 19 Pens 페이지 추가2014-04-28T10:35:02Z<p>SMALLTALK80 Chapter 19 Pens 페이지 추가</p>
<p><b>New page</b></p><div>;Chapter 19 Pens<br />
<br />
==Pens==<br />
<br />
<syntaxhighlight lang="text"><br />
Object<br />
<br />
Magnitude<br />
Character<br />
Date<br />
Time<br />
<br />
Number<br />
Float<br />
Fraction<br />
Integer<br />
LargeNegativeInteger<br />
LargePositiveInteger<br />
SmallInteger<br />
<br />
LookupKey<br />
Association<br />
<br />
Link<br />
<br />
Process<br />
<br />
Collection<br />
<br />
SequenceableCollection<br />
LinkedList<br />
<br />
Semaphore<br />
<br />
ArrayedCollection<br />
Array<br />
<br />
Bitmap<br />
DisplayBitmap<br />
<br />
RunArray<br />
String<br />
Symbol<br />
Text<br />
ByteArray<br />
<br />
Interval<br />
OrderedCollection<br />
SortedCollection<br />
Bag<br />
MappedCollection<br />
Set<br />
Dictionary<br />
IdentifyDictionary<br />
<br />
Stream<br />
PositionableStream<br />
ReadStream<br />
WriteStream<br />
ReadWriteStream<br />
ExternalStream<br />
FileStream<br />
<br />
Random<br />
<br />
File<br />
FileDirectory<br />
FilePage<br />
<br />
UndefinedObject<br />
Boolean<br />
False<br />
True<br />
<br />
ProcessorScheduler<br />
Delay<br />
SharedQueue<br />
<br />
Behavior<br />
ClassDescription<br />
Class<br />
MetaClass<br />
<br />
Point<br />
Rectangle<br />
BitBit<br />
CharacterScanner<br />
<br />
Pen***<br />
<br />
DisplayObject<br />
DisplayMedium<br />
Form<br />
Cursor<br />
DisplayScreen<br />
InfiniteForm<br />
OpaqueForm<br />
Path<br />
Arc<br />
Circle<br />
Curve<br />
Line<br />
LinearFit<br />
Spline<br />
</syntaxhighlight><br />
<br />
<br />
As explained in the previous chapter, Forms represent images. Lines can be created by copying a Form to several locations in another Form at incremental distances between two designated points. Higher-level access to line drawing is provided by instances of class Pen.<br />
<br />
<br />
Pen is a subclass of BitBlt. As such, it is a holder for source and destination Forms. The source Form can be colored black or white or different tones of gray, and copied into the destination Form with different combination rules, different halftone masks, and with respect to different clipping rectangles. The source Form is the Pen's writing tool or nib. The destination Form is the Pen's writing surface; it is usually the Form representing the display screen.<br />
<br />
<br />
In addition to the implementations inherited from BitBlt,a Pen has a Point that indicates a position on the display screen and a Number that indicates a direction in which the Pen moves. A Pen understands messages that cause it to change its position or direction. When its position changes, the Pen can leave a copy of its Form at its former position. By moving the Pen to different screen positions and copying its Form to one or more of these positions, graphic designs are created.<br />
<br />
<br />
Several programming systems provide this kind of access to line drawing. In these systems, the line drawer is typically called a "turtle" after the one first provided in the MIT/BBN Logo language (Seymour Papert, MindStorms: Children, Computers and Powerful Ideas, Basic Books, 1980; Harold Abelson and Andrea diSessa, Turtle Geometry: The Computer as a Medium for Exploring Mathematics, MIT Press, 1981). The protocol for Pens supports messages that are like the turtle commands provided in Logo. These consist of commands for telling the turtle to go some distance, turn some amount, to place a pen in a down position, and to place a pen in an up position. When the pen is down and it moves, a trace of the turtle's path is created. The corresponding Pen messages are go: distance, turn: amount, down, and up. <br />
<br />
<br />
Multiple Pens can be created and their movement on the screen coordinated so that the process of creating a graphical design can itself be graphically pleasing. The next section contains the protocol that is provided in class Pen. Subsequent sections give examples of designs that can be created by sending messages to Pens.<br />
<br />
<br />
<br />
===Class Pen===<br />
<br />
Instances of class Pen are created by sending Pen the message new. A Pen created this way can draw anywhere on the display screen; its initial position is the center of the screen, facing in a direction towards the top of the screen. The Pen is set to draw (i.e., it is down) with a source Form or nib that is a 1 by 1 black dot.<br />
<br />
<br />
There are two ways to change the source Form of a Pen. One way is to send the Pen the message defaultNib: widthInteger. The other way is to reset the source Form by sending the Pen the messages it inherits from its superclass, BitBlt. For example, the message sourceForm: changes the source form, or the message mask: changes the halftone form (the mask) used in displaying the source form. (Note that the default mask for displaying is black.)<br />
<br />
{| style="border: 1px solid black;"<br />
|- style="color: white; background-color: black;"<br />
| colspan="2" |initialize-release<br />
|- style="vertical-align:top;"<br />
|defaultNib: shape||A "nib" is the tip of a pen. This is an easy way to set up a default pen. The Form for the receiver is a rectangular shape with height and width equal to (1) the argument, shape, if shape is an Integer; or (2) the coordinates of shape if shape is a Point.<br />
|- style="color: black; background-color: gray;"<br />
| colspan="2" |Pen instance protocol<br />
|}<br />
<br />
<br />
Thus<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic ← Pen new defaultNib: 2<br />
</syntaxhighlight><br />
<br />
<br />
creates a Pen with a black Form that is 2 bits wide by 2 bits high.<br />
<br />
<br />
The accessing protocol for a Pen provides access to the Pen's current direction, location, and drawing region. The drawing region is referred to as the Pen's frame.<br />
<br />
{| style="border: 1px solid black;"<br />
|- style="color: white; background-color: black;"<br />
| colspan="2" |accessing<br />
|- style="vertical-align:top;"<br />
|direction||Answer the receiver's current direction. 270 is towards the top of the screen.<br />
|- style="vertical-align:top;"<br />
|location||Answer the receiver's current location.<br />
|- style="vertical-align:top;"<br />
|frame||Answer the Rectangle in which the receiver can draw.<br />
|- style="vertical-align:top;"<br />
|frame: aRectangle||Set the Rectangle in which the receiver can draw to be the argument, aRectangle.<br />
|- style="color: black; background-color: gray;"<br />
| colspan="2" |Pen instance protocol<br />
|}<br />
<br />
<br />
Continuing to use the example, bic, and assuming that the display screen is 600 bits wide and 800 bits high, we have<br />
<br />
{| style="border: 1px solid black;"<br />
|- style="color: white; background-color: black;"<br />
|'''expression'''||'''result'''<br />
|- style="vertical-align:top;"<br />
|bic direction||270<br />
|- style="vertical-align:top;"<br />
|bic location||300@400<br />
|- style="vertical-align:top;"<br />
|bic frame:(50@50 extent: 200@200)<br />
|- style="vertical-align:top;"<br />
|bic location||300@400<br />
|}<br />
<br />
<br />
Notice that when the Pen direction is towards the top of the display screen, the angle is 270 degrees. Notice also that the Pen is currently outside its drawing region and would have to be placed within the Rectangle, 50@ 50 corner: 250 @250, before any of its marks could be seen.<br />
<br />
<br />
The "turtle" drawing commands alter the Pen's drawing state, orient its drawing direction, and reposition it.<br />
<br />
{| style="border: 1px solid black;"<br />
|- style="color: white; background-color: black;"<br />
| colspan="2" |moving<br />
|- style="vertical-align:top;"<br />
|down||Set the state of the receiver to "down" so that it leaves marks when it move.<br />
|- style="vertical-align:top;"<br />
|up||Set the state of the receiver to "up" so that it does not leave marks when it moves.<br />
|- style="vertical-align:top;"<br />
|turn: degrees||Change the direction that the receiver faces by an amount equal to the argument, degrees.<br />
|- style="vertical-align:top;"<br />
|north||Set the receiver's direction to facing toward the top of the display screen.<br />
|- style="vertical-align:top;"<br />
|go: distance||Move the receiver in its current direction a number of bits equal to the argument, distance. If the receiver status is "down," a line will be drawn using the receiver's Form as the shape of the drawing brush.<br />
|- style="vertical-align:top;"<br />
|goto: aPoint||Move the receiver to position aPoint. If the receiver status is "down", a line will be drawn from the current position to the new one using the receiver's Form as the shape of the drawing brush. The receiver's direction does not change.<br />
|- style="vertical-align:top;"<br />
|place: aPoint||Set the receiver at position aPoint. No lines are drawn.<br />
|- style="vertical-align:top;"<br />
|home||Place the receiver at the center of the region in which it can draw.<br />
|- style="color: black; background-color: gray;"<br />
| colspan="2" |Pen instance protocol<br />
|}<br />
<br />
<br />
Thus we can place bic in the center of its frame by evaluating the expression<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic home<br />
</syntaxhighlight><br />
<br />
<br />
If we then ask<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic location<br />
</syntaxhighlight><br />
<br />
<br />
the response would be 150 @150.<br />
<br />
<br />
Suppose that we drew a line with a Pen and then decided that we wanted to erase it. If the line had been drawn with a black Form, then we can erase it by drawing over it with a white Form of at least the same size. Thus<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic go: 100<br />
</syntaxhighlight><br />
<br />
<br />
draws the black line. Then<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic white<br />
</syntaxhighlight><br />
<br />
<br />
sets the drawing mask to be all white (the message white is inherited from the protocol of BitBlt), and then<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic go: -100<br />
</syntaxhighlight><br />
<br />
<br />
draws over the original line, erasing it.<br />
<br />
<br />
An exercise that is common in the Logo examples is to create various polygon shapes, such as a square.<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
4 timesRepeat: [bic go: 100. bic turn: 90]<br />
</syntaxhighlight><br />
<br />
<br />
The following expression creates any polygon shape by computing the angle of turning as a function of the number of sides. If nSides is the number of sides of the desired polygon, then<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
nSides timesRepeat: [bic go: 100. bic turn: 360 // nSides]<br />
</syntaxhighlight><br />
<br />
<br />
will draw the polygon. We can create a class Polygon whose instances refer to the number of sides and length of each side. In addition, each Polygon has its own Pen for drawing. In the definition that follows, we specify that a Polygon can be told to draw on the display screen; the method is the one described earlier.<br />
<br />
{| style="border: 0px solid black;"<br />
|- style="vertical-align:top;"<br />
|class name||Polygon<br />
|- style="vertical-align:top;"<br />
|superclass||Object<br />
|- style="vertical-align:top;"<br />
|instance variable names||drawingPen<br>nSides<br>length<br />
|- style="vertical-align:top;"<br />
|class methods<br />
|<syntaxhighlight lang="smalltalk"><br />
instance creation<br />
new<br />
↑super new default<br />
</syntaxhighlight><br />
|- style="vertical-align:top;"<br />
|instance methods<br />
|<syntaxhighlight lang="smalltalk"><br />
drawing<br />
draw<br />
drawingPen black.<br />
nSides timesRepeat: [drawingPen go: length; turn: 360 // nSides]<br />
accessing<br />
length: n<br />
length ← n<br />
sides: n<br />
nSides ← n<br />
private<br />
default<br />
drawingPen ← Pen new.<br />
self length: 100.<br />
self sides: 4<br />
</syntaxhighlight><br />
|}<br />
<br />
<br />
Then a Polygon can be created and a sequence of polygons drawn by evaluating the expressions<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
poly ← Polygon new.<br />
3 to: 10 do: [ :sides | poly sides: sides. poly draw]<br />
</syntaxhighlight><br />
<br />
<br />
The result is shown in Figure 19.1.<br />
<br />
[[image:Smalltalk80LanguageImplementation_19-1.png|640px|그림 19-1]]<br />
<br />
<br />
<br />
==Geometric Designs==<br />
<br />
The Logo books mentioned earlier provide extensive examples of how to use this kind of access to line drawing in order to create images on a computer display screen. We provide several examples of methods that can be added to a Pen so that any Pen can draw a geometric design such as those shown in Figures 19.2 19.5. (Note: These methods are in the system as part of the description of Pen so that users can play with creating geometric designs.)<br />
<br />
===Spirals===<br />
<br />
The first design is called a spiral.A spiral is created by having the Pen draw incrementally longer lines; after each line is drawn, the Pen turns some amount. The lines drawn begin at length 1 and increase by 1 each time until reaching a length equal to the first argument of the message spiral:angle:. The second argument of the message is the amount the Pen turns after drawing each line.<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
spiral: n angle: a<br />
1 to: n do:<br />
[ :i | self go: i. self turn: a]<br />
</syntaxhighlight><br />
<br />
<br />
Each of the lines in Figure 19.2 was drawn by sending bic the message spiral:angle:, as follows.<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic spiral: 150 angle: 89<br />
</syntaxhighlight><br />
<br />
[[image:Smalltalk80LanguageImplementation_19-2a.png|320px|그림 19-2a]]<br />
<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic spiral: 150 angle: 91<br />
</syntaxhighlight><br />
<br />
[[image:Smalltalk80LanguageImplementation_19-2b.png|320px|그림 19-2b]]<br />
<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic spiral: 150 angle: 121<br />
</syntaxhighlight><br />
<br />
[[image:Smalltalk80LanguageImplementation_19-2c.png|320px|그림 19-2c]]<br />
<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic home.<br />
bic spiral: 150 angle: 89.<br />
bic home.<br />
bic spiral: 150 angle:91<br />
</syntaxhighlight><br />
<br />
[[image:Smalltalk80LanguageImplementation_19-2d.png|320px|그림 19-2d]]<br />
<br />
<br />
<br />
===Dragon Curve===<br />
<br />
Figure 19.3 is an image of a "dragon curve" of order 8 which was drawn in the middle of the screen by evaluating the expression<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic ← Pen new defaultNib: 4.<br />
bic dragon: 9<br />
</syntaxhighlight><br />
<br />
<br />
The method associated with the message dragon: in class Pen is<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
dragon: n<br />
n = 0<br />
ifTrue: [self go: 10]<br />
ifFalse:<br />
[n > 0<br />
ifTrue:<br />
[self dragon: n - 1.<br />
self turn: 90.<br />
self dragon: 1 - n]<br />
ifFalse:<br />
[self dragon: -1 - n.<br />
self turn: -90.<br />
self dragon: 1 + n]]<br />
</syntaxhighlight><br />
<br />
[[image:Smalltalk80LanguageImplementation_19-3.png|그림 19-3]]<br />
<br />
<br />
Dragon curves were discussed by Martin Gardner in his mathematical games column in Scientific American (March 1967, p. 124, and April 1967, p. 119). Another discussion of dragon curves appears in Donald Knuth and Chandler Davis, "Number Representations and Dragon Curves," Journal of Recreation Mathematics, Vol. 3, 1970, pp. 66-81 and 133-149. <br />
<br />
<br />
<br />
===Hilbert Curve===<br />
<br />
Figure 19.4 is a space-filling curve attributed to the mathematician David Hilbert. A space-filling curve has an index; as the index increases to infinity, the curve tends to cover the points in a plane. The example is the result of evaluating the expression<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
Pen new hilbert: 5 side: 8<br />
</syntaxhighlight><br />
<br />
<br />
The index for the example is 5; at each point, a line 8 pixels long is drawn. The corresponding method for the message hilbert:side is<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
hilbert: n side: s<br />
| a m |<br />
n = 0 ifTrue: [↑self turn: 180].<br />
n > 0 ifTrue: [a ← 90.<br />
m < - n - 1]<br />
ifFalse: [a ← -90.<br />
m ← n + 1].<br />
self turn: a.<br />
self hilbert: 0 - m side: s.<br />
self turn: a.<br />
self go: s.<br />
self hilbert: m side: s.<br />
self turn: 0 - a.<br />
self go: s.<br />
self turn: 0 - a<br />
self hilbert: m side: s.<br />
self go: s.<br />
self turn: a.<br />
self hilbert: 0 - m side: s.<br />
self turn: a<br />
</syntaxhighlight><br />
<br />
[[image:Smalltalk80LanguageImplementation_19-4.png|640px|그림 19-4]]<br />
<br />
<br />
Hilbert curve, where the source form is a different shape, creates a nice effect. Suppose the Form is three dots in a row; this is a system cursor referred to as wait. The image in Figure 19.5 was created by evaluating the expressions<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic ← Pen new sourceForm: Cursor wait.<br />
bic combinationRule: Form under.<br />
bic hilbert: 4 side: 16<br />
</syntaxhighlight><br />
<br />
[[image:Smalltalk80LanguageImplementation_19-5.png|640px|그림 19-5]]<br />
<br />
<br />
Expressions Cursor wait and Form under access a Form and a combination rule, respectively, that are constants in the system and that are known to the named classes. Other such constants are listed in a section of the next chapter. The messages sourceForm: and combinationRule: are inherited by Pens from their superclass BitBlt.<br />
<br />
<br />
<br />
===Commander Pen===<br />
<br />
The next example is shown in Figure 19.6. Although we can not show the process by which the design was created, it is a nice example for the reader to try. The basic idea is to create an object that controls several Pens and coordinates their drawing a design. We call the class of this kind of object, Commander. A Commander is an array of Pens. Pens controlled by a Commander can be given directions by having the Commander enumerate each Pen and evaluate a block containing Pen commands. So if a Commander's Pens should each go: 100, for example, then the Commander can be sent the message<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
do: [ :eachPen | eachPen go: 100]<br />
</syntaxhighlight><br />
<br />
<br />
A Commander also responds to messages to arrange its Pens so that interesting designs based on symmetries can be created. The two messages given in the description of Commander shown next are fanOut and lineUpFrom: startPoint to: endPoint. The first message arranges the Pens so that their angles are evenly distributed around 360 degrees. A Commander's Pens can be positioned evenly along a line using the message lineUpFrom:to:, where the arguments define the end points of the line.<br />
<br />
<br />
A description for Commander follows. The message new: is redefined so that Pens are stored in each element of the Array.<br />
<br />
{| style="border: 0px solid black;"<br />
|- style="vertical-align:top;"<br />
|class name||Commander<br />
|- style="vertical-align:top;"<br />
|superclass||Array<br />
|- style="vertical-align:top;"<br />
|class methods<br />
|<syntaxhighlight lang="smalltalk"><br />
instance creation<br />
new: numberOfPens<br />
| newCommander |<br />
newCommander ← super new: numberOfPens.<br />
1 to: numberOfPens do:<br />
[ :index | newCommander at: index put: Pen new].<br />
↑newCommander<br />
</syntaxhighlight><br />
|- style="vertical-align:top;"<br />
|instance methods<br />
|<syntaxhighlight lang="smalltalk"><br />
distributing<br />
fanOut<br />
1 to: self size do:<br />
[ :index |<br />
(self at: index) turn: (index -1) * (360 / self size)]<br />
lineUpFrom: startPoint to: endPotint<br />
1 to: self size do:<br />
[ :index |<br />
(self at: index)<br />
place: startPoint + (stopPoint - startPoint * (index -1) / (self size - 1))]<br />
</syntaxhighlight><br />
|}<br />
<br />
<br />
The methods are useful examples of sending messages to instances of class Point. The image in Figure 19.6 was drawn by evaluating the expressions<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic ← Commander new: 4.<br />
bic fanOut<br />
bic do: [ :eachPen | eachPen up. eachPen go: 100. eachPen down].<br />
bic do: [ : eachPen | eachPen spiral: 200 angle: 121]<br />
</syntaxhighlight><br />
<br />
<br />
The message do: to a Commander is inherited from its Collection superclass.<br />
<br />
[[image:Smalltalk80LanguageImplementation_19-6.png|640px|그림 19-6]]<br />
<br />
<br />
Another example of the use of a Commander is given in Figure 19.7. This image was created by using the message lineUpFrom:to:. It is a simple sequence of spirals arranged along a line at an angle, created by evaluating the expressions<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic ← Commander new: 6.<br />
bic lineUpFrom: (300@150) to: (300@500).<br />
bic do: [ :eachPen | eachPen spiral: 200 angle: 121]<br />
</syntaxhighlight><br />
<br />
<br />
❏ Additional Protocol for Commander Pen An expanded description of Commander adds to Commander each message of the protocol of class Pen whose behavior changes position or orientation. This additional protocol supports the ability to send messages that are part of Pen's protocol to the Commander. Each such message is implemented as broadcasting the message to the elements of the collection. In this way, messages to Commander take the same form as messages to any Pen, rather than that of a do: message. With the class defined in this way, drawing sequences to a Commander appear more like drawing sequences to a Pen. Moreover, all the Pens commanded by a Commander draw in parallel; for example, all the spirals of Figures 19.6 or 19.7 would grow at once.<br />
<br />
[[image:Smalltalk80LanguageImplementation_19-7.png|그림 19-7]]<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
down<br />
self do: [ :each | each down]<br />
up<br />
self do: [ :each | each up]<br />
turn: degrees<br />
self do: [ :each | each turn: degrees]<br />
north<br />
self do: [ :each | each north]<br />
go: distance<br />
self do: [ :each | each go: distance]<br />
goto: aPoint<br />
self do: [ :each | each goto: aPoint]<br />
place: aPoint<br />
self do: [ :each | each place: aPoint]<br />
home<br />
self do: [ :each | each home]<br />
spiral: n angle: a<br />
1 to: n do:<br />
[ :i | self go: i. self turn: a]<br />
</syntaxhighlight><br />
<br />
<br />
<br />
With this additional protocol, Figure 19.6 can be drawn by evaluating the expressions<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic ← Commander new: 4.<br />
bic fanOut.<br />
bic up.<br />
bic go: 100.<br />
bic down.<br />
bic spiral: 200 angle: 121<br />
</syntaxhighlight><br />
<br />
<br />
and Figure 19.7 by the expressions<br />
<br />
<syntaxhighlight lang="smalltalk"><br />
bic ← Commander new: 6.<br />
bic lineUpFrom: (300@150) to: (300@500).<br />
bic spiral: 200 angle: 121<br />
</syntaxhighlight><br />
<br />
<br />
<br />
==Notes==<br />
<references /><br />
<br />
[[Category:Smalltalk80LanguageImplementation]]</div>Onionmixer