sp-11. 構造体とグラフィックス

420 Views

January 26, 22

スライド概要

Scheme プログラミング
URL: https://www.kkaneko.jp/pro/scheme/index.html

金子邦彦研究室
URL: https://www.kkaneko.jp/index.html

profile-image

金子邦彦(かねこくにひこ) 福山大学・工学部・教授 ホームページ: https://www.kkaneko.jp/index.html 金子邦彦 YouTube チャンネル: https://youtube.com/user/kunihikokaneko

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

sp-11. 構造体とグラフィックス (Scheme プログラミング) URL: https://www.kkaneko.jp/pro/scheme/index.html 金子邦彦 1

2.

アウトライン 11-1 define による変数定義 11-2 DrScheme でのグラフィックス 11-3 パソコン演習 11-4 課題 2

3.

11-1 define による変数定義 3

4.

変数 • 変数には,名前,値がある 名前 値 例)(define PI 3.14) (define A (list 15 8 6)) 4

5.

リストの変数定義 (define A (list 15 8 6)) 変数名 リストの本体 5

6.

変数とは • 「オブジェクト」に名前を付けたもの • オブジェクトとは,数値,文字列,リス トなど.「値」を持つ • コンピュータは,変数の値と名前の関 係を記憶している 6

7.

11-2 DrScheme でのグラフィックス 7

8.

DrScheme でのグラフィックス • DrScheme のグラフィックス機能である draw.ss teachpack • • • • • start: draw-solid-line: 線 draw-solid-rect: draw-solid-disk: clear-solid-disk: す • draw-circle: • stop: 「描画用ウインドウ」を開く 四角形 塗りつぶされた円 一度描いた「塗りつぶされた円」を消 円 「描画用ウインドウ」を閉じる 8

9.

11-3 パソコン演習 9

10.

パソコン演習の進め方 • 資料を見ながら,「例題」を行ってみる • 各自,「課題」に挑戦する • 遠慮なく質問してください • 自分のペースで先に進んで構いません 10

11.

DrScheme の使用 • DrScheme の起動 プログラム • → PLT Scheme → DrScheme 今日の演習では「Intermediate Student」 に設定 Language → Choose Language → Intermediate Student → Execute ボタン 11

12.

draw.ss teach pack のロード • DrScheme の描画機能である draw.ss teachpack を使うために, draw.ss teach pack をロードせよ この操作は1回だけでよい (次回からは自動的にロードされるように なる) 12

13.

draw.ss teach pack のロード Language → Add Teachpack → htdp ディレクトリを選択 → draw.ss を選択 → Execute ボタン 13

14.

例題1.簡単な絵を描く • DrScheme の描画機能である draw.ss teachpack を 使って,簡単な絵を描く • • • • • start: draw-solid-line: 線 draw-solid-rect: draw-solid-disk: clear-solid-disk: す • draw-circle: • stop: 「描画用ウインドウ」を開く 四角形 塗りつぶされた円 一度描いた「塗りつぶされた円」を消 円 「描画用ウインドウ」を閉じる 14

15.

「例題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

17.

例題1の実行結果 描画用ウインドウが 現れる 17

18.

例題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

20.

例題2.ball 構造体を描く • ball 構造体を使って,(x, y) の位置に円を描くプ ログラム draw-ball を書く • 構造体とグラフィックス処理の組み合わせ • ball 構造体の属性値を設定するために make-ball (コ ンストラクタ)を使う • 属性 x, y を取り出すために ball-x, ball-y (セレクタ) を使う x y delta-x delta-y 位置 速度 20

21.
[beta]
「例題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

22.

まず,ball 構造体を 定義している 22

23.

次に,関数 draw-ball を 定義している 23

25.

描画用ウインドウが 現れる 25

26.

ball 構造体 • ball は,x, y, delta-x, delta-y から構成する x y 位置 delta-x delta-y 速度 名前 (define-struct ball (x y delta-x delta-y)) 属性の並び 26

27.

(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

28.

例題3.リストの変数定義 • リスト (list 15 8 6) を値として持つ 変数Aを定義する • 変数を定義するために define を使う • リストを作るために cons を使う 28

29.

「例題3.リストの変数定義」の手順 1. 次を「定義用ウインドウ」で,実行しなさい • 入力した後に,Execute ボタンを押す (define A (list 15 8 6)) 2. その後,次を「実行用ウインドウ」で実行しなさい A (first A) (rest A) ☆ 次は,例題4に進んでください 29

30.

まず, (define A (list 15 8 6)) と書いて,変数Aの定義 を行っている 30

31.

A と実行すると,Aの値である (list 15 8 6) が表示される 31

32.

(first A), (rest A) を 実行している 32

33.

例題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

34.

「例題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

35.

AddressNote 構造体の定義 変数 book の定義 (AddressNote 構造体のリスト 変数 book の操作 35

36.

例題5.頂点のリストを値とする 変数の定義 • 「頂点」のリストを値として持つ変 数 P を定義する • 変数を定義するために define を使う • 1つの頂点 = posn 構造体 make-posn を使用 • リストを作るために cons を使う 36

37.

「例題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

38.

y (10, 70) (100, 100) (0, 0) 0 x 38

39.

まず,変数Pの定義 を行っている 39

40.

Pの値が表示されている 40

41.

(first P), (rest P) を 実行している 41

42.

変数定義 変数名 (define P (cons (make-posn 0 0) (cons (make-posn 10 70) (cons (make-posn 100 30) empty)))) リストの本体 42

43.

posn 構造体 • posn 構造体は,すでに DrScheme に組み込み済 み • (define-struct 構造名) を実行していなくても, posn 構造体を使うことができる 43

44.

例題6.折れ線 • 折れ線を描くプログラム drawpolyline を作り,実行する • 1つの「頂点」 → 構造体 • 折れ線 → 「頂点」のリスト 44

45.

「例題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

47.

入力と出力 a-poly の値: (cons (make-posn 0 0) (cons (make-posn 10 70) (cons (make-posn 100 30) empty))) true draw-polyline 入力 入力は posn 構造体 のリスト 出力 出力は常に true 47

48.

(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

49.

折れ線 draw-polyline 1. (rest a-poly) が空ならば: true → 終了条件 → 自明な解 2. そうで無ければ: • 2点: (first a-poly) と (first (rest a-poly)) を使って,線分を書き,その後 (draw-polyline (rest a-poly)) を実行 ⇒ 結局,すべての点について,線分を描くことを 繰り返す 49

50.

折れ線の終了条件 No (empty? (rest a-poly)) Yes (and (draw-solid-line (first a-poly) (first (rest a-poly))) (draw-polyline (rest a-poly))) true が自明の解 50

51.

描画命令と他の命令を並べるときは「and」 でつなぐ (and (draw-solid-line (first a-poly) (first (rest a-poly))) (draw-polyline (rest a-poly))) 描画命令 draw-solid-line と animation とを and でつないでいる 51

52.

よくある間違い 描画命令と他の命令 が並んでいるのだが、 「and」を 書き忘れている エラーが出て, 実行できない 52

53.

(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

54.

(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

55.

例題7.多角形 • 折れ線を描くプログラム drawpolygon を作り,実行する • 1つの「頂点」 → 構造体 • 折れ線 → 「頂点」のリスト • 終点と始点を結ぶ(これが,例題 6との違い) 55

56.

「例題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

57.

「例題7.多角形」の手順 (2/2) 2. その後,次を「実行用ウインドウ」で実行しなさい (start 100 100) (draw-polygon P) (stop) ☆ 次は,課題に進んでください 57

59.

入力と出力 a-poly の値: (cons (make-posn 0 0) (cons (make-posn 10 70) (cons (make-posn 100 30) empty))) true draw-polygon 入力 入力は posn 構造体 のリスト 出力 出力は常に true 59

60.

draw-polygon の中で行っていること draw-polygon a-poly (cons (last a-poly) a-poly)) を draw-polyling の入力 として与える 入力 true draw-polyline 出力 (例題5と同じプログラム) 入力は posn 構造体 のリスト 出力は常に true 60

61.

(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

62.

(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

63.

折れ線のリストからの描画 • 例題1との関係 • draw_function: 入力: • draw_接線 • draw_小区画‘ 折れ線のリスト 63

64.

11-4 演習課題 64

65.

課題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

66.

課題2 ball 構造体(授業の例題2)についての問題 • • • ball のデータ a-ball から,ボールの速さを求める関 数を作成し,実行結果を報告しなさい ボールの速さは: √δx2 + δy2 66

67.

課題3 ball 構造体(授業の例題2)についての問題 • • ball のデータ a-ball について,「x < 0 または y < 0 または x > 100 または y > 100 のときのみ true を出 力し,そうでなければfalseを出力」 するような関数 を作成し,実行結果を報告しなさい 67

68.

課題4 • x-y 平面上の2点 a と b から,その間の距離を求 める関数 distance を作成し,実行結果を報告しな さい • 2点 a, b のための構造体を定義すること 68

69.

課題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

70.

課題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

71.

さらに勉強したい人への 補足説明資料 DrScheme でのアニメーション 71

72.

内容 • Dr Scheme でのタイマー機能とアニメー ション 72

73.

例題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

74.
[beta]
「例題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

76.

ball を1秒描く • (draw-and-clear (make-ball 10 10 0 0)) の実行時に,「描画用ウインドウ」 に,赤い円が現れて消えるので,確 認すること 76

77.

変数 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

78.

複数の描画命令を並べるときは 「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

79.

よくある間違い 複数の描画命令 が並んでいるのだが、 「and」を 書き忘れている エラーが出て, 実行できない 79

80.

例題9.動く ball を描く • ball 構造体(授業の例題2)を使って,動く ボールのアニメーションのプログラム animation を作る • ボールを動かすための関数 move-ball を作る • 動くボールのアニメーションの関数 animation は, move-ball と draw-and-clear(授業の例題8) を呼 び出すと共に,animation(自分自身) を再帰的に呼 び出す 80

81.

「例題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

82.

「例題9.動く ball を描く」の手順 (2/2) 2. その後,次を「実行用ウインドウ」で実行しなさい (start 100 100) (animation (make-ball 0 0 10 5)) (stop) 82

84.

動く ball を描く • 「描画用ウインドウ」に,赤い円が動く様子を確 認すること • 満足したら「(stop)」を実行して,「描画用ウイ ンドウ」を閉じる 84

85.

(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

86.

描画命令と他の命令を並べるときは「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

87.

課題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

88.

課題8 • 課題5で作成したプログラムを変更して,全 てのballが「描画用ウインドウ」の外にあれば 「描画用ウインドウ」を閉じるようにしなさ い. • また,「描画用ウインドウ」の外にあるボー ルについては,draw-solid-disk を実行しない ようにしなさい • 描画用ウインドウを閉じるには「(stop)」を用いる 88

89.

課題9 • 例題9を参考にして,複数のballのアニメー ションのプログラムを作成し,実行結果を報 告しなさい • 作成したアニメーションプログラムが,全ての ball が「描画用ウインドウ」の外に出たら,アニ メーションが終わるようになっていることを確認 すること • もし,アニメーションが終わらないのなら,必ず 終わるように変更すること 89

90.

課題10 • 課題9についての問題 • 動いている間に大きさや色が変るようにプログラ ムを変更しなさい 90

91.

課題11 • 課題9についての問題 • 「描画用ウインドウ」の境界まで達したら,跳ね 返りの角度や速度などを変えて,跳ね返るように プログラムを変更しなさい 91