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

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

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

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

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

Q&A

解決済

4回答

4808閲覧

3点から長方形を作りたい

b7n

総合スコア30

Java

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

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

0グッド

2クリップ

投稿2016/03/05 14:29

編集2016/03/05 23:53

javaで3次元の3つの点から長方形を書こうと思っています。
しかし、与えられた3つの点は長方形の頂点ではないため、そのまま使うと歪んでしまいます。
ABを通りCを使って描かれた長方形イメージ図
↑ABを通りCを使って描かれた長方形イメージ図

java

1import javax.vecmath.Vector3f; 2import org.lwjgl.opengl.GL11; 3~略~ 4/** 5 * 長方形を描く 6 * @param A 位置A 7 * @param B 位置B 8 * @param C 位置C 9 */ 10public void drawQuad(Vector3f A, Vector3f B, Vector3f C) { 11 12 // A2(A')を求めたい 13 Vector3f A2 = ~~~~~; 14 15 // A2からB2を求める 16 Vector3f AtoB = new Vector3f(B); 17 AtoB.sub(A); 18 Vector3f B2 = new Vector3f(A2); 19 B2.add(AtoB); 20 21 // 描画 22 GL11.glBegin(GL11.GL_QUADS); 23 GL11.glVertex3f(A.x, A.y, A.z); 24 GL11.glVertex3f(B.x, B.y, B.z); 25 GL11.glVertex3f(B2.x, B2.y, B2.z); 26 GL11.glVertex3f(A2.x, A2.y, A2.z); 27 GL11.glEnd(); 28 29}

A'を求めることは可能でしょうか?

また、A'は具体的のどのようなプログラムで計算すれば求まるのでしょうか?

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

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

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

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

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

guest

回答4

0

ベストアンサー

ベクトルで考えるのが簡単かもしれません。(各点の座標を位置ベクトルと考える)
ベクトルC + t(実数)×ベクトルAB = ベクトルA + s(実数)×(ABC平面上のABに直交するベクトル)
ベクトルについて少し勉強する必要がありますが、それを使えばこの方程式を解くことでA'を求められます。

また、他にベクトルを使う方法としては、

  1. ベクトルABとベクトルACの内積を求める (=ABの長さ×ACのAB方向の長さ(符号はABと同じ方向か否か))
  2. (1.の結果)÷(ABの長さ)^2を求める (=ACのAB方向の長さ/ABの長さ)
  3. ベクトルC - (2.の結果)×ベクトルAB がA'の位置ベクトル、すなわちA'の座標

(第2項はACのAB方向の長さ×AB方向の長さ1のベクトル)

こっちのほうが方程式を解く必要がないため、プログラムするなら簡単かと。

投稿2016/03/06 15:32

編集2016/03/07 02:15
swordone

総合スコア20649

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

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

b7n

2016/03/07 14:52

具体的な解説をしていただき、ありがとうございます。 方程式に関してはどれもプログラムにしにくくて困ってましたが、2つ目の方法でプログラムすることに成功しました! 内積を長さで割るという考えに目からウロコです。 そしてそれぞれの計算で何を示すことができるかがわかりやすく解説してあり助かります。 完成したコードの抜粋を以下に挙げておきます。 -------------------------------------------------- /** * 頂点A、頂点Bと、補助点Pを使い、長方形ABCDとなるような頂点C、頂点Dを求めます * @param vecA 頂点A (図中点A) * @param vecB 頂点B (図中点B) * @param vecP 補助点P (図中点C) * @param vecD 頂点C 書き換え対象 (図中点A') * @param vecC 頂点D 書き換え対象 (図中点B') */ public void makeRectangleSquare(Vector3f A, Vector3f B, Vector3f P, Vector3f C, Vector3f D) { // ① ベクトルABとベクトルAPの内積を求める (=ABの長さ×APのAB方向の長さ(符号はABと同じ方向か否か)) Vector3f vecAB = new Vector3f(B).sub(A); Vector3f vecAP = new Vector3f(P).sub(A); float dotABAP = vecAB.dot(vecAP); // ② (1.の結果)÷(ABの長さ)^2を求める (=APのAB方向の長さ/ABの長さ) double divAPAB = dotABAP / A.lengthSquaredTo(B); // ③ ベクトルP - (2.の結果)×ベクトルAB がA'の位置ベクトル、すなわちA'の座標 // (第2項はAPのAB方向の長さ×AB方向の長さ1のベクトル) D.set(P).sub(vecAB.scale(divAPAB)); C.set(D).add(B).sub(A); } /** * ベクトルクラス(使用箇所抜粋) */ public class Vector3f implements Serializable { ~略~ public float x; public float y; public float z; ~略~ public Vector3f set(Vector3f vec) { this.x = vec.x; this.y = vec.y; this.z = vec.z; return this; } ~略~ public float lengthSquaredTo(Vector3f vec) { return pow2(this.x - vec.x) + pow2(this.y - vec.y) + pow2(this.z - vec.z); } protected final float pow2(float num) { return num * num; } ~略~ public float dot(Vector3f vec) { return this.x * vec.x + this.y * vec.y + this.z * vec.z; } public Vector3f scale(double scale) { this.x *= scale; this.y *= scale; this.z *= scale; return this; } public Vector3f add(Vector3f vec) { this.x += vec.x; this.y += vec.y; this.z += vec.z; return this; } ~略~ public Vector3f sub(Vector3f vec) { this.x -= vec.x; this.y -= vec.y; this.z -= vec.z; return this; } ~略~ } --------------------------------------------------
swordone

2016/03/07 16:24

ちなみに方程式を解く場合は、行列を使って解くことができます。
guest

0

2 つの方法を述べます。

方法 1:

次の 2 つの条件を満たすようにする事として考えていきます。
(1) 直線 A - A' と 直線 A - B は直交する
(2) 直線 A - A' と 直線 C - A' は直交する
(A, B, C が一直線上に並んでいなければ、a' は1つだけ求まるはずです)

直交するかどかは 3 平方の定理で
(直線 B - A' の長さ) ^ 2 = (直線 A - B の長さ) ^ 2 + (直線 A - A'の長さ) ^ 2
でチェックできます。

2点 (x0, y0, z0), (x1, y1, z1) の長さ ^ 2 は
(x1 - x0) ^ 2 + (y1 - y0) ^ 2 + (z1 - z-) ^ 2
でもとまります。

A = (x0, y0, z0)
B = (x1, y1, z1)
C = (x2, y2, z2)
A' = (x, y, z)
のように変数を設定して、(1), (2) の関係を数式にすると、
x, y , z を含む 2 つの式ができます。
この式を変形させて x =..., y = ..., z = ... とすればよいはずです。

方法 2:

A, B, C を並行移動、回転をさせて
B = (0, 0, 0), A = (xa, ya, 0). C = (xc, yc, 0)
になるようにすれば,
A' = (xa, yc, 0)
です。
元に場所に戻るように回転、移動を (xa, yc, 0) にほどこせば、A' がもとまります。

点の回転、移動は、行列計算で表現できます。
イメージ説明

投稿2016/03/05 22:43

編集2016/03/06 12:31
katoy

総合スコア22324

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

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

b7n

2016/03/05 23:58

大変わかりやすく解説いただきありがとうございます。 イメージはできたのですがいざプログラムにしようとすると、 ①直交の関係の数式 ②行列の回転移動の具体的なプログラム、また、どのように移動、回転するのか などがわからず、困ってしまいました。 具体的なプログラムを挙げてもらえませんか?
guest

0

まず、点Aと点Bの距離をLとします。
そして、点Aが原点(x:0, y:0, z:0)に、点Bが垂直(x:0, y:L, z:0)になるように、点Cに平行移動と回転の座標変換Tを掛け、点C''を求めます。
この時、点C''のy値を0にしたものが点A''、同じくy値をLにしたものが点B''となります。
最後に、先ほど掛けた座標変換Tの逆変換T'を点A''と点B''にそれぞれ掛ければ、点A'と点B'が求められます。

投稿2016/03/05 17:58

編集2016/03/05 18:02
Stripe

総合スコア2183

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

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

b7n

2016/03/05 23:59

回答ありがとうございます。 > 点Cに平行移動と回転の座標変換T がよくわからないので、具体的なプログラムを挙げてもらえませんか?
Stripe

2016/03/06 15:26

とりあえず、平行移動の座標変換は簡単に作れますよね?
guest

0

中学か高校でならった一次関数の考え方を使ってはどうでしょうか。

  1. 直線ABと平行(変化の割合が同じ)で点Cを通る直線の式を求める
  2. 点Aを通り直背ABと垂直に交わる(変化の割合の積が-1)直線の式を求める
  3. 1と2の交点の座標を求める => A'の座標です。

投稿2016/03/05 16:37

編集2016/03/05 22:27
sekitaka_1214

総合スコア509

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

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

Stripe

2016/03/05 17:31

二次関数だと曲線になりますが??
sekitaka_1214

2016/03/05 22:26

失礼しました。1次関数ですね。
b7n

2016/03/06 00:04

回答ありがとうございます。 空間図形において、 「一次関数を2点から求める」 プログラムや、 「垂直に交わる直線の式」 を求める方法がよくわからないので、 具体的なプログラムを挙げてもらえませんか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問