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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

4回答

3333閲覧

2点の最短距離での移動

OMDM1991

総合スコア25

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2015/09/25 16:08

以下のソースコードで実行すると、最短距離ではない移動になってしまいます。(詳細は画像参照)

java

1if(X2 < X1){X1 --;} 2if(X2 > X1){X1 ++;} 3if(Y2 < Y1){Y1 --;} 4if(Y2 > Y1){Y1 ++;}

イメージ説明
どのように記述すれば最短距離で移動してくれるでしょうか?

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

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

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

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

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

guest

回答4

0

(x1, y1) - (x2, y2) を結ぶ直線上を移動する点(x, y) を式で次のように表すことができます。
x = x1 + t * (x2 - x1)
y = y1 + t * (y2 - y1)
ここで tは 移動開始後の経過時間を表します。そして
t = 0 の時に (x1, y1) にいる
t = 1 の時に (x2, y2) にいる
ものとします。

点を (x1, x2) から 0.1 秒毎に移動させて、1秒後に (x2, y2)動作の擬似コードは次のようになります。

t = 0.0 dt = 0.01 // 0.01 秒毎に点を描画する (100 フレーム / 1秒 の描画に対応) dx = x2 - x1 dy = y2 - y1 move(x1, y1) // スタート地点に点を移動させる while (t < 1.0) { x = x1 + t * dx // t 秒後の点の x 座標を計算 y = y1 + t * dy // t 秒後の点の y 座標を計算 move(x, y) // 点を (x, y) に移動させる。 t += dt wait(dt) // dt 秒間 スリープする。 }

↑では t を 1秒で 0.0 〜 1.0 まで等間隔で変化させていますが、
t の変化量を変化させると、加速しながら移動したり、減速しながら移動させるようなこともできます。

↑では x, y を t を変数にした関数にしていますが、
この関数を工夫すると、円を描くようにさせたり、四角形を描くようにさせたりすることもできます。

投稿2015/09/27 07:24

編集2015/09/27 07:27
katoy

総合スコア22324

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

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

0

直線を書くアルゴリズムというものがあります。
(コンピュータグラフックスの教科書なら触れられているトピックのはず)
以下に参考情報を紹介します。

参考情報:

...
ブレゼンハムのアルゴリズム(Bresenham's line algorithm)は、与えられた始点と終点の間に連続した点を置き、近似的な直線を引くためのアルゴリズム。
ブレゼンハムの線分描画アルゴリズム、ブレゼンハムアルゴリズムとも。
コンピュータのディスプレイに直線を描画するのによく使われ、整数の加減算とビットシフトのみで実装できるので多くのコンピュータで使用可能である。
コンピュータグラフィックスの分野の最初期のアルゴリズムの1つである。これを若干拡張すると、円を描くことができる。
...

↑ には図解もあり、わかりやすいです。

↑は英語ですが、DDA, Xiaolin Wu's line algorithm へのリンクも含んだ解説があります。
DDA https://en.wikipedia.org/wiki/Digital_differential_analyzer_(graphics_algorithm)
Xiaolin Wu https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm

投稿2015/09/25 16:37

編集2015/09/25 22:14
katoy

総合スコア22324

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

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

OMDM1991

2015/09/27 04:33

丁寧な回答有難うございます。
guest

0

点P(X1,Y1)と点Q(X2,Y2)を点P(X1,Y1)が原点に重なるように並行移動します。
原点に並行移動するのは、これから求める回転量(角度)の計算を簡単にするためです。

X軸あるいはY軸と平行になるように原点を中心に回転します。
ここではX軸と並行になるように回転したとします。
回転後の点Q'は(X2',0)となります。点P は(0,0)、原点にあるので変化しません。

移動する点をRとすると、点Rは、(0,0) から、(X2',0) まで移動させれば良いことが
わかります。移動させるときに先ほどの回転量(角度)を点Rに逆向きに回転して点R’を求めます。
さらに平行移動した分を元に戻して点R''を求めます。

点R''は、(X1,Y1)から(X2,Y2) への最短距離を移動します。

投稿2015/09/25 17:09

umeaji

総合スコア101

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

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

OMDM1991

2015/09/27 04:33

丁寧な回答有難うございます。
guest

0

ベストアンサー

n回ループでたどり着く、という発想で説明します。

X軸、Y軸の1ループあたりの移動量を求め、
毎ループ加算していけば直線で移動するようになります。

X軸は(X2-X1)/n、Y軸は(Y2-Y1)/n、になりますね。

なので、↓みたいな感じ。(数字は適当です)

// X2,Y2にたどり着くループ数 int n = 10; // (X1,Y1)の座標 float X1 = 10, Y1 = 0; // (X2,Y2)の座標 float X2 = 0, Y2 = 6; // X軸の1ループあたりの移動量 float Xn = (X2 - X1) / n; System.out.println(String.format("X軸の移動量=%s", Xn)); // Y軸の1ループあたりの移動量 float Yn = (Y2 - Y1) / n; System.out.println(String.format("Y軸の移動量=%s", Yn)); // 移動用変数 float posX = X1, posY = Y1; System.out.println(String.format("(posX=%s,posY=%s)", posX, posY)); // 移動処理 for(int i = 0; i < n; i++) { posX += Xn; posY += Yn; System.out.println(String.format("(posX=%s,posY=%s)", posX, posY)); }

投稿2015/09/25 17:02

TetsujiMiwa

総合スコア1124

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

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

OMDM1991

2015/09/27 04:31

丁寧で分かりやすい回答有難うございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問