のようにする 上の例では GeneralPath を new するときに コンストラクタに何も指定していないが 直線を表す Line, 四角形を表す Rectangle などを引数に与えてもよい 矢印を作成するメソッドの引数矢印を表す GeneralPath を生成するために getarrowpat

Similar documents
手書認識 グラフ描画 Step2-2 手書認識 : 認識結果を PaintPanel で描画する < 属性付き文字列 AttributedString> 標準出力では分かりにくいうえに認識結果を使えないので 認識するごとに PaintPanel に文字を描画することにする ここで 数式はただの文字列

Cir

ブロック崩し Step1 矢印キーで左右に動かせるパドルを描画する < パドルの表現方法 > パドルは java.awt パッケージの Rectangle という Java が用意しているクラスを使う これは四角形を表すクラスで 左上の点の座標と幅 高さをもっている (x, y) Rectangle

PowerPoint Presentation

Java講座

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

Animals サンプル Step3 張り付けた動物の上をクリックすると それぞれの鳴き声で鳴く その鳴く間 一定時間 ( ここでは 1 秒間 ) 画像が別のものに変わる <アニメーションの基礎 : タイマーについて> アニメーションは アプリケーションが指定する間 一定間隔でどんどん画像をおきかえ

Animals サンプル Step 2 張り付けた動物の上をクリックすると それぞれの鳴き声で鳴く < 例外について > エラーや 通常の処理の中では起こってはいけない事象のことを例外といい 例外が起こる可能性がある場合はその対応処理を記述しなければならない 一般に java.lang パッケージの

IT プロジェクト

教材ドットコムオリジナル教材 0から始めるiアフ リ リファレンス i アプリ簡易リファレンス ver i アプリ Java 独自のメソッド (1)iアプリの命令を使えるようにする import com.nttdocomo.ui.*; (2) 乱数を使う import java.u

Javaプログラムの実行手順

Graphical User Interface 描画する

オブジェクト指向プログラミング・同演習 5月21日演習課題

Java プログラミング Ⅰ 3 回目変数 変数 変 数 一時的に値を記憶させておく機能型 ( データ型 ) と識別子をもつ 2 型 ( データ型 ) 変数の種類型に応じて記憶できる値の種類や範囲が決まる 型 値の種類 値の範囲 boolean 真偽値 true / false char 2バイト文

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

文字列操作と正規表現

JAVA入門

GUI プログラミング第 4 Graph ~ 手書認識と関数グラフ描画 ~ マウスで数式を書いて認識し 関数グラフを描画する < 手書認識とグラフ描画のステップ> ステップ 1_1 フレームの作成 ステップ 1_2 マウスで自由に線を書く ステップ 2-1 手書認識認識結果を標準出力する ステップ

(Microsoft PowerPoint - \223\306\217KJAVA\221\346\202R\224\ ppt)

基本情報STEP UP演習Java対策

ガイダンス

ガイダンス

ガイダンス

シミュレーションの簡単な例 GUI 無しのシミュレーションを作る GUI を作る パラメタを設定するデモンストレーションをする 2 オブジェクト指向プログラミング特論

Microsoft PowerPoint ppt

PowerPoint プレゼンテーション

JavaプログラミングⅠ

Animals サンプル Step 1 動物の種類を指定しておいて クリックした場所に画像を貼り付ける < レイアウトについて > 前回は ラベルやボタンの位置を座標で設定した Absolute Layout を選んだためである レイアウトは どのようにボタンなどのコンポーネントを配置するかを決定す

グラフの探索 JAVA での実装

Java プログラミング Ⅰ 3 回目変 数 今日の講義講義で学ぶ内容 変数とは 変数の使い方 キーボード入力の仕方 変 数 変 数 一時的に値を記憶させておく機能 変数は 型 ( データ型 ) と識別子をもちます 2 型 ( データ型 ) 変数に記憶する値の種類変数の型は 記憶できる値の種類と範囲

Java 基礎問題ドリル ~ メソッドを理解する ~ 次のプログラムコードに 各設問の条件にあうメソッドを追加しなさい その後 そのメソッドが正しく動作することを検証するためのプログラムコードを main メソッドの中に追加しなさい public class Practice { // ここに各設問

PowerPoint プレゼンテーション

Prog1_6th

第1章 ビジュアルプログラミング入門

< F2D8EA CE909482CC92EA82852E6A7464>

Microsoft Word - BouncingBall.doc

Java演習(4) -- 変数と型 --

JavaプログラミングⅠ

Microsoft PowerPoint - prog09.ppt

JavaプログラミングⅠ

Microsoft PowerPoint - prog09.ppt

問 次の Fortran プログラムの説明及びプログラムを読んで、設問に答えよ。

Prog1_3rd

Prog1_10th

レコードとオブジェクト

Microsoft PowerPoint - prog08.ppt

スライド 1

<4D F736F F F696E74202D AC C8899E D834F E >

Prog2_9th

データ構造とアルゴリズム論

JavaプログラミングⅠ

< F2D B838A835882CC8CF68EAE2E6A7464>

2

Taro-twokansu3.jtd

Prog2_12th

レコード class Point attr_accessor("x", "y") インスタンス変数の宣言 point.rb

Microsoft PowerPoint - lec06 [互換モード]

ToDo: 今回のタイトル

PowerPoint プレゼンテーション

GEC-Java

Method(C 言語では関数と呼ぶ ) メソッドを使うと 処理を纏めて管理することができる 処理 ( メソッド ) の再実行 ( 再利用 ) が簡単にできる y 元々はC 言語の関数であり 入力値に対する値を 定義するもの 数学では F(x) = 2x + 1 など F(x)=2x+1 入力値 (

// ステージを設定します stage.setscene(scene); stage.settitle(" キャンバス "); // ステージを表示します stage.show(); public static void main(string[] args) launch(args); キャンバス

Microsoft PowerPoint - OOP.pptx

JAVA とテンプレート

PowerPoint プレゼンテーション

第二回独習 Java ゼミ 第二章クラスとメソッド 2.1 メソッドの構造 2.2 静的メソッドと静的変数の概要 2.3 インスタンスメソッドとインスタンス変数の概要 2.4 Integerクラス 2006/04/19 神津健太

Prog1_2nd

Microsoft Word - 92.doc

< F2D834F838C A815B A CC>

PowerPoint プレゼンテーション

2016 年度 JAVA 講座第六週目 目次 パッケージ... 2 パッケージの作成... 2 パッケージの使用方法... 3 異なるパッケージ同名クラスの宣言... 4 パッケージの側面から見たアクセス修飾子... 4 ラッパークラス... 5 ラッパークラス利用法:キャスト... 5 ラッパーク

12.1 インターネットアドレス インターネットアドレス インターネットアドレス 32 ビットの長さを持つインターネットに接続されたマシンを識別するのに使う インターネットアドレスは ピリオドで区切られたトークンの並びで表現されることもある インターネットアドレス

Java言語 第1回

JavaプログラミングⅠ

< F2D B825082CC96E291E82E6A7464>

プログラミング入門1

Microsoft Word - 3new.doc

Microsoft PowerPoint - prog08.ppt

DVIOUT-exer

PowerPoint プレゼンテーション

< F2D F B834E2E6A7464>

HCI プログラミング 5 回目ウィンドウに画像を表示してみよう 今日の講義で学ぶ内容 画像の表示 画像のエフェクト 画像のビューポート指定 画像の表示 1 画像を表示してみましょう 画像の表示はクラス ImageView により管理されます ソースファイル名 :Sample5_1.java //

Microsoft Word - A05_AndroidプログラミングJUMP_画面800×1280

デジタル表現論・第6回

Java Scriptプログラミング入門 3.6~ 茨城大学工学部情報工学科 08T4018Y 小幡智裕

Prog1_15th

メソッドのまとめ

< F2D82518E9F8AD CC95BD8D7388DA93AE2E6A7464>

スライド 1

GUIプログラムⅣ

新・明解Java入門

Javaセキュアコーディングセミナー2013東京第1回 演習の解説

< F2D82518E9F8AD CC834F CC8CFC82AB82C68D4C>

問題1 以下に示すプログラムは、次の処理をするプログラムである

やさしいJavaプログラミング -Great Ideas for Java Programming サンプルPDF

Microsoft Word - no11.docx

Microsoft PowerPoint - prog13.ppt

Microsoft PowerPoint - prog13.ppt

以下に java.awt.graphics クラスの主なメソッドを示す (Graphics クラスの ) メソッド drawline(int x1, int y1, int x2, int y2) drawrect(int x, int y, int width, int height) fillr

PowerPoint Presentation

Transcription:

手書認識 グラフ描画 Step3 認識した数式をもとに関数グラフを描画する < 数式の構造解析 > 一般に 1+3 などと文字列で数式をうけとっても コンピュータはそれをそのままで式とは認識しない あくまで 文字列は文字の並びであり そこに数学的な意味は含まれない 数式として計算するためには プログラムによって数式の構造を解析し コンピュータが計算できる形式に変換する必要がある 今回のプログラムでは 通常の記法でかかれた数式の文字列を 逆ポーランド記法 (Reverse Polish Notation, RPN) という数式の書き方に変換して計算している これは 数字などを演算子の後に記述する書き方で コンピュータとの親和性が高い 本演習では 数式解析して RPN に変換し 計算をする部分はソースごと提供するので 使い方のみ説明する たとえば x 2 + 1 x + 3 という式を計算したい場合 関数に渡すために数式を次のように文字列で表現する String str = x^2+1/(x+3) ; この式で x=5 の値を求めたい場合は Term term = RPNUtil.RPN(str); double y = term.func(5.0); とすると y に解 25.125 が代入される ただし Term クラスと RPNUtil クラスは Java が提供するものではなく rpn パッケージに含まれる独自のクラスである <GeneralPath について> 関数をグラフ描画するにあたって 矢印を描画する必要がある 今回は 一般的な直線や曲線の集合をあらわす GeneralPath というクラスを使って描画する GeneralPath は線の集合であり それらの線が必ずしもつながっている必要はない 一般に 点 (x1, y1) から点 (x2, y2) に直線を引くには GeneralPath path = new GeneralPath(); path.moveto(x1, y1); // x1, y1 に移動 path.lineto(x2, y2); // x2, y2 まで直線をひく g2d.draw(path); // 描画 -1-

のようにする 上の例では GeneralPath を new するときに コンストラクタに何も指定していないが 直線を表す Line, 四角形を表す Rectangle などを引数に与えてもよい 矢印を作成するメソッドの引数矢印を表す GeneralPath を生成するために getarrowpath(point1, point2, barb, degree) というメソッドを定義して使っている 引数の意味は 次の図にあるとおりである barb degree point2 point1 Point2D.Float クラス getarrowpath メソッドの引数 point1, point2 は ava.awt.geom パッケージの Point2D.Float クラスである このクラスは Point2D というクラスの中に宣言されたサブクラスで 他に Point2D.Double クラスもある 宣言方法は次のようになっている public abstract class Point2D implements Cloneable { public static class Float extends Point2D implements Serializable { public float x; public float y; ( 中略 ) public static class Double extends Point2D implements Serializable { public double x; public double y; ( 中略 ) ( 中略 ) このように入れ子になってるクラスのことを内部クラス またはインナークラスと呼ぶ 今まで使っていた java.awt パッケージの Point クラスは x 座標と y 座標が int 型であったが Point2D.Float クラスは float 型 Point2D.Double クラスは double 型である -2-

< 作成手順 > 1.rpn.zip を適当な場所で解凍し rpn フォルダをコピーしてプロジェクトの src フォルダ (D: workspace Graph src) の中に貼り付ける 2. パッケージ エクスプローラで Graph プロジェクトを選択し 右クリック リフレッシュ rpn パッケージがあることを確認 3. のソースを編集 4.GraphFrame.java でインポート文を 2 つ追加し グラフ描画メソッドを編集 import javax.swing.joptionpane; import rpn.rpnexception; public class GraphFrame extends javax.swing.jframe { ( 中略 ) private void graphbuttonactionperformed(actionevent evt) { try { // 範囲取得 graphpanel.setxmin(double.parsedouble(xminfield.gettext())); graphpanel.setxmax(double.parsedouble(xmaxfield.gettext())); graphpanel.setymin(double.parsedouble(yminfield.gettext())); graphpanel.setymax(double.parsedouble(ymaxfield.gettext())); // 数式設定 graphpanel.setformula(paintpanel.getformula()); graphpanel.repaint(); catch (RPNException e) { JOptionPane.showMessageDialog(this, " 正しい数式を設定してください \n"+e.getmessage()); catch (NumberFormatException fe) { JOptionPane.showMessageDialog(this, " 範囲を正しく入力してください "); 5. 実行し 適当な式を 1 文字ずつ入力 認識し グラフ描画ボタンを押す グラフが正しく描画されることを確認する -3-

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 package graph; import java.awt.color; import java.awt.graphics; import java.awt.graphics2d; import java.awt.point; import java.awt.font.textattribute; import java.awt.geom.generalpath; import java.awt.geom.line2d; import java.awt.geom.point2d; import java.text.attributedcharacteriterator; import java.text.attributedstring; import java.text.characteriterator; import javax.swing.jpanel; import rpn.rpnexception; import rpn.rpnutil; import rpn.term; public class GraphPanel extends JPanel { private Term term; // 数式オブジェクト private double xmin=-10, xmax=10; // x の表示範囲 ( 関数の座標 ) private double ymin=-10, ymax=10; // y の表示範囲 ( 関数の座標 ) private int divnum = 200; // グラフ線の刻み幅 * コンストラクタ ( 何もしない ) public GraphPanel() { * 描画メソッド @Override public void paintcomponent(graphics g) { super.paintcomponent(g); Graphics2D g2d = (Graphics2D)g; // 白色背景 g2d.setcolor(color.white); g2d.fillrect(0, 0, getwidth(), getheight()); // グラフ描画 if (term!= null) { // 座標軸 ------------------------------------------- // 黒色設定 g2d.setcolor(color.black); // 原点を取得 Point origin = getgraphicalcoordinate(0, 0); // x 軸の矢印の始点と終点を取得 /* getarrowpath で使うので Point2D.Float にする * これは座標を float で保持する点のクラス Point2D.Float pf1 = new Point2D.Float(0, origin.y); Point2D.Float pf2 = new Point2D.Float(getWidth(), origin.y); // x 軸の矢印を取得 GeneralPath arrow = getarrowpath(pf1, pf2, 10, 20); // x 軸の矢印を描画 g2d.draw(arrow); // y 軸の矢印の始点と終点を取得 pf1 = new Point2D.Float(origin.x, getheight()); pf2 = new Point2D.Float(origin.x, 0); // y 軸の矢印を取得 arrow = getarrowpath(pf1, pf2, 10, 20); -4-

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 // y 軸の矢印を描画 g2d.draw(arrow); // 関数線 -------------------------------------------- // 赤色設定 g2d.setcolor(color.red); double x1,y1,x2,y2; Point p1, p2; // divnum 個の刻みで関数線を描画 for (int i=0; i<divnum; i++) { // i 番目の点を計算 // 数式オブジェクト term.func(x 座標 ) で y 座標を取得可能 x1 = xmin + (xmax-xmin)*i/(double)divnum; y1 = term.func(x1); // i+1 番目の点を計算 x2 = xmin + (xmax-xmin)*(i+1)/(double)divnum; y2 = term.func(x2); // 2 つの点の描画すべき点を取得 p1 = getgraphicalcoordinate(x1, y1); p2 = getgraphicalcoordinate(x2, y2); // パネルの中だったら描画する if (p1.y >= 0 && p1.y <= getheight() && p2.y >= 0 && p2.y <= getheight()) // 直線を描画 g2d.drawline(p1.x, p1.y, p2.x, p2.y); * 関数の座標系からパネルの座標を取得 * @param x * @param y * @return パネル上の点 private Point getgraphicalcoordinate(double x, double y) { return new Point((int)(getWidth()*(x-xMin)/(xMax-xMin)), (int)(getheight() - getheight()*(y-ymin)/(ymax-ymin))); * パスによって矢印線を表すオブジェクトを取得 <br> * point2 に矢印をつける * @param point1 始点 * @param point2 終点 * @param barb 矢印部分の長さ * @param degree 矢印部分の角度 (degree) * @return 矢印を表すパス private GeneralPath getarrowpath(point2d.float point1, Point2D.Float point2, int barb, int degree) { // 角度をラジアンにする double phi = Math.toRadians(degree); // 始点と終点によって決まる線分の角度を求める double theta = Math.atan2(point2.y - point1.y, point2.x - point1.x); // 始点から終点へのパスを取得 GeneralPath path = new GeneralPath(new Line2D.Float(point1, point2)); // 矢印部分の先端の座標を取得 double x = point2.x + barb*math.cos(theta+math.pi-phi); double y = point2.y + barb*math.sin(theta+math.pi-phi); // 矢印部分の先端へ移動 path.moveto((float)x, (float)y); // 終点へ向かってラインを引く path.lineto((float)point2.x, (float)point2.y); -5-

129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 // もうひとつの矢印部分の先端を取得 x = point2.x + barb*math.cos(theta+math.pi+phi); y = point2.y + barb*math.sin(theta+math.pi+phi); // 終点から矢印部分の先端へラインを引く path.lineto((float)x, (float)y); // 矢印線を表すパスを返す return path; * 属性付き文字列から数式を表すオブジェクトを作成 <br> * RPNUtil.RPN( 数式文字列 ) で Term オブジェクトを生成できる * @param formula 数式を表す属性付き文字列 * @throws RPNException public void setformula(attributedstring formula) throws RPNException { // null だったら何もしない ---------------------------------------------- if (formula == null) return; // 数式文字列生成例 :x の 2 乗 x^2 など ---------------------------------- StringBuffer sb = new StringBuffer(); // 数式文字列生成用 StringBuffer sbsup = new StringBuffer(); // 上付き文字保存用 // 属性付き文字列のループのまわし方は以下のようにする // char 変数 ch に文字が順に入り 属性はイテレータ ite が持っている AttributedCharacterIterator ite = formula.getiterator(); for (char ch=ite.first(); ch!=characteriterator.done; ch=ite.next()) { // 上付き文字属性だったら ch を sbsup に追加 if (ite.getattribute(textattribute.superscript) == TextAttribute.SUPERSCRIPT_SUPER) { if (sbsup.length() == 0) { sb.append('^'); sbsup.append(ch); // 上付き文字属性でなければ ch を sb に追加 else { // sbsup に何か文字が入ってれば sb に sbsup の内容を追加 if (sbsup.length()!= 0) { sb.append(sbsup); sbsup.delete(0, sbsup.length()); // sbsup を空にする sb.append(ch); // 最後に sbsup に残っている分を sb に追加 if (sbsup.length()!= 0) { sb.append(sbsup); sbsup.delete(0, sbsup.length()); // πは pi に は * にする for (int i=0; i<sb.length(); i++) { // if (sb.charat(i) == 'π') と等価 if (sb.charat(i) == 0x03C0) { sb = sb.replace(i, i+1, "pi"); i++; // else if (sb.charat(i) == ' ') と等価 else if (sb.charat(i) == 0xD7) { sb = sb.replace(i, i+1, "*"); // 数式文字列を解析して数式オブジェクトを作る ---------------------- term = RPNUtil.RPN(sb.toString()); -6-

193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 /* 範囲 setter ********************************************************* public void setxmin(double xmin) { this.xmin = xmin; public void setxmax(double xmax) { this.xmax = xmax; public void setymin(double ymin) { this.ymin = ymin; public void setymax(double ymax) { this.ymax = ymax; -7-