質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

3回答

4664閲覧

タートルグラフィックスを用いて文字を描画したい

GuMasi

総合スコア73

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2020/03/26 07:13

編集2020/04/06 11:13

タートルグラフィックスを用いて文字(名前:apple)を描画したいのですが可能でしょうか?

追記:

python

1from turtle import * 2 3with open("handwriting-apple.txt", encoding="utf-8") as stream: 4 write("Apple", None, "center", "serif 64 bold") 5 color("red") 6 penup() 7 pensize(4) 8 9 for line in stream: 10 action, *args = line.strip().split(" ") 11 print(action, args) 12 if action == "setpos": 13 x, y = map(int, args) 14 setpos(x-480, -y+400) 15 elif action == "pendown": 16 x, y = map(int, args) 17 setpos(x-480, -y+400) 18 pendown() 19 elif action == "penup": 20 penup() 21 22hideturtle() 23done()

コード、エラー

追記2:
.pyファイルに記録用のコードを記述し実行後

イメージ説明

追記3: ![イメージ説明]

recordファイル、エラー内容

イメージ説明

replayファイル

追記4:エラーの出力内容、バージョンの確認。

イメージ説明

追記5: 該当部分のコード

```python
'''
from turtle import *

with open("handwriting-apple.txt", encoding="utf-8") as stream:
write("Apple", None, "center", "serif 64 bold")
color("red")
penup()
pensize(4)

# : キャンバスの絶対座標で記録されてるので、タートル中心の座標に修正(数値は適当) for line in stream: action, *args = line.strip().split(" ") print(action, args) if action == "setpos": x, y = map(int, args) setpos(x-480, -y+400) elif action == "pendown": x, y = map(int, args) setpos(x-480, -y+400) pendown() elif action == "penup": penup()

hideturtle()
done()
'''

実行方法: python record_motion.py > handwriting-apple.txt

import sys
sys.stdout = open("motion.log", "w", encoding = "utf-8")
from turtle import *

s = Screen()
t = Turtle()

def onmotion(e):
print("setpos {} {}".format(e.x, e.y))

def onrelease(e):
print("penup")
s.cv.unbind("<Motion>")
s.cv.unbind("<ButtonRelease-1>")

def onpress(e):
print("pendown {} {}".format(e.x, e.y))
s.cv.bind("<Motion>", onmotion)
s.cv.bind("<ButtonRelease-1>", onrelease)

s.cv.bind("<ButtonPress-1>", onpress)
t.write("Apple", None, "center", "serif 64 bold")
t.hideturtle()
done()

実行結果 ![イメージ説明](7771a217c22bf26ad5e7d53e77ceeebf.png) 追記:6 setpos数値変更    ```python from turtle import * with open("motion.log", encoding= "utf-8") as stream: write("Apple", None, "center", "serif 64 bold") color("red") penup() pensize(4) # XXX: キャンバスの絶対座標で記録されてるので、タートル中心の座標に修正(数値は適当) for line in stream: action, *args = line.strip().split(" ") print(action, args) if action == "setpos": x, y = map(int, args) setpos(x-360, -y+340) elif action == "pendown": x, y = map(int, args) setpos(x-360, -y+340) pendown() elif action == "penup": penup() hideturtle() done()

実行結果
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

投稿2020/03/26 10:48

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

GuMasi

2020/03/27 09:44

cateyeさん回答してくださりありがとうございます。 参考にさせていただきます。
GuMasi

2020/03/29 05:31

試みましたところ、.pyファイルに記録用のコードを記述させていただきましたらAppleと表示(質問追記2参照)されました。 こちらのコードを用いてアニメーションをさせることも可能なのでしょうか?
teamikl

2020/03/29 12:53

記録用のプログラムを実行しマウスでドラッグすると コンソール画面にその座標が表示するようになってます。 なので、`> ファイル名`と出力をファイルへリダイレクトするように実行して マウスの軌跡をファイルに保存します。 その後、そのファイルを用いて再生用のプログラムで再生できます。 下の5つ同時に描画のはデモとして載せただけでコードは添付してません。
GuMasi

2020/03/30 11:49

> ファイル名`と出力をファイルへリダイレクト >>私の知識力が乏しく申し訳ない(コメントの返信の箇所も異なることも合わせまして)のですが、ファイルへリダイレクトとはどのようなことなのでしょうか?
teamikl

2020/03/30 12:04

すいません、説明が大雑把になってたかもしれません。 現在はプログラムをどのように実行されてますか? 「記録用」の実行方法は以下の通り python~の文字をコマンドライン環境に打ち込んで実行するのを想定してます。 ‘実行方法: python record_motion.py > handwriting-apple.txt‘ 後ろの`> ファイル名` の部分が、リダイレクトといい、 通常なら画面に文字を印字するところをファイルへ書き込むように出力先を変更できます。
GuMasi

2020/03/31 11:32

>現在はプログラムをどのように実行されてますか? >>現在はファイル(record_motion.py )に記録用を記述し、もう一つのファイル(handwriting-apple.txt)に再生用 のコードを記述し、python3 record_motion.pyとし実行しています。 > ‘実行方法: python record_motion.py > handwriting-apple.txt‘ >>handwriting-apple.txt‘はpython record_motion.py > に続けて入力し実行でよろしいでしょうか? > 後ろの`> ファイル名` の部分が、リダイレクトといい、 >>教えてくださりありがとうございます。 上記でいいますとhandwriting-apple.txt‘がリダイレクトにあたるのですね。
teamikl

2020/03/31 11:41

作成するファイル名は、特に指定していませんでした。 リダイレクトも含め自分の回答を更新しますね。 記録用 record_motion.py 再生用 replay_motion.py handwriting-apple.txt は record_motion.py をリダイレクトで実行して生成されるファイル。ファイル名の部分は 再生用で開かれるファイル名に合わせます。 不等号の記号がリダイレクトで、 ファイルはリダイレクト先になります。
GuMasi

2020/04/01 12:50

>作成するファイル名は、特に指定していませんでした。 リダイレクトも含め自分の回答を更新しますね。 >>ありがとうございます。 上記のhandwriting-apple.txt の出力例のように座標が出力はされました。 >handwriting-apple.txt は record_motion.py をリダイレクトで実行して生成されるファイル。ファイル名の部分は 再生用で開かれるファイル名に合わせます。 >>申し訳ないのですが、画像で示していただけますと助かります。 >不等号の記号がリダイレクトで、 ファイルはリダイレクト先になります。 >>すみません、誤認識していました。
teamikl

2020/04/01 13:01

> 上記のhandwriting-apple.txt の出力例のように座標が出力はされました。 これは、どこに出力されました?実行環境のターミナルでしょうか?それともファイル? ファイルが出力されていない場合、リダイレクトがうまく行ってないので、実行方法を見直す必要があります。 と思ったら、画像を見て気づきました。 IDEで実行の場合、コマンドラインでリダイレクトするようにするのは追加で設定が必要ですね。 スクリプト側でファイルに出力するように対応してみます。 記録用のファイルの先頭の方に、以下の2行を追加してみてください。 ``` import sys sys.stdout = open("handwriting-apple.txt", "w", encoding="utf-8") ```
teamikl

2020/04/01 13:27

記録~再生時のキャプチャを回答に乗せました。 (※ 画像内ではファイル名は motion.log に変更ましたが、 記録と再生スクリプトで同じファイルを参照するようにだけ注意してください)
GuMasi

2020/04/02 14:23

>これは、どこに出力されました?実行環境のターミナルでしょうか?それともファイル? >>ターミナルです。 >記録用のファイルの先頭の方に、以下の2行を追加してみてください。 >>ありがとうございます。 追加させていただきまして、同様に記録用、再生用にmotion.logに変更し実行いたしましたのですが私の環境ではエラー(質問欄に追記3)が出力されてしまいます。
teamikl

2020/04/02 15:39 編集

実行環境が python 2.7 になってないですか? python -> python3 ではどうでしょう python2.xで動かす場合の ソース中に日本語がある場合の文字コードの問題の対策 python2.x では冒頭に # -*- coding: utf-8 -*- という行をいれて指定します。 もしくは、暫定的な対策ならソース中の日本語のコメント全削除(コメントアウトではなくdelete) python3.x 系では問題ないはずです。 ==== バージョンの確認方法 import sys print(sys.version)
GuMasi

2020/04/03 06:31

>実行環境が python 2.7 になってないですか? python -> python3 ではどうでしょう なっていたかもしれません。 バージョンの確認も合わせまして、python3で再度実行しましたところ、(上記参照追記4)SyntaxError: invalid syntaxというエラーメッセージが出力されてしまいます。 お手数おかけいたしまして申し訳ないです。
teamikl

2020/04/03 06:58 編集

いえ、こちらこそ、説明不足なところがありまして 実行環境含めて、確認した方がよかったですね(リダイレクトの辺りは) 出力をファイルに保存する処理を、リダイレクトに頼って省略してたので。 何度かスクリプトを修正したので、念の為もう一度確認してみます。 手元の環境では、win10 ですが一応 3.7.0, 3.8.0 で動作確認 エラーについて SyntaxError は2か所ですか? line 30: 誤: open(("motion.log", "w", encoding = "utf-8") 正: open("motion.log", "w", encoding="utf-8") - open(( ←かっこが2重になってます - "=" 画像なので解りませんが イコールが全角になっていませんか? もうひとつの line11: に関しては、画像では見切れているようなので 該当部分のコードを提示お願いします。
GuMasi

2020/04/04 14:12

>何度かスクリプトを修正したので、念の為もう一度確認してみます。 手元の環境では、win10 ですが一応 3.7.0, 3.8.0 で動作確認 確認くださりましてありがとうございます。 >エラーについて SyntaxError は2か所ですか? 一か所です。 >もうひとつの line11: に関しては、画像では見切れているようなので 該当部分のコードを提示お願いします。 質問欄(追記5)に該当部分も含めましたコードを追加させていただきました。 またopenのかっこが2重を修正し、実行致しましたらウインドウ(Apple)がたちあがり、その後文字に沿って書きました後に、python3 replay_motion.py と実行しましたところ文字の場所(質問欄参照)とは異なる場所に表示されてしまいました。
teamikl

2020/04/04 14:41

追記5: 該当部分のコードですが 再生用(replay)のコードがコメント内に書かれていて 実行されるのは記録用(record)のコードになってますよね。 日本語コメントは python3.xであれば問題ないはずですが、 エラーに該当するコメント内の日本語を削除してみてください。 一応、別回答にて 2.x にも対応したコードを投稿しました。 ---- 座標のズレに関して、 XXX: キャンバスの絶対座標で記録されてるので、タートル中心の座標に修正(数値は適当) この辺りは本題から外れるために簡略化してます。 setpos(x-480, -y+400) を調整してみてください。(2箇所)
GuMasi

2020/04/05 12:34

>追記5: 該当部分のコードですが 再生用(replay)のコードがコメント内に書かれていて 実行されるのは記録用(record)のコードになってますよね。 はい。 >エラーに該当するコメント内の日本語を削除してみてください。 一応、別回答にて 2.x にも対応したコードを投稿しました。 わかりました。 ありがとうございます。 >setpos(x-480, -y+400) を調整してみてください。(2箇所) はい。 こちらを調節することによって文字に沿って描画させることができるのですね。
GuMasi

2020/04/06 11:09

setposの数値を調整しましたところ文字に沿っては描画(上記参照追記6)されてるようなのですが、 こちらで大丈夫でしょうか?
teamikl

2020/04/06 11:18

お、うまくいきましたね ズレに関しては微調整は必要かもしれませんが、 意図通りの動作です
GuMasi

2020/04/06 11:26

ありがとうございます。 teamikl様のおかげです。
guest

0

ベストアンサー

追記を重ねて読みにくく成ってきたかもしれないので検めて

変更点:

  • Python 2.x/3.x 両方対応です。
  • リダイレクト~は気にしなくても大丈夫です。普通に実行。
  • 出力される&読み込まれるファイルは"motion.log"としました。

記録用スクリプト

record_motion.py

python

1# -*- coding: utf-8 -*- 2 3from __future__ import print_function, unicode_literals 4 5## Redirect STDOUT to "motion.log" file 6import io, sys 7sys.stdout = io.open("motion.log", "w", encoding="utf-8") 8 9from turtle import * 10 11def main(): 12 s = Screen() 13 t = Turtle() 14 15 def onmotion(e): 16 print("setpos {} {}".format(e.x, e.y)) 17 18 def onrelease(e): 19 print("penup") 20 s.cv.unbind("<Motion>") 21 s.cv.unbind("<ButtonRelease-1>") 22 23 def onpress(e): 24 print("pendown {} {}".format(e.x, e.y)) 25 s.cv.bind("<Motion>", onmotion) 26 s.cv.bind("<ButtonRelease-1>", onrelease) 27 28 s.cv.bind("<ButtonPress-1>", onpress) 29 t.write("Apple", None, "center", "serif 64 bold") 30 t.hideturtle() 31 done() 32 33if __name__ == "__main__": 34 main()

再生用スクリプト

replay_motion.py

python

1# -*- coding: utf-8 -*- 2 3from turtle import * 4import fileinput 5 6def main(): 7 write("Apple", None, "center", "serif 64 bold") 8 color("red") 9 penup() 10 pensize(4) 11 12 for line in fileinput.input(files=["motion.log"]): 13 params = line.strip().split(" ") 14 action, args = params[0], params[1:] 15 print(action, args) 16 if action == "setpos": 17 x, y = map(int, args) 18 setpos(x-480, -y+400) 19 elif action == "pendown": 20 x, y = map(int, args) 21 setpos(x-480, -y+400) 22 pendown() 23 elif action == "penup": 24 penup() 25 26 hideturtle() 27 done() 28 29if __name__ == "__main__": 30 main() 31

出力されるログファイルのサンプル

motion.log

pendown 393 326 setpos 393 327 setpos 393 329 setpos 393 334 setpos 390 340 setpos 389 344 setpos 388 345 setpos 386 348 setpos 384 352 setpos 383 354 setpos 383 355 setpos 381 358 setpos 380 359 setpos 378 361 setpos 377 363 setpos 375 365 setpos 374 369 setpos 373 373 setpos 371 376 setpos 370 380 setpos 369 381 setpos 369 382 setpos 369 384 setpos 368 386 setpos 368 387 setpos 368 388 penup pendown 388 337 setpos 389 337 setpos 392 340 setpos 393 343 setpos 395 347 setpos 398 353 setpos 400 358 setpos 403 366 setpos 406 373 setpos 408 377 setpos 410 382 setpos 411 385 setpos 411 386 penup pendown 378 364 setpos 379 364 setpos 385 365 setpos 392 365 setpos 399 367 setpos 401 367 setpos 402 367 penup

投稿2020/04/03 07:28

編集2020/04/03 07:30
teamikl

総合スコア8760

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

タートルが文字の線に沿って動き描画するアニメーションを期待されているのでしょうか? (hand-writing animation)
それとも、単に画面上に文字が表示されていればいいのか、どちらでしょう。
どちらも可能ですが、やりたいことの詳細によっては手間が変わってきます。

後者は単純に turtleモジュールにあるwrite() メソッドで文字をオブジェクトとして描画できます。
前者は、まずタートルがどのように動くかの情報を作る必要があります。

  1. 動きのデータを生成するプログラムを作成
  2. 例) 画面に Apple の文字を描画して、文字に沿ってマウスを動かした時の座標を記録

(ペンタブ等使えばもう少し綺麗に書けるかも・・)
3. 座標データを読み込み描画アニメーションとして再生するプログラムを作成

追記: 記録~再生の手順
イメージ説明

イメージ説明

イメージ説明

他にも、文字を綺麗に表示したい場合は、フォントのデータから情報を得る等
色々と凝る必要がありますが、大枠は大体このような感じです。


記録用(record_motion.py) リダイレクト付きで実行してください

python

1# -*- coding: utf-8 -*- 2# 実行方法: python record_motion.py > motion.log 3from turtle import * 4 5# リダイレクトがうまくいかない場合以下の2行を有効にしてみてください 6# import sys 7# sys.stdout = open("motion.log", "w", encoding="utf-8") 8 9s = Screen() 10t = Turtle() 11 12def onmotion(e): 13 print("setpos {} {}".format(e.x, e.y)) 14 15def onrelease(e): 16 print("penup") 17 s.cv.unbind("<Motion>") 18 s.cv.unbind("<ButtonRelease-1>") 19 20def onpress(e): 21 print("pendown {} {}".format(e.x, e.y)) 22 s.cv.bind("<Motion>", onmotion) 23 s.cv.bind("<ButtonRelease-1>", onrelease) 24 25s.cv.bind("<ButtonPress-1>", onpress) 26t.write("Apple", None, "center", "serif 64 bold") 27t.hideturtle() 28done()

再生用(replay_motion.py)

# -*- coding: utf-8 -*- from turtle import * with open("motion.log", encoding="utf-8") as stream: write("Apple", None, "center", "serif 64 bold") color("red") penup() pensize(4) # XXX: キャンバスの絶対座標で記録されてるので、タートル中心の座標に修正(数値は適当) for line in stream: action, *args = line.strip().split(" ") print(action, args) if action == "setpos": x, y = map(int, args) setpos(x-480, -y+400) elif action == "pendown": x, y = map(int, args) setpos(x-480, -y+400) pendown() elif action == "penup": penup() hideturtle() done()

motion.log の出力例

pendown 390 332 setpos 390 333 setpos 390 334 setpos 390 335 setpos 390 337 : : :

このような感じに、マウスをドラッグ中に通った座標が記録されます。

投稿2020/03/26 13:41

編集2020/04/02 15:38
teamikl

総合スコア8760

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

GuMasi

2020/03/27 10:34

回答いただきましてありがとうございます。 >タートルが文字の線に沿って動き描画するアニメーションを期待されているのでしょうか? (hand-writing animation)それとも、単に画面上に文字が表示されていればいいのか、どちらでしょう。 >>後者の単に画面上に表示されますのをイメージしていました。 コードのfrom turtle import *のアスタリスクについてなのですが、importのよこのアスタリスクはどのような意味なのでしょうか? 後、同様にコードを実行しましたのですが私の環境ではエラー(質問追記:上記参照)になってしまいます。
teamikl

2020/03/27 11:40

モジュールの提供する定数・関数をすべてインポートするという意味になります。 (__all__ が定義されていればその名前のみをインポート) Pythonではあまり推奨されない方法ですが、 turtle しか使わない状況では毎回モジュール名を付けるのが 冗長になりがちなので、このようにしてます。 エラーについては、まず「記録用」のスクリプトで テキストファイルを生成されるのを想定してます。 コメントの指示通りの手順で実行して下さい。 (ファイル名が間違えていたので修正します) 文字表示だけなら、上記のスクリプトは忘れてしまって大丈夫。 write() の部分のみです。 ‘‘‘ from turtle import * write("apple") ‘‘‘
GuMasi

2020/03/28 12:49

>turtle しか使わない状況では毎回モジュール名を付けるのが 冗長になりがちなので、このようにしてます。 >>そうなのですね。 > コメントの指示通りの手順で実行して下さい。 (ファイル名が間違えていたので修正します) >>ありがとうございます、試みてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問