420 Views
January 26, 22
スライド概要
Scheme プログラミング
URL: https://www.kkaneko.jp/pro/scheme/index.html
金子邦彦研究室
URL: https://www.kkaneko.jp/index.html
金子邦彦(かねこくにひこ) 福山大学・工学部・教授 ホームページ: https://www.kkaneko.jp/index.html 金子邦彦 YouTube チャンネル: https://youtube.com/user/kunihikokaneko
sp-11. 構造体とグラフィックス (Scheme プログラミング) URL: https://www.kkaneko.jp/pro/scheme/index.html 金子邦彦 1
アウトライン 11-1 define による変数定義 11-2 DrScheme でのグラフィックス 11-3 パソコン演習 11-4 課題 2
11-1 define による変数定義 3
変数 • 変数には,名前,値がある 名前 値 例)(define PI 3.14) (define A (list 15 8 6)) 4
リストの変数定義 (define A (list 15 8 6)) 変数名 リストの本体 5
変数とは • 「オブジェクト」に名前を付けたもの • オブジェクトとは,数値,文字列,リス トなど.「値」を持つ • コンピュータは,変数の値と名前の関 係を記憶している 6
11-2 DrScheme でのグラフィックス 7
DrScheme でのグラフィックス • DrScheme のグラフィックス機能である draw.ss teachpack • • • • • start: draw-solid-line: 線 draw-solid-rect: draw-solid-disk: clear-solid-disk: す • draw-circle: • stop: 「描画用ウインドウ」を開く 四角形 塗りつぶされた円 一度描いた「塗りつぶされた円」を消 円 「描画用ウインドウ」を閉じる 8
11-3 パソコン演習 9
パソコン演習の進め方 • 資料を見ながら,「例題」を行ってみる • 各自,「課題」に挑戦する • 遠慮なく質問してください • 自分のペースで先に進んで構いません 10
DrScheme の使用 • DrScheme の起動 プログラム • → PLT Scheme → DrScheme 今日の演習では「Intermediate Student」 に設定 Language → Choose Language → Intermediate Student → Execute ボタン 11
draw.ss teach pack のロード • DrScheme の描画機能である draw.ss teachpack を使うために, draw.ss teach pack をロードせよ この操作は1回だけでよい (次回からは自動的にロードされるように なる) 12
draw.ss teach pack のロード Language → Add Teachpack → htdp ディレクトリを選択 → draw.ss を選択 → Execute ボタン 13
例題1.簡単な絵を描く • DrScheme の描画機能である draw.ss teachpack を 使って,簡単な絵を描く • • • • • start: draw-solid-line: 線 draw-solid-rect: draw-solid-disk: clear-solid-disk: す • draw-circle: • stop: 「描画用ウインドウ」を開く 四角形 塗りつぶされた円 一度描いた「塗りつぶされた円」を消 円 「描画用ウインドウ」を閉じる 14
「例題1.簡単な絵を描く」の手順 1. 次を「実行用ウインドウ」で実行しなさい (start 100 100) (draw-solid-line (make-posn 0 0) (make-posn 80 80) 'red) (draw-solid-rect (make-posn 50 50) 50 20 'green) (draw-circle (make-posn 20 20) 20 'blue) (draw-solid-disk (make-posn 70 70) 10 'red) (stop) ☆ 次は,例題2に進んでください 15
16
例題1の実行結果 描画用ウインドウが 現れる 17
例題1のまとめ • 描画用のウインドウを開く (start 100 100) • 描画の実行 (draw-solid-line (make-posn 0 0) (make-posn 80 80) 'red) (draw-solid-rect (make-posn 50 50) 50 20 'green) (draw-circle (make-posn 20 20) 20 'blue) (draw-solid-disk (make-posn 70 70) 10 'red) • 描画用ウインドウを閉じる (stop) 18
19
例題2.ball 構造体を描く • ball 構造体を使って,(x, y) の位置に円を描くプ ログラム draw-ball を書く • 構造体とグラフィックス処理の組み合わせ • ball 構造体の属性値を設定するために make-ball (コ ンストラクタ)を使う • 属性 x, y を取り出すために ball-x, ball-y (セレクタ) を使う x y delta-x delta-y 位置 速度 20
「例題2.ball 構造体を描く」の手順
1. 次を「定義用ウインドウ」で,実行しなさい
• 入力した後に,Execute ボタンを押す
(define-struct ball
(x y delta-x delta-y))
;; draw-ball: a ball -> none
;; draw a solid disk at (x,y)
(define (draw-ball a-ball)
(draw-solid-disk (make-posn
(ball-x a-ball)
(ball-y a-ball))
5 'red))
2. その後,次を「実行用ウインドウ」で実行しなさい
(start 100 100)
(draw-ball (make-ball 10 10 0 0))
(stop)
☆ 次は,例題3に進んでください 21
まず,ball 構造体を 定義している 22
次に,関数 draw-ball を 定義している 23
24
描画用ウインドウが 現れる 25
ball 構造体 • ball は,x, y, delta-x, delta-y から構成する x y 位置 delta-x delta-y 速度 名前 (define-struct ball (x y delta-x delta-y)) 属性の並び 26
(define-struct ball (x y delta-x delta-y)) ;; draw-ball: a ball -> none ;; draw a solid disk at (x,y) (define (draw-ball a-ball) (draw-solid-disk (make-posn (ball-x a-ball) (ball-y a-ball)) 5 'red)) (start 100 100) (draw-ball (make-ball 10 10 0 0)) (stop) 27
例題3.リストの変数定義 • リスト (list 15 8 6) を値として持つ 変数Aを定義する • 変数を定義するために define を使う • リストを作るために cons を使う 28
「例題3.リストの変数定義」の手順 1. 次を「定義用ウインドウ」で,実行しなさい • 入力した後に,Execute ボタンを押す (define A (list 15 8 6)) 2. その後,次を「実行用ウインドウ」で実行しなさい A (first A) (rest A) ☆ 次は,例題4に進んでください 29
まず, (define A (list 15 8 6)) と書いて,変数Aの定義 を行っている 30
A と実行すると,Aの値である (list 15 8 6) が表示される 31
(first A), (rest A) を 実行している 32
例題4.構造体のリスト • 次のプログラムを実行し,「(name-list book)」 から「(list "Mike" "Bill" "Ken")」に至る過程の概 略を見る (define-struct address-record (name age address)) (define book (list (make-address-record "Mike" 10 "Fukuoka") (make-address-record "Bill" 20 "Saga") (make-address-record "Ken" 30 "Nagasaki"))) (define (name-list a-book) (cond [(empty? a-book) empty] [else (cons (address-record-name (first a-book)) (name-list (rest a-book)))])) 33
「例題4.構造体のリスト」の手順 1. 次を「定義用ウインドウ」で,実行しなさい • 入力した後に,Execute ボタンを押す (define-struct address-record (name age address)) (define book (list (make-address-record "Mike" 10 "Fukuoka") (make-address-record "Bill" 20 "Saga") (make-address-record "Ken" 30 "Nagasaki"))) 2. その後,次を「実行用ウインドウ」で実行しなさい book (first book) (address-record-address (first book)) ☆ 次は,例題5に進んでください 34
AddressNote 構造体の定義 変数 book の定義 (AddressNote 構造体のリスト 変数 book の操作 35
例題5.頂点のリストを値とする 変数の定義 • 「頂点」のリストを値として持つ変 数 P を定義する • 変数を定義するために define を使う • 1つの頂点 = posn 構造体 make-posn を使用 • リストを作るために cons を使う 36
「例題5.頂点のリストを値とする 変数の定義」の手順 1. 次を「定義用ウインドウ」で,実行しなさい • 入力した後に,Execute ボタンを押す (define P (cons (make-posn 0 0) (cons (make-posn 10 70) (cons (make-posn 100 30) empty)))) 2. その後,次を「実行用ウインドウ」で実行しなさい P (first P) (rest P) ☆ 次は,例題6に進んでください 37
y (10, 70) (100, 100) (0, 0) 0 x 38
まず,変数Pの定義 を行っている 39
Pの値が表示されている 40
(first P), (rest P) を 実行している 41
変数定義 変数名 (define P (cons (make-posn 0 0) (cons (make-posn 10 70) (cons (make-posn 100 30) empty)))) リストの本体 42
posn 構造体 • posn 構造体は,すでに DrScheme に組み込み済 み • (define-struct 構造名) を実行していなくても, posn 構造体を使うことができる 43
例題6.折れ線 • 折れ線を描くプログラム drawpolyline を作り,実行する • 1つの「頂点」 → 構造体 • 折れ線 → 「頂点」のリスト 44
「例題6.折れ線」の手順 1. 次を「定義用ウインドウ」で,実行しなさい • 入力した後に,Execute ボタンを押す (define P (cons (make-posn 0 0) 例題5と同じ (cons (make-posn 10 70) (cons (make-posn 100 30) empty)))) (define (draw-polyline a-poly) (cond [(empty? (rest a-poly)) true] [else (and (draw-solid-line (first a-poly) (first (rest a-poly))) (draw-polyline (rest a-poly)))])) 2. その後,次を「実行用ウインドウ」で実行しなさい (start 100 100) (draw-polyline P) (stop) ☆ 次は,例題7に進んでください 45
46
入力と出力 a-poly の値: (cons (make-posn 0 0) (cons (make-posn 10 70) (cons (make-posn 100 30) empty))) true draw-polyline 入力 入力は posn 構造体 のリスト 出力 出力は常に true 47
(define (draw-polyline a-poly) (cond 終了条件 [(empty? (rest a-poly)) true]自明な解 [else (and (draw-solid-line (first a-poly) (first (rest apoly))) (draw-polyline (rest a-poly)))])) 48
折れ線 draw-polyline 1. (rest a-poly) が空ならば: true → 終了条件 → 自明な解 2. そうで無ければ: • 2点: (first a-poly) と (first (rest a-poly)) を使って,線分を書き,その後 (draw-polyline (rest a-poly)) を実行 ⇒ 結局,すべての点について,線分を描くことを 繰り返す 49
折れ線の終了条件 No (empty? (rest a-poly)) Yes (and (draw-solid-line (first a-poly) (first (rest a-poly))) (draw-polyline (rest a-poly))) true が自明の解 50
描画命令と他の命令を並べるときは「and」 でつなぐ (and (draw-solid-line (first a-poly) (first (rest a-poly))) (draw-polyline (rest a-poly))) 描画命令 draw-solid-line と animation とを and でつないでいる 51
よくある間違い 描画命令と他の命令 が並んでいるのだが、 「and」を 書き忘れている エラーが出て, 実行できない 52
(draw-polyline P) から true が得られる過程の概略 (1/2) (draw-polyline P) 最初の式 = (draw-polyline (list (make-posn 0 0) (make-posn 10 70) (make-posn 100 30))) = ... = (and (draw-solid-line (makeposn 0 0) (make-posn 10 70)) (draw-polyline (rest (list (make-posn 0 0) (make-posn 10 70) (make-posn 100 30))))) =… = (draw-polyline (rest (list (make-posn 0 0) (make-posn 10 70) (make-posn 100 30)))) = (draw-polyline (list (make-posn 10 70) (make-posn 100 30))) コンピュータ内部での計算 53
(draw-polyline P) から true が得られる過程の概略 (2/2) = ... = (and (draw-solid-line (makeposn 10 70) (make-posn 100 30)) (draw-polyline (rest (list (make-posn 10 70) (makeposn 100 30))))) =… = (draw-polyline (rest (list (make-posn 10 70) (make終了条件が posn 100 30)))) = (draw-polyline (list (make-posn 100 30)))成立 コンピュータ内部での計算 = ... = true 実行結果 54
例題7.多角形 • 折れ線を描くプログラム drawpolygon を作り,実行する • 1つの「頂点」 → 構造体 • 折れ線 → 「頂点」のリスト • 終点と始点を結ぶ(これが,例題 6との違い) 55
「例題7.多角形」の手順 (1/2) 1. 次を「定義用ウインドウ」で,実行しなさい • 入力した後に,Execute ボタンを押す (define P (cons (make-posn 0 0) (cons (make-posn 10 70) (cons (make-posn 100 30) empty)))) (define (draw-polyline a-poly) (cond [(empty? (rest a-poly)) true] [else (and (draw-solid-line (first a-poly) (first (rest a-poly))) (draw-polyline (rest a-poly)))])) (define (last a-poly) (cond [(empty? (rest a-poly)) (first a-poly)] [else (last (rest a-poly))])) (define (draw-polygon a-poly) (draw-polyline (cons (last a-poly) a-poly))) 例題6と同じ 56
「例題7.多角形」の手順 (2/2) 2. その後,次を「実行用ウインドウ」で実行しなさい (start 100 100) (draw-polygon P) (stop) ☆ 次は,課題に進んでください 57
58
入力と出力 a-poly の値: (cons (make-posn 0 0) (cons (make-posn 10 70) (cons (make-posn 100 30) empty))) true draw-polygon 入力 入力は posn 構造体 のリスト 出力 出力は常に true 59
draw-polygon の中で行っていること draw-polygon a-poly (cons (last a-poly) a-poly)) を draw-polyling の入力 として与える 入力 true draw-polyline 出力 (例題5と同じプログラム) 入力は posn 構造体 のリスト 出力は常に true 60
(define (draw-polyline a-poly) (cond [(empty? (rest a-poly)) true] [else (and (draw-solid-line (first a-poly) (first (rest a-poly))) (draw-polyline (rest a-poly)))])) (define (last a-poly) (cond [(empty? (rest a-poly)) (first a-poly)] [else (last (rest a-poly))])) (define (draw-polygon a-poly) (draw-polyline (cons (last a-poly) a-poly))) 61
(draw-polygon P) からの過程の概略 (draw-polygon P) = (draw-polygon (list (make-posn 0 0) (make-posn 10 70) (make-posn 100 30))) = ... = (draw-polyline (list (make-posn 100 30) (make-posn 0 0) (make-posn 10 70) (make-posn 100 30))) 以下省略 (cons (last a-poly) a-poly)) の実行結果 62
折れ線のリストからの描画 • 例題1との関係 • draw_function: 入力: • draw_接線 • draw_小区画‘ 折れ線のリスト 63
11-4 演習課題 64
課題1 • 次の式を順に実行し,実行結果を報告せよ. 1. (start 300 300) 2. (draw-solid-line (make-posn 100 100) (makeposn 200 200) ’red) 3. (draw-circle (make-posn 200 100) 50 ’red) 4. (draw-solid-disk (make-posn 100 200) 50 ’green) 5. (stop) 65
課題2 ball 構造体(授業の例題2)についての問題 • • • ball のデータ a-ball から,ボールの速さを求める関 数を作成し,実行結果を報告しなさい ボールの速さは: √δx2 + δy2 66
課題3 ball 構造体(授業の例題2)についての問題 • • ball のデータ a-ball について,「x < 0 または y < 0 または x > 100 または y > 100 のときのみ true を出 力し,そうでなければfalseを出力」 するような関数 を作成し,実行結果を報告しなさい 67
課題4 • x-y 平面上の2点 a と b から,その間の距離を求 める関数 distance を作成し,実行結果を報告しな さい • 2点 a, b のための構造体を定義すること 68
課題5 • 複数のball を描画するプログラムの作成. • 次の関数 draw-ball は, ball のデータ a-ball から 1つのballを描くプログラムである. • これを参考にして,複数のballを描く関数 drawall-balls を作成しなさい.draw-all-balls の入力 はball構造体のリストである. • 複数の ball を扱うので,ball 構造体のリストを扱 うことになる • 必ず動作確認まで行うこと. (define (draw-ball a-ball) (draw-solid-disk (make-posn (ball-x a-ball) (ball-y a-ball)) 5 'red)) 69
課題6 • 複数のball を消すプログラムの作成. • 次の関数 clear-ball は, ball のデータ a-ball から 1つのballを消すプログラムである. • これを参考にして,複数のballを描く関数 clearall-balls を作成しなさい.clear-all-balls の入力 はball構造体のリストである. • 必ず動作確認まで行うこと. (define (clear-ball a-ball) (clear-solid-disk (make-posn (ball-x a-ball) (ball-y a-ball)) 5)) 70
さらに勉強したい人への 補足説明資料 DrScheme でのアニメーション 71
内容 • Dr Scheme でのタイマー機能とアニメー ション 72
例題8.ball を1秒描く • ball 構造体(授業の例題2)を使って,(x, y) の位置 に,ball を1秒だけ描くための関数 draw-and-clear を作り,実行する • 円を描く関数: draw-solid-disk 関数を使う • 円を消す関数: clear-solid-disk 関数を使う • 円を書いた後に, sleep-for-a-while 関数を使って1秒待ち, 円を消す • and 文を使い,draw-solid-disk, sleep-for-a-while, clearsolid-disk を順次実行する 73
「例題8.ball を1秒描く」の手順
1. 次を「定義用ウインドウ」で,実行しなさい
•
入力した後に,Execute ボタンを押す
(define-struct ball
例題2と同じ
(x y delta-x delta-y))
(define DELAY 1)
;;draw-and-clear: ball -> true
;;draw, sleep, clear a disk from the canvas
;;structural design, Scheme knowledge
(define (draw-and-clear a-ball)
(and
(draw-solid-disk (make-posn (ball-x a-ball) (ball-y a-ball)) 5 'red)
(sleep-for-a-while DELAY)
(clear-solid-disk (make-posn (ball-x a-ball) (ball-y a-ball)) 5 'red)))
2. その後,次を「実行用ウインドウ」で実行しなさい
(start 100 100)
(draw-and-clear (make-ball 10 10 0 0))
(stop)
74
75
ball を1秒描く • (draw-and-clear (make-ball 10 10 0 0)) の実行時に,「描画用ウインドウ」 に,赤い円が現れて消えるので,確 認すること 76
変数 DELAY (define DELAY 1) (define-struct ball (x y delta-x delta-y)) の定義 ball 構造 ;;draw-and-clear:a-ball->true ;;draw, sleep, clear a disk from the canvas ;;structural design, Scheme knowledge (define (draw-and-clear a-ball) (and (draw-solid-disk (make-posn (ball-x a-ball) (ball-y a-ball)) 5 'red) (sleep-for-a-while DELAY) (clear-solid-disk (make-posn (ball-x a-ball) (ball-y a-ball)) 5 'red))) 関数 draw-and-clear (strart 100 100) (draw-and-clear (make-ball 10 10 0 0)) (stop) draw-and-clear を 使っている部分 77
複数の描画命令を並べるときは 「and」でつなぐ (and (draw-solid-disk (make-posn (ball-x a-ball) (ball-y a-ball)) 5 'red) (sleep-for-a-while DELAY) (clear-solid-disk (make-posn (ball-x a-ball) (ball-y a-ball)) 5 'red)) 3つの描画命令 draw-solid-disk, sleep-for-a-while, clear-solid-disk を and でつないでいる 78
よくある間違い 複数の描画命令 が並んでいるのだが、 「and」を 書き忘れている エラーが出て, 実行できない 79
例題9.動く ball を描く • ball 構造体(授業の例題2)を使って,動く ボールのアニメーションのプログラム animation を作る • ボールを動かすための関数 move-ball を作る • 動くボールのアニメーションの関数 animation は, move-ball と draw-and-clear(授業の例題8) を呼 び出すと共に,animation(自分自身) を再帰的に呼 び出す 80
「例題9.動く ball を描く」の手順 (1/2) 1. 次を「定義用ウインドウ」で,実行しなさい • 入力した後に,Execute ボタンを押す (define-struct ball (x y delta-x delta-y)) (define DELAY 1) (define (draw-ball a-ball) (draw-solid-disk (make-posn (ball-x a-ball) (ball-y a-ball)) 5 'red)) (define (clear-ball a-ball) (clear-solid-disk (make-posn (ball-x a-ball) (ball-y a-ball)) 5)) (define (move-ball a-ball) (make-ball (+ (ball-x a-ball) (ball-delta-x a-ball)) (+ (ball-y a-ball) (ball-delta-y a-ball)) (ball-delta-x a-ball) (ball-delta-y a-ball))) (define (animation a-ball) (and (draw-ball a-ball) (sleep-for-a-while DELAY) (clear-ball a-ball) (animation (move-ball a-ball)))) 81
「例題9.動く ball を描く」の手順 (2/2) 2. その後,次を「実行用ウインドウ」で実行しなさい (start 100 100) (animation (make-ball 0 0 10 5)) (stop) 82
83
動く ball を描く • 「描画用ウインドウ」に,赤い円が動く様子を確 認すること • 満足したら「(stop)」を実行して,「描画用ウイ ンドウ」を閉じる 84
(define-struct ball (x y delta-x delta-y)) ball 構造 (define DELAY 1) 変数 DELAY の定義 (define (draw-ball a-ball) (draw-solid-disk (make-posn draw-ball 関数 (ball-x a-ball) (ball-y a-ball)) 5 'red)) (define (clear-ball a-ball) (clear-solid-disk (make-posn clear-ball 関数 (ball-x a-ball) (ball-y a-ball)) 5)) (define (move-ball a-ball) (make-ball (+ (ball-x a-ball) (ball-delta-x a-ball)) (+ (ball-y a-ball) (ball-delta-y a-ball)) move-ball 関数 (ball-delta-x a-ball) (ball-delta-y a-ball))) (define (animation a-ball) (and (draw-ball a-ball) animation 関数 (sleep-for-a-while DELAY) (clear-ball a-ball) (animation (move-ball a-ball)))) 85
描画命令と他の命令を並べるときは「and」で つなぐ (define (animation a-ball) (and (draw-ball a-ball) (sleep-for-a-while DELAY) (clear-ball a-ball) (animation (move-ball a-ball)))) 描画命令の1種である sleep-for-a-while と 他の式を and でつないでいる 86
課題7 • 複数のball を動かすプログラムの作成. • 次の関数 move-ball は,1つの ball を動かすプ ログラムである.速度からの位置の計算を行って いる • これを参考にして,複数のballを動かす関数 move-all-balls を作成しなさい.move-all-balls の入力はball構造体のリストである. • 必ず動作確認まで行うこと. (define (move-ball a-ball) (make-ball (+ (ball-x a-ball) (ball-delta-x a-ball)) (+ (ball-y a-ball) (ball-delta-y a-ball)) (ball-delta-x a-ball) (ball-delta-y a-ball))) 87
課題8 • 課題5で作成したプログラムを変更して,全 てのballが「描画用ウインドウ」の外にあれば 「描画用ウインドウ」を閉じるようにしなさ い. • また,「描画用ウインドウ」の外にあるボー ルについては,draw-solid-disk を実行しない ようにしなさい • 描画用ウインドウを閉じるには「(stop)」を用いる 88
課題9 • 例題9を参考にして,複数のballのアニメー ションのプログラムを作成し,実行結果を報 告しなさい • 作成したアニメーションプログラムが,全ての ball が「描画用ウインドウ」の外に出たら,アニ メーションが終わるようになっていることを確認 すること • もし,アニメーションが終わらないのなら,必ず 終わるように変更すること 89
課題10 • 課題9についての問題 • 動いている間に大きさや色が変るようにプログラ ムを変更しなさい 90
課題11 • 課題9についての問題 • 「描画用ウインドウ」の境界まで達したら,跳ね 返りの角度や速度などを変えて,跳ね返るように プログラムを変更しなさい 91