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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

Q&A

解決済

1回答

1295閲覧

C++ DirectX ある点に最も近い球上の点を求めたい

m35

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

0グッド

0クリップ

投稿2022/02/02 01:49

編集2022/02/02 01:51

_### //点p0に最も近い球上の点p2を求めなさい。_
⚠spはsphere(球)のことです。

ベクトルd =(球体の中心の位置ベクトルー任意の点の位置ベクトル)
球面上の最も近い点=任意の点+(ベクトルdの長さー半径)×dの単位ベクトル

という式をもとに、自力で作成してみたのですが、うまくいきません。
どこが間違っているのか見当がつかないので、質問させてもらいました。

//球体の中心の位置ベクトル DirectX::XMVECTOR SPC = DirectX::XMLoadFloat3(&sp.c); //任意の点の位置ベクトル DirectX::XMVECTOR P0 = DirectX::XMLoadFloat3(&p0); //ベクトルd DirectX::XMVECTOR DirectionVec = DirectX::XMVectorSubtract(SPC, P0); //ベクトルdの長さ DirectX::XMFLOAT3 lengthD; DirectX::XMStoreFloat3(&lengthD, DirectionVec); //ベクトルdの長さ - 半径 変数 DirectX::XMFLOAT3 DirectionVecSubtractRadius; DirectionVecSubtractRadius.x = lengthD - sp.r; DirectionVecSubtractRadius.y = lengthD - sp.r; DirectionVecSubtractRadius.z = lengthD - sp.r; //(ベクトルdの長さ - 半径) × dの単位ベクトル 変数 DirectX::XMVECTOR XYZVECTOR = DirectX::XMLoadFloat3(&DirectionVecSubtractRadius); //dの単位ベクトルを作って DirectX::XMVector3Normalize(DirectionVec); //掛け算する(Scaleパターンも一応試しました) XYZVECTOR = DirectX::XMVector3Cross(DirectionVec, XYZVECTOR); //球面上の最も近い点から任意の点をなくしたもの DirectX::XMFLOAT3 xyz; DirectX::XMStoreFloat3(&xyz, XYZVECTOR); //任意の点 + 球面上の最も近い点任意の点をなくしたもの = 球面上の最も近い点? p2.x = p0.x + xyz.x; p2.y = p0.y + xyz.y; p2.z = p0.z + xyz.z;

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

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

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

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

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

fana

2022/02/02 02:34

> どこが間違っているのか見当がつかない とのことですが, 逆に何の演算を行っているのか見当も付きません. > …という式をもとに なる話通りの演算を行ってみてはどうですか? その話に外積が出てくるとは思えないのですが,XMVector3Cross を持ち出している個所では一体何の演算をしているのですか? > ベクトルdの長さ って言われたら,ふつーはスカラー量を考えると思うのですが,あなたの言う「長さ」とは一体何なのですか?
m35

2022/02/02 02:37

FLOAT distance(DirectX::XMFLOAT3 p1, DirectX::XMFLOAT3 p2) { FLOAT dist; dist = sqrtf((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y) + (p2.z - p1.z) * (p2.z - p1.z) ); return dist; } //DirectX::XMVECTOR SPR = DirectX::XMLoadFloat3(&sp.r); /*DirectX::XMFLOAT3 normalizeVecD; DirectX::XMVector3Normalize(D); DirectX::XMStoreFloat3(&normalizeVecD, D);*/ #if 0 /* DirectX::XMFLOAT3 lengthD; DirectX::XMStoreFloat3(&lengthD, DirectX::XMVector3Length(D));*/ float lengthD = distance(sp.c, p0); DirectX::XMVector3Normalize(DirectionVec); DirectX::XMFLOAT3 XYZ; DirectX::XMStoreFloat(&XYZ.x, DirectX::XMVectorScale(DirectionVec, (lengthD - sp.r))); DirectX::XMStoreFloat(&XYZ.y, DirectX::XMVectorScale(DirectionVec, (lengthD - sp.r))); DirectX::XMStoreFloat(&XYZ.z, DirectX::XMVectorScale(DirectionVec, (lengthD - sp.r))); p2.x = p0.x + XYZ.x; p2.y = p0.y + XYZ.y; p2.z = p0.z + XYZ.z; #elif 0 質問しかしていないと捉えられているのであれば、ものすごく不愉快なので反論します。 一番合っている可能性が高いものを質問に出しているだけであって、何回も、数日間、数パターン試行錯誤して、見当がつかないし、解答も来なさそうなのでこちらに投稿しました。 適当に質問丸投げして解決してくれたらありがたいんですけどね(笑) 1時間くらい考えても、答えにたどり着けないからここにきているのです。 ご理解の程よろしくお願いします。
m35

2022/02/02 02:41

アドバイスありがとうございます。 上記の通り、長さ をスカラー値で取って動かしてもだめでした。 もう一度長さをスカラー値で取って作り直してみます。
m35

2022/02/02 03:04

//ベクトルdの長さ float lengthD = distance(sp.c, p0); //ベクトルdの長さ - 半径 変数 DirectX::XMFLOAT3 DirectionVecSubtractRadius; DirectionVecSubtractRadius.x = lengthD - sp.r; DirectionVecSubtractRadius.y = lengthD - sp.r; DirectionVecSubtractRadius.z = lengthD - sp.r; //球面上の最も近い点から任意の点をなくしたもの DirectX::XMFLOAT3 xyz; //dの単位ベクトルを作って DirectX::XMVector3Normalize(DirectionVec); //掛け算する xyz.x = DirectX::XMVectorGetX(DirectX::XMVectorScale(DirectionVec, DirectionVecSubtractRadius.x)); xyz.y = DirectX::XMVectorGetY(DirectX::XMVectorScale(DirectionVec, DirectionVecSubtractRadius.y)); xyz.z = DirectX::XMVectorGetZ(DirectX::XMVectorScale(DirectionVec, DirectionVecSubtractRadius.z)); //任意の点 + 球面上の最も近い点任意の点をなくしたもの = 球面上の最も近い点? p2.x = p0.x + xyz.x; p2.y = p0.y + xyz.y; p2.z = p0.z + xyz.z; やはりだめでした。 変な演算に関しては至極真っ当な意見だと思います。 3Dプログラミングを初めて半年も満たないくらいの初心者なので、コード全体を俯瞰してみることができないレベルにおり、自分でも何をしているのか分かっていないのです。 ただ、バカなりに色々試行錯誤してみてはいるので、その辺はご了承ください。
fana

2022/02/02 04:01

> デバッグしたら良いのではありませんか? ここが最も重要なところね. コード全体を見るとかそういう話じゃなくて. > ベクトルd =(球体の中心の位置ベクトルー任意の点の位置ベクトル) > 球面上の最も近い点=任意の点+(ベクトルdの長さー半径)×dの単位ベクトル っていう演算で目的を達成できるのか否か,という理屈の部分は紙上ででも確認できる. ↓ ここがOKならば,紙上での計算通りに進むコードを書くわけだ. で,実装して動かしたら変な結果が出るなら,「紙上での計算通りに進んでるか否か」を確認すべきでしょ,っていう. 各演算の結果値が紙上での値と一致しているのか否かを上から順に見ていけばよい. ある時点で食い違ったならばその場所の実装が間違っている.それだけの話.
fana

2022/02/02 04:08

想定通りの演算結果が得られているか否かを確認する作業をする. そのためにはもちろん「各演算の想定通りの結果って何?」っていうのを把握しておく必要がある. 「長さってスカラーちゃうの?」とか言ってるのは,そもそもの話(数学の部分)はちゃんとわかってるのか?ってことね. これはコードを書く以前のところ.プログラミングと全然関係ない部分. もしもそこができてないなら目の前のコードをこねくり回していても何も解決しないわけなので.
m35

2022/02/02 04:13

なるほどですね!今までしっかりと紙で計算してこなかったので、このようなデバッグ方法があるとは思いつきませんでした。 各演算の結果値が紙上での値と一致しているのか否かを上から順に見ていけばよい. もしかしたら、私のプログラミング人生を大きく変えてくれる一言かもしれません。 肝心の問題は解けていませんが、より大きな収穫があったと思います。 本当にありがとうございます。
fana

2022/02/02 04:23

何やら終了したみたいですが,「ベクトルdが零ベクトルの場合はどうすんの?」みたいな話とかも適切にデバッグなされるがよろしいかと.
guest

回答1

0

ベストアンサー

XMVector3Normalize 関数について調べてみましょう。
この関数は引数に渡した変数を勝手に書き換えてくれる訳ではありません。

投稿2022/02/02 04:02

yaito3014

総合スコア176

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問