0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

図形を描く

Last updated at Posted at 2025-05-25

導入

Pharo で図形を描いてみます。Pharo は Smalltalk 処理系の一つですが、Smalltalk は Lisp 言語と LOGO 言語の影響を強く受けているオブジェクト指向言語です。LOGO のようにタートルを実装し、いろいろな図形を描いてみます。

FractalMorph クラス

まずは FractalMorph クラスからです。このクラスはタートルの機能を実装します。

BorderedMorph subclass: #FractalMorph
	instanceVariableNames: 'location angle'
	classVariableNames: ''
	package: 'PBE-Fractal'

FractalMorph は BorderedMorph のサブクラスとします。インスタンス変数は location と angle を持ちます。location はタートルの置き場所であり、angle はタートルが向いている方向を表します。タートルの向きの指定は度数法ですが、angle は弧度法(ラジアン)で持つようにします。

accessing プロトコルメソッド

インスタンス変数を参照するメソッド群を実装します。

angle
	^ angle
location
	^ location

drawing プロトコルメソッド

タートルを操作するメソッド群を実装します。回転するメソッドはタートルが回転するだけで線は描画しませんが、タートルが前進するメソッドは線を描画します。

forward: amountOfMovement
	| x y newLocation |
	x := angle cos * amountOfMovement.
	y := angle sin * amountOfMovement.
	newLocation := x @ y translateBy: self location.
	self
		addMorph:
			(LineMorph
				from: self location
				to: newLocation
				color: Color yellow
				width: 2).
	self location: newLocation
turnLeft: degree
	self turnRight: degree negated
turnRight: degree
	self angle: self angle + (2 * Float pi * degree / 360)

initializing プロトコルメソッド

自身のオブジェクトを初期化するメソッドを実装します。

initialize
	super initialize.
	self angle: 0.
	self location: self center

protected プロトコルメソッド

自身とサブクラスからのみ使用して欲しいメソッドを実装します。

angle: radian
	angle := radian
location: point
	location := point

overrides プロトコルメソッド

このプロトコル内にはオーバーライドしているメソッドが自動的にカテゴライズされます。これから図形を描画するサブクラスを実装しますが、そのサブクラスでオーバーライドされているメソッドも含みます。以下がオーバーライドされているメソッド群です。

angle
angle:
forward:
initialize
location
location:
turnLegt:
turnRight:

実際に図形を描画するオブジェクトを実装する。

FractalMorph オブジェクトだけでは図形は何も描画できません。具体的に図形を描画するオブジェクト(これを「特化」といいます)を実装していきます。

KochMorph

KochMorph は、コッホ曲線を描画するオブジェクトです。スーパークラスは先程実装した FractalMorph です。

FractalMorph subclass: #KochMorph
	instanceVariableNames: ''
	classVariableNames: ''
	package: 'PBE-Fractal'

drawing プロトコルメソッド

コッホ曲線を描画するメソッドを実装します。

drawKoch: n
	| nn |
	n > 7
		ifTrue: [ nn := n / 3.
			self drawKoch: nn.
			self turnLeft: 60.
			self drawKoch: nn.
			self turnLeft: -120.
			self drawKoch: nn.
			self turnLeft: 60.
			self drawKoch: nn ]
		ifFalse: [ self forward: 20 ]

initializing プロトコルメソッド

自身を初期化するメソッドです。

initialize
	super initialize.
	self extent: 800 @ 300.
	self location: 100 @ 200.
	self drawKoch: 100

実行

Playground で以下を do-it します。

KochMorph new openInWorld

こんな Morph を表示します。
koch.png

TriangleMorph

TriangleMorph は小さい三角形をたくさん描画して大きな三角形を描画ます。インスタンス変数に lengthOfSide を持ちます。描画する三角形の一辺の長さ持ちます。スーパークラスは FractalMorph です。

FractalMorph subclass: #TriangleMorph
	instanceVariableNames: 'lengthOfSide'
	classVariableNames: ''
	package: 'PBE-Fractal'

accessing プロトコルメソッド

インスタンス変数を参照するメソッド群を実装します。

halfLengthOfSide
	^(self lengthOfSide / 2) rounded
heightOfTriangle
	^ (self halfLengthOfSide * 3 sqrt) rounded
lengthOfSide
	^lengthOfSide
lengthOfSide: newLength
	lengthOfSide := newLength

constants プロトコルメソッド

三角形を何段にするかの定数値を持ちます。値は 5 となっているので五段の三角形を描画します。

stepOfTriangles
	^5

drawing プロトコルメソッド

三角形を描画するメソッドを実装します。

drawTriangle: topPoint
	self angle: 0.
	self location: topPoint.
	self turnRight: 60.
	self forward: self lengthOfSide.
	self turnRight: 120.
	self forward: self lengthOfSide.
	self turnRight: 120.
	self forward: self lengthOfSide
drawTriangleRec1: row top: aPoint 
	row = 0
		ifTrue: [ ^self ].
	self drawTriangleRec2: row top: aPoint.
	self drawTriangleRec1: row - 1 top: (aPoint x + self halfLengthOfSide) @ (aPoint y + self heightOfTriangle)
drawTriangleRec2: row top: aPoint 
	row = 0
		ifTrue: [ ^self ].
	self drawTriangle: aPoint.
	self drawTriangleRec2: row - 1 top: (aPoint x - self halfLengthOfSide) @ (aPoint y + self heightOfTriangle)

initializing プロトコルメソッド

初期化メソッドです。

initialize
	super initialize.
	self extent: 800 @ 800.
	self location: self center x @ 100.
	self lengthOfSide: 100.
	self drawTriangleRec1: self stepOfTriangles top: self location

実行

Playground で以下を do-it します。

TriangleMorph new openInWorld

こんな Morph を表示します。
tri.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?