/****************************/ /* マニピュレータ */ /* coded by Y.Suganuma */ /****************************/ import java.io.*; import java.awt.*; import java.awt.event.*; import java.util.StringTokenizer; public class Link { public static void main (String[] args) throws IOException { LinkControl lc = new LinkControl("マニピュレータ"); } } class LinkControl extends Frame implements Runnable, ActionListener { Thread th; boolean state = true; Dimension d; Insets insets; int init = 1, n_l = 3, err = 0; int len[] = {200, 100, 50}; int now[] = new int [n_l]; int now_o[] = new int [n_l]; int next[] = new int [n_l]; Button bt; /************************/ /* コンストラクタ */ /* name : タイトル */ /************************/ LinkControl(String name) { // Frameクラスのコンストラクタの呼び出し super(name); // Windowの大きさの設定 int i1, s = 0; for (i1 = 0; i1 < n_l; i1++) s += len[i1]; setSize(s+40, s+70); d = getSize(); // ウィンドウを表示 setVisible(true); insets = getInsets(); // リセットボタンの追加 setLayout(null); Font f = new Font("MS 明朝", Font.PLAIN, 20); bt = new Button("Reset"); bt.setFont(f); bt.setBackground(Color.yellow); bt.addActionListener(this); // リスナー bt.setLocation(s-50-insets.right, insets.top+10); bt.setSize(new Dimension(80, 30)); add(bt); // イベントアダプタ addWindowListener(new WinEnd()); // スレッドの定義と開始 th = new Thread(this); th.start(); } /******************************/ /* ボタンが押されたときの処理 */ /******************************/ public void actionPerformed(ActionEvent e) { init = 1; } /******************/ /* スレッドの実行 */ /******************/ public void run() { int i1, k, draw = 1, sw = 0, chg, y1, y2, s = 0; double a; String str; StringTokenizer token; while (state) { try { th.sleep(500); } catch (InterruptedException e) {} // 初期設定 if (init > 0) { init = 0; chg = 1; for (i1 = 0; i1 < n_l; i1++) { now[i1] = 0; next[i1] = 0; } repaint(); } // 初期設定以外 else { // 角度の読み込み chg = 0; try { BufferedReader in = new BufferedReader(new FileReader("angle")); str = in.readLine(); token = new StringTokenizer(str, " \n"); k = -1; while (token.hasMoreTokens()) { if (k < 0) { draw = Integer.parseInt(token.nextToken()); if (draw > 0) break; } else next[k] = (int)Math.round(90.0 * Integer.parseInt(token.nextToken()) / 255.0); k++; } in.close(); } catch (IOException er_i) {} // 描画 if (draw == 0 && err == 0) { sw = 1; while (sw > 0) { sw = 0; try { th.sleep(10); } catch (InterruptedException e) {} for (i1 = 0; i1 < n_l; i1++) { if (next[i1] != now[i1]) { sw = 1; chg = 1; if (next[i1] > now[i1]) now[i1]++; else now[i1]--; } } if (sw > 0) { repaint(); y1 = d.height - insets.bottom - 10; y2 = y1; for (i1 = 0; i1 < n_l; i1++) { if (i1 == 0) { a = now[i1] * Math.PI / 180.0; s = 0; } else a = (s + now[i1]) * Math.PI / 180.0; y2 = y2 - (int)Math.round(len[i1] * Math.cos(a)); s += now[i1]; } if (y2 >= y1) { err = 1; break; } } } } } // 位置情報の出力 if (chg > 0) { str = "angle"; for (i1 = 0; i1 < n_l; i1++) { now_o[i1] = (int)Math.round(now[i1] * 255.0 / 90.0); str += (" " + now[i1]); } System.out.println(str); str = (err == 0) ? "1" : "2"; try { PrintStream out = new PrintStream(new FileOutputStream("angle")); for (i1 = 0; i1 < n_l; i1++) str += (" " + now_o[i1]); out.println(str); out.close(); } catch (IOException er_o) {} } } } /********/ /* 描画 */ /********/ public void paint (Graphics g) { int i1, x1, y1, x2, y2, s = 0; int xp[] = new int [4]; int yp[] = new int [4]; double a = 0.0; // 座標軸の描画 g.setColor(Color.black); x1 = insets.left + 10; y1 = d.height - insets.bottom - 10; y2 = insets.top + 5; g.drawLine(x1, y1, x1, y2); x2 = d.width - insets.right - 5; g.drawLine(x1, y1, x2, y1); // リンクの描画 for (i1 = 0; i1 < n_l; i1++) { if (i1 == 0) { a = now[i1] * Math.PI / 180.0; s = 0; } else { a = (s + now[i1]) * Math.PI / 180.0; x1 = x2; y1 = y2; } x2 = x1 + (int)Math.round(len[i1] * Math.sin(a)); y2 = y1 - (int)Math.round(len[i1] * Math.cos(a)); g.setColor(Color.pink); xp[0] = x1 - (int)Math.round(2 * Math.sin(a-0.5*Math.PI)); yp[0] = y1 + (int)Math.round(2 * Math.cos(a-0.5*Math.PI)); xp[1] = x1 - (int)Math.round(2 * Math.sin(a+0.5*Math.PI)); yp[1] = y1 + (int)Math.round(2 * Math.cos(a+0.5*Math.PI)); xp[2] = x2 - (int)Math.round(2 * Math.sin(a+0.5*Math.PI)); yp[2] = y2 + (int)Math.round(2 * Math.cos(a+0.5*Math.PI)); xp[3] = x2 - (int)Math.round(2 * Math.sin(a-0.5*Math.PI)); yp[3] = y2 + (int)Math.round(2 * Math.cos(a-0.5*Math.PI)); g.fillPolygon(xp, yp, 4); g.setColor(Color.red); g.fillOval(x1-5, y1-5, 10, 10); s += now[i1]; } } /************/ /* 終了処理 */ /************/ class WinEnd extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } }