マウスのx座標とy座標の2つを返り値とした関数を作りたい
マウスのx座標とy座標の2つを返り値とした関数を作りたい
初投稿です。C言語もまだ始めたての学生です。
DXライブラリでゲーム作りをしていて、混乱してしまったので質問させていただきます。
メニューの操作をマウスでさせようと思い、キーボードで操作させたときと同じように
「メニュー本体」と「マウス操作」に分けてソースを書いています。
「マウス操作」内でGetMousePoint関数を使って取得したマウスカーソルの座標を、「メニュー本体」に関数の返り値として返したいのですが、
x座標、y座標をひとつの関数で返せなくて困っています。
x座標を返す関数、y座標を返す関数と別々で作れば解決するのですが、
管理がしにくく、見た目的にも微妙です。
ポインタを使う方法もあるようですが、ソースが別々なので混乱しています。
具体的にどのようにするといいか教えてください。
また、ポインタを使わずに返す方法があれば教えてください。
DXライブラリでゲーム作りをしていて、混乱してしまったので質問させていただきます。
メニューの操作をマウスでさせようと思い、キーボードで操作させたときと同じように
「メニュー本体」と「マウス操作」に分けてソースを書いています。
「マウス操作」内でGetMousePoint関数を使って取得したマウスカーソルの座標を、「メニュー本体」に関数の返り値として返したいのですが、
x座標、y座標をひとつの関数で返せなくて困っています。
x座標を返す関数、y座標を返す関数と別々で作れば解決するのですが、
管理がしにくく、見た目的にも微妙です。
ポインタを使う方法もあるようですが、ソースが別々なので混乱しています。
具体的にどのようにするといいか教えてください。
また、ポインタを使わずに返す方法があれば教えてください。
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
C++なら、戻り値として構造体またはstd::pairを使用すればいいです。Nekonami さんが書きました:ポインタを使わずに返す方法があれば教えてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
C++なら引数としてポインタを渡し、その指す先に座標を格納すればいいです。Nekonami さんが書きました:具体的にどのようにするといいか教えてください。
C++ならポインタの代わりに参照が利用できます。Nekonami さんが書きました:ポインタを使わずに返す方法があれば教えてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
C言語の文法でも構造体なら戻り値として使えますよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
int MouseX, MouseY;
int res = GetMousePoint( &MouseX, &MouseY );
// これで、MouseX にマウスの X 座標, MouseY にマウスの Y 座標が入っています。
昔の C は、今の C/C++ と違って、構造体を返すことができなかったので、
2つ以上の値を返す時はポインタを渡していました。
しかし、構造体を返すと、変数のコピーが行われ、
大きな構造体の場合はコピー処理の時間がもったいないので、
いまでも、ポインタを渡す方法が用いられることが多いです。
http://www1.cts.ne.jp/~clab/hsample/Point/Point18.html
http://oshiete.goo.ne.jp/qa/3955714.html
上記のリンク先も参考にしてください。
int res = GetMousePoint( &MouseX, &MouseY );
// これで、MouseX にマウスの X 座標, MouseY にマウスの Y 座標が入っています。
昔の C は、今の C/C++ と違って、構造体を返すことができなかったので、
2つ以上の値を返す時はポインタを渡していました。
しかし、構造体を返すと、変数のコピーが行われ、
大きな構造体の場合はコピー処理の時間がもったいないので、
いまでも、ポインタを渡す方法が用いられることが多いです。
http://www1.cts.ne.jp/~clab/hsample/Point/Point18.html
http://oshiete.goo.ne.jp/qa/3955714.html
上記のリンク先も参考にしてください。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
ありがとうございます。構造体を使う方法がわかりやすそうです。
どうにも座標で指定しようとすると、複雑な形のボタンが作れなさそうです。
httpのように、画像をクリックしたら〜というような指定はできないのでしょうか?
どうにも座標で指定しようとすると、複雑な形のボタンが作れなさそうです。
httpのように、画像をクリックしたら〜というような指定はできないのでしょうか?
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
HTTPに「画像をクリックしたら〜というような指定」をする機能はない気がしますが、何のことでしょうか?Nekonami さんが書きました:httpのように、画像をクリックしたら〜というような指定はできないのでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
いいえ。DXライブラリを使用したプログラムでは、HTTPとは違って、Nekonami さんが書きました:httpのように、画像をクリックしたら〜というような指定はできないのでしょうか?
画像を表示し、その画像を表示している部分のクリック判定を行うクラスを作成するなどの実装をすることにより、
「画像をクリックしたら~というような指定」に近いものができると思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
ありがとうございます。みけCAT さんが書きました: いいえ。DXライブラリを使用したプログラムでは、HTTPとは違って、
画像を表示し、その画像を表示している部分のクリック判定を行うクラスを作成するなどの実装をすることにより、
「画像をクリックしたら~というような指定」に近いものができると思います。
表示している部分のクリック判定はどのように行えばいいでしょうか?
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
「どのように行えばいいでしょうか?」→「適切な計算式による計算で行えばいいです。」Nekonami さんが書きました:表示している部分のクリック判定はどのように行えばいいでしょうか?
具体的に、どのような形のボタンを作りたいですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
円、六角形などです。みけCAT さんが書きました: 具体的に、どのような形のボタンを作りたいですか?
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
円は、円の中心とマウスの座標の位置の距離(ユークリッド距離)が円の半径以下なら円の中にマウスの座標があります。
六角形(または任意の多角形)は三角形に分割し、
それぞれの三角形について、図のような方法で判定を行えばいいと思います。
p,qは連立方程式を解けば求まります。
六角形(または任意の多角形)は三角形に分割し、
それぞれの三角形について、図のような方法で判定を行えばいいと思います。
p,qは連立方程式を解けば求まります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
ありがとうございました!挑戦してみたいと思います。みけCAT さんが書きました:円は、円の中心とマウスの座標の位置の距離(ユークリッド距離)が円の半径以下なら円の中にマウスの座標があります。
六角形(または任意の多角形)は三角形に分割し、
それぞれの三角形について、図のような方法で判定を行えばいいと思います。
p,qは連立方程式を解けば求まります。
最後に編集したユーザー Nekonami on 2014年3月31日(月) 22:09 [ 編集 1 回目 ]
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
すみません、だいぶ日が空いてしまいました。
みけCATさんが用意して下さった画像を元にやってみたのですが、ベクトルがどういう値か理解できず、しばらく別のことをしていました。(すみません)
ベクトルとは、座標のことを指しているのでしょうか?
画像右上の式を見て、X座標とY座標それぞれでX2-X1、Y1-Y2 (ミス)Y2-Y1というように値を引いて新たに座標を出したのですが…
説明不足ですみません。まだベクトルの概念も理解していないのでこのような質問をさせていただきました。
補足になるかわかりませんが、自分なりに考えたソースコードを貼っておきます。
三角形は二等辺三角形になるようにしています。
赤ベクトルが底辺で…という感じです。
よろしくお願いします。
【追記】一旦解決済みは消させていただきます。
みけCATさんが用意して下さった画像を元にやってみたのですが、ベクトルがどういう値か理解できず、しばらく別のことをしていました。(すみません)
ベクトルとは、座標のことを指しているのでしょうか?
画像右上の式を見て、X座標とY座標それぞれでX2-X1、Y1-Y2 (ミス)Y2-Y1というように値を引いて新たに座標を出したのですが…
説明不足ですみません。まだベクトルの概念も理解していないのでこのような質問をさせていただきました。
補足になるかわかりませんが、自分なりに考えたソースコードを貼っておきます。
三角形は二等辺三角形になるようにしています。
赤ベクトルが底辺で…という感じです。
よろしくお願いします。
// 三角形内にマウスカーソルがあるか判定 (左の底角のX座標, Y座標, 底辺の長さ, 三角形の高さ(三角形の頂点が上ならマイナスで示す))
void JudgeMousePoint_Triangle(int StartPoint_X, int StartPoint_Y, int Length_W, int Length_H){
int RedVektor_X = (StartPoint_X + Length_W) - StartPoint_X,
RedVektor_Y = 0, // StartPoint_Y - StartPoint_Y つまり 0
BlueVektor_X = (StartPoint_X + (Length_W / 2 /*頂点のY座標は底辺の中点のY座標と同じ*/)) - StartPoint_X,
BlueVektor_Y = (StartPoint_Y + Length_H) - StartPoint_Y;
// まだここまでです
}
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
違います。ベクトルは「向きと長さを持った量」です。Nekonami さんが書きました:ベクトルとは、座標のことを指しているのでしょうか?
ここでは、線分を「始点」と「始点から終点に移動するときの移動量」で表しています。
この「始点から終点に移動するときの移動量」がベクトルになります。
・ベクトルの算出は(冗長ですが)正しいと思います。Nekonami さんが書きました:説明不足ですみません。まだベクトルの概念も理解していないのでこのような質問をさせていただきました。
補足になるかわかりませんが、自分なりに考えたソースコードを貼っておきます。
三角形は二等辺三角形になるようにしています。
赤ベクトルが底辺で…という感じです。
よろしくお願いします。
・「頂点のY座標は底辺の中点のY座標と同じ」というコメントは間違っていると思います。
・三角形にマウスカーソルがあるか判定するには、三角形の情報の他にマウスカーソルの情報も必要です。
・そもそも戻り値がvoidですが、どのように判定結果を返すのでしょうか?
【追記】コードを解釈した図を貼っておきます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
Y座標ではなくX座標でした。頂点から垂線を引いたときに底辺の中点と交わる、という風に言いたかったんです。みけCAT さんが書きました:・「頂点のY座標は底辺の中点のY座標と同じ」というコメントは間違っていると思います。Nekonami さんが書きました:ベクトルとは、座標のことを指しているのでしょうか?
・三角形にマウスカーソルがあるか判定するには、三角形の情報の他にマウスカーソルの情報も必要です。
・そもそも戻り値がvoidですが、どのように判定結果を返すのでしょうか?
それとvoidはまだ返り値を返す段階ではなかったのでとりあえず書きました。悪い癖ですね。気をつけます。
ベクトルの値の求め方はとりあえずあっているようでしたので、そこから判定につなげる為にもう一つ。
連立方程式を解くということですが、2つの式は具体的にどのようになりますか?(数学の問題になりますかね…汗)
【追記】コード解釈の画像はその通りです。
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
緑ベクトルを(GreenVektor_X, GreenVektor_Y)と仮定します。
連立方程式はNo: 14の画像の下に書いてあるように、 です。
未知変数はp,q、他は定数(既知)です。
連立方程式はNo: 14の画像の下に書いてあるように、 です。
未知変数はp,q、他は定数(既知)です。
オフトピック
ベクトルはvektorではなくvectorと書くのが正式ですが…
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
XとYでそれぞれ式を立てればよかったのですね。ありがとうございます。
また何か質問する機会があればよろしくお願いします。
みけCAT さんが書きました:オフトピックベクトルはvektorではなくvectorと書くのが正式ですが…
オフトピック
vektorはドイツ語らしいです。ひょえー。
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
なるほど、そうでしたか。Nekonami さんが書きました:みけCAT さんが書きました:オフトピックベクトルはvektorではなくvectorと書くのが正式ですが…オフトピックvektorはドイツ語らしいです。ひょえー。
ドイツ語-英語 翻訳:: Vektor :: 辞書
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
とりあえず三角形、円の2つとも完成しました。
(ベクトルを求める式、よく見たら無駄だらけでした…)
これで大丈夫ですかね?
【追記】円のdouble型は関数 hypot を hypotf にしてfloat型にしてもいいと思いますか?
(ベクトルを求める式、よく見たら無駄だらけでした…)
これで大丈夫ですかね?
// m_Point はマウスカーソルの座標
// hypot はリファレンス math.h 内の関数
// 三角形内にマウスカーソルがあるか判定 (左の底角のX座標, Y座標, 底辺の長さ, 三角形の高さ(三角形の頂点が上にあるならマイナスで示す))
int JudgeMousePoint_Triangle(int StartPoint_X, int StartPoint_Y, int Length_W, int Length_H){
// 三角形の底辺になるベクトル
int RedVector_X = Length_W, // (StartPoint_X + Length_W) - StartPoint_X つまり Length_W
RedVector_Y = 0, // StartPoint_Y - StartPoint_Y つまり 0
// 三角形の左の斜辺になるベクトル
BlueVector_X = Length_W / 2, // (StartPoint_X + (Length_W / 2)) - StartPoint_X つまり Length_W / 2
BlueVector_Y = Length_H; // (StartPoint_Y + Length_H) - StartPoint_Y つまり Length_H
int p, q;
int PointVector_X = RedVector_X*p + BlueVector_X*q, // StartPointから現在のマウスカーソルまでのベクトル
PointVector_Y = RedVector_Y*p + BlueVector_Y*q;
if(0 <= p && 0 <= q && p + q <= 1){ // 三角形内にマウスカーソルがあれば
return 1;
}else{
return 0;
}
}
// 円内にマウスカーソルがあるか判定 (円の中心のX座標, Y座標, 半径)
int JudgeMousePoint_Circle(int StartPoint_X, int StartPoint_Y, double Radius){
int Length_W = m_Point_X - StartPoint_X, // 直角三角形の底辺
Length_H = m_Point_Y - StartPoint_Y; // 直角三角形の高さ
if(Length_H > 0){ // Heightがマイナスなら
Length_H = -Length_H; // プラスにする
}
double Distance = hypot(Length_W, Length_H); // 円の中心からマウスカーソルまでの距離(斜辺の長さ)を求める
if(Distance <= Radius){ // 円内にマウスカーソルがあれば
return 1;
}else{
return 0;
}
}
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
円の当たり判定は大丈夫だと思いますが、三角形はどう考えてもダメです。
・p,qが初期化されていないように見える
・マウスカーソルの情報が使用されていない
・PointVector_X、PointVector_Yが使用されていない
・そもそも0と1の間の数を扱うのに、p,qはint型ではダメ
逆になぜこれで完成したと思ったのですか?自分でテストしたのですか?
・p,qが初期化されていないように見える
・マウスカーソルの情報が使用されていない
・PointVector_X、PointVector_Yが使用されていない
・そもそも0と1の間の数を扱うのに、p,qはint型ではダメ
逆になぜこれで完成したと思ったのですか?自分でテストしたのですか?
はい。Nekonami さんが書きました:【追記】円のdouble型は関数 hypot を hypotf にしてfloat型にしてもいいと思いますか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
> RedVektor_X*p + BlueVektor_X*q = GreenVektor_X
> RedVektor_Y*p + BlueVektor_Y*q = GreenVektor_Y
この連立方程式を p,q について解かなければならないのであって,
この式をそのままコーディングすれば良いというわけではないと思いますよ.
> RedVektor_Y*p + BlueVektor_Y*q = GreenVektor_Y
この連立方程式を p,q について解かなければならないのであって,
この式をそのままコーディングすれば良いというわけではないと思いますよ.
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
先ほど修正してテストしてみましたが、関数がマウスカーソルの位置に関係なく1を返しています。みけCAT さんが書きました:円の当たり判定は大丈夫だと思いますが、三角形はどう考えてもダメです。
・p,qが初期化されていないように見える
・マウスカーソルの情報が使用されていない
・PointVector_X、PointVector_Yが使用されていない
・そもそも0と1の間の数を扱うのに、p,qはint型ではダメ
逆になぜこれで完成したと思ったのですか?自分でテストしたのですか?
コードを貼っておきます。
#include "DxLib.h"
int m_Point_X, m_Point_Y; // マウスカーソル座標
// 三角形内にマウスカーソルがあるか判定 (左の底角のX座標, Y座標, 底辺の長さ, 三角形の高さ(三角形の頂点が上にあるならマイナスで示す))
int JudgeMousePoint_Triangle(int StartPoint_X, int StartPoint_Y, int Length_W, int Length_H){
// 三角形の底辺になるベクトル
int RedVector_X = Length_W, // (StartPoint_X + Length_W) - StartPoint_X つまり Length_W
RedVector_Y = 0, // StartPoint_Y - StartPoint_Y つまり 0
// 三角形の左の斜辺になるベクトル
BlueVector_X = Length_W / 2, // (StartPoint_X + (Length_W / 2)) - StartPoint_X つまり Length_W / 2
BlueVector_Y = Length_H; // (StartPoint_Y + Length_H) - StartPoint_Y つまり Length_H
float p = 0, q = 0;
GetMousePoint(&m_Point_X,&m_Point_Y);
int PointVector_X = m_Point_X - StartPoint_X, // StartPointから現在のマウスカーソルまでのベクトル
PointVector_Y = m_Point_Y - StartPoint_Y;
// この下を修正してみます
PointVector_X = RedVector_X*p + BlueVector_X*q;
PointVector_Y = RedVector_Y*p + BlueVector_Y*q;
if(0 <= p && 0 <= q && p + q <= 1){ // 三角形内にマウスカーソルがあれば
return 1;
}else{
return 0;
}
}
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
int White = GetColor( 255, 255, 255 );
int Yellow = GetColor( 255 , 255 , 0 );
// 判定が行われる三角形を描画
DrawTriangle(100,100, 200,100, 150,200, Yellow, TRUE);
int a = JudgeMousePoint_Triangle(100,100,100,100);
if(a == 1){
DrawFormatString( 0, 0, White, "ok"); // 文字を描画する
}
}
DxLib_End(); // DXライブラリ終了処理
return 0;
}
コードを見返してみても連立方程式の部分に問題があるのでは、と思いました。usao さんが書きました:> RedVektor_X*p + BlueVektor_X*q = GreenVektor_X
> RedVektor_Y*p + BlueVektor_Y*q = GreenVektor_Y
この連立方程式を p,q について解かなければならないのであって,
この式をそのままコーディングすれば良いというわけではないと思いますよ.
それぞれについて解けばいいのですね。やってみます。
また夜に結果を報告したいと思います。
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
もしよろしければ、なぜこの式を使うことで判定できるか詳しく解説して頂けませんか?
理解を深めて応用を利かせられるようにしたいです。
理解を深めて応用を利かせられるようにしたいです。
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
ベクトルの話ができないと非常に説明し難い気がしますが,
No.14のみけCATさんの図で言えば,
要は,その連立方程式を解く というのは,
緑の矢印を,赤の矢印(をp倍に伸縮したもの)と青の矢印(をq倍〃)の和で表す,ということを考えたら
pとqはそれぞれどんな値になるか? という話です.
p,qの満たすべき条件に関しては,
赤と青の矢印の成す角が直角な場合を考えてみるとわかりやすいかもしれません.
例えば,一方がX軸に,他方がY軸に沿うような場面ですね.
さらに考えやすく,この2の矢印(ベクトル)の長さが共に1な場合を考えるとわかりやすいです.
緑の矢印というのは判定したい実際の点の座標(x,y)を表しています.
これが,三つの点{ (0,0), (1,0), (0,1) }で作られる三角形の内部にあるかどうかを判定するにはどうすればいいか.
x >= 0
y >= 0
でなければならないことはすぐにわかります.
さらに,緑の矢印の先端(x,y)が三角形の斜辺よりも向こう側に行かないためには
x + y <= 1
である必要があります.
…で,説明しにくいのですが,このような条件を 赤と青の2つの矢印がいろんな取り方の場合にも考えると
その連立方程式と,p,qの条件になる,と.
(ここで説明した最も考えやすい場合について 連立方程式を考えてみると
x = 1*p + 0*q
y = 0*p + 1*q
みたくなりますね.つまりこの場合,x==pであり,y==qです.
↑に書いたxとyに関する3つの満たすべき条件のx,yをp,qに置き換えれば,
みけCATさんが書かれたp,qに関する条件に一致しますね.)
No.14のみけCATさんの図で言えば,
要は,その連立方程式を解く というのは,
緑の矢印を,赤の矢印(をp倍に伸縮したもの)と青の矢印(をq倍〃)の和で表す,ということを考えたら
pとqはそれぞれどんな値になるか? という話です.
p,qの満たすべき条件に関しては,
赤と青の矢印の成す角が直角な場合を考えてみるとわかりやすいかもしれません.
例えば,一方がX軸に,他方がY軸に沿うような場面ですね.
さらに考えやすく,この2の矢印(ベクトル)の長さが共に1な場合を考えるとわかりやすいです.
緑の矢印というのは判定したい実際の点の座標(x,y)を表しています.
これが,三つの点{ (0,0), (1,0), (0,1) }で作られる三角形の内部にあるかどうかを判定するにはどうすればいいか.
x >= 0
y >= 0
でなければならないことはすぐにわかります.
さらに,緑の矢印の先端(x,y)が三角形の斜辺よりも向こう側に行かないためには
x + y <= 1
である必要があります.
…で,説明しにくいのですが,このような条件を 赤と青の2つの矢印がいろんな取り方の場合にも考えると
その連立方程式と,p,qの条件になる,と.
(ここで説明した最も考えやすい場合について 連立方程式を考えてみると
x = 1*p + 0*q
y = 0*p + 1*q
みたくなりますね.つまりこの場合,x==pであり,y==qです.
↑に書いたxとyに関する3つの満たすべき条件のx,yをp,qに置き換えれば,
みけCATさんが書かれたp,qに関する条件に一致しますね.)
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
>緑の矢印を,赤の矢印(をp倍に伸縮したもの)と青の矢印(をq倍〃)の和で表す,ということを考えたら
>pとqはそれぞれどんな値になるか? という話です.
これをもっと簡単に言うと,
矢印の根元の場所から,緑矢印の先端の場所 まで行きたいです.
しかし,直接移動可能な方向は,赤矢印(に平行な)方向と,青矢印(〃)方向 に限定されています.
では,
赤方向にどれだけ(赤矢印のp倍)進んで,その後青方向にどれだけ(青矢印のq倍)進めば 目的の位置に行けるでしょうか?
みたいなことですね.
>pとqはそれぞれどんな値になるか? という話です.
これをもっと簡単に言うと,
矢印の根元の場所から,緑矢印の先端の場所 まで行きたいです.
しかし,直接移動可能な方向は,赤矢印(に平行な)方向と,青矢印(〃)方向 に限定されています.
では,
赤方向にどれだけ(赤矢印のp倍)進んで,その後青方向にどれだけ(青矢印のq倍)進めば 目的の位置に行けるでしょうか?
みたいなことですね.
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
usaoさん、ご返信ありがとうございます。
ベクトルについてまだ学習してないので理解できたかわかりませんが、力の分解のようなことでしょうか?
自分なりの解釈をまとめた画像を貼っておきます。
ベクトルについてまだ学習してないので理解できたかわかりませんが、力の分解のようなことでしょうか?
自分なりの解釈をまとめた画像を貼っておきます。
- 添付ファイル
-
- Vector.png (10.87 KiB) 閲覧数: 11947 回
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
一応三角形内にあるか判定できるようになりました。
(連立方程式は知人に手伝ってもらいながら解きました。)
ただ、予定している黄色い三角形の範囲より2回りくらい大きい三角形で判定しているようです。
問題箇所を教えて下さい。
(連立方程式は知人に手伝ってもらいながら解きました。)
ただ、予定している黄色い三角形の範囲より2回りくらい大きい三角形で判定しているようです。
問題箇所を教えて下さい。
#include "DxLib.h"
int m_Point_X, m_Point_Y; // マウスカーソル座標
// 三角形内にマウスカーソルがあるか判定 (左の底角のX座標, Y座標, 底辺の長さ, 三角形の高さ(三角形の頂点が上にあるならマイナスで示す))
int JudgeMousePoint_Triangle(int StartPoint_X, int StartPoint_Y, int Length_W, int Length_H){
// 三角形の底辺になるベクトル
int RedVector_X = Length_W, // (StartPoint_X + Length_W) - StartPoint_X つまり Length_W
RedVector_Y = 0, // StartPoint_Y - StartPoint_Y つまり 0
// 三角形の左の斜辺になるベクトル
BlueVector_X = Length_W / 2, // (StartPoint_X + (Length_W / 2)) - StartPoint_X つまり Length_W / 2
BlueVector_Y = Length_H; // (StartPoint_Y + Length_H) - StartPoint_Y つまり Length_H
float p = 0, q = 0;
GetMousePoint(&m_Point_X,&m_Point_Y);
int PointVector_X = m_Point_X - StartPoint_X, // StartPointから現在のマウスカーソルまでのベクトル
PointVector_Y = m_Point_Y - StartPoint_Y;
p = (BlueVector_Y * PointVector_X - BlueVector_X * PointVector_Y) / (RedVector_X * BlueVector_Y - RedVector_Y * BlueVector_X);
q = (RedVector_X * PointVector_Y - RedVector_Y * PointVector_X) / (RedVector_X * BlueVector_Y - RedVector_Y * BlueVector_X);
if(0 <= p && 0 <= q && p + q <= 1){ // 三角形内にマウスカーソルがあれば
return 1;
}else{
return 0;
}
}
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
int White = GetColor( 255, 255, 255 );
int Yellow = GetColor( 255 , 255 , 0 );
// 判定が行われる三角形を描画
DrawTriangle(100,100, 200,100, 150,200, Yellow, TRUE);
int a = JudgeMousePoint_Triangle(100,100,100,100);
if(a == 1){
DrawFormatString( 0, 0, White, "ok"); // 文字を描画する
}
}
DxLib_End(); // DXライブラリ終了処理
return 0;
}
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
割り算を整数で行っているのが問題ですね。
割られる値/割る値をfloatにキャストしてから割り算をしてください。
割られる値/割る値をfloatにキャストしてから割り算をしてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
というと、RedVector_XやBlueVector_Yなどをすべてfloatにキャストしてしまえばいいのですか?みけCAT さんが書きました:割り算を整数で行っているのが問題ですね。
割られる値/割る値をfloatにキャストしてから割り算をしてください。
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
キャストというより、それらの変数の型を最初からfloatにすればいいと思います。Nekonami さんが書きました:というと、RedVector_XやBlueVector_Yなどをすべてfloatにキャストしてしまえばいいのですか?みけCAT さんが書きました:割り算を整数で行っているのが問題ですね。
割られる値/割る値をfloatにキャストしてから割り算をしてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい
アドバイスを基に修正してみたらうまくいきました。
みけCATさんはじめ、アドバイスを下さった皆さんありがとうございました。
以下、完成形のコードです。
みけCATさんはじめ、アドバイスを下さった皆さんありがとうございました。
以下、完成形のコードです。
#include "DxLib.h"
int m_Point_X, m_Point_Y; // マウスカーソル座標
// 三角形内にマウスカーソルがあるか判定 (左の底角のX座標, Y座標, 底辺の長さ, 三角形の高さ(三角形の頂点が上にあるならマイナスで示す))
int JudgeMousePoint_Triangle(int StartPoint_X, int StartPoint_Y, int Length_W, int Length_H){
// 三角形の底辺になるベクトル
float RedVector_X = Length_W, // (StartPoint_X + Length_W) - StartPoint_X つまり Length_W
RedVector_Y = 0, // StartPoint_Y - StartPoint_Y つまり 0
// 三角形の左の斜辺になるベクトル
BlueVector_X = Length_W / 2, // (StartPoint_X + (Length_W / 2)) - StartPoint_X つまり Length_W / 2
BlueVector_Y = Length_H; // (StartPoint_Y + Length_H) - StartPoint_Y つまり Length_H
float p = 0, q = 0;
GetMousePoint(&m_Point_X,&m_Point_Y);
float PointVector_X = m_Point_X - StartPoint_X, // StartPointから現在のマウスカーソルまでのベクトル
PointVector_Y = m_Point_Y - StartPoint_Y;
p = (BlueVector_Y * PointVector_X - BlueVector_X * PointVector_Y) / (RedVector_X * BlueVector_Y - RedVector_Y * BlueVector_X);
q = (RedVector_X * PointVector_Y - RedVector_Y * PointVector_X) / (RedVector_X * BlueVector_Y - RedVector_Y * BlueVector_X);
if(0 <= p && 0 <= q && p + q <= 1){ // 三角形内にマウスカーソルがあれば
return 1;
}else{
return 0;
}
}
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
int White = GetColor( 255, 255, 255 );
int Yellow = GetColor( 255 , 255 , 0 );
// 判定が行われる三角形を描画
DrawTriangle(100,100, 200,100, 150,200, Yellow, TRUE);
int a = JudgeMousePoint_Triangle(100,100,100,100);
if(a == 1){
DrawFormatString( 0, 0, White, "ok"); // 文字を描画する
}
}
DxLib_End(); // DXライブラリ終了処理
return 0;
}