マウスのx座標とy座標の2つを返り値とした関数を作りたい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Nekonami
記事: 21
登録日時: 10年前

マウスのx座標とy座標の2つを返り値とした関数を作りたい

#1

投稿記事 by Nekonami » 10年前

初投稿です。C言語もまだ始めたての学生です。
DXライブラリでゲーム作りをしていて、混乱してしまったので質問させていただきます。

メニューの操作をマウスでさせようと思い、キーボードで操作させたときと同じように
「メニュー本体」と「マウス操作」に分けてソースを書いています。
「マウス操作」内でGetMousePoint関数を使って取得したマウスカーソルの座標を、「メニュー本体」に関数の返り値として返したいのですが、
x座標、y座標をひとつの関数で返せなくて困っています。

x座標を返す関数、y座標を返す関数と別々で作れば解決するのですが、
管理がしにくく、見た目的にも微妙です。

ポインタを使う方法もあるようですが、ソースが別々なので混乱しています。
具体的にどのようにするといいか教えてください。
また、ポインタを使わずに返す方法があれば教えてください。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#2

投稿記事 by みけCAT » 10年前

Nekonami さんが書きました:ポインタを使わずに返す方法があれば教えてください。
C++なら、戻り値として構造体またはstd::pairを使用すればいいです。

コード:

struct point_t {
    int x,y;
}

point_t getMousePoint(void) {
    point_t ret;
    ret.x=マウスのx座標;
    ret.y=マウスのy座標;
    return ret;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#3

投稿記事 by みけCAT » 10年前

Nekonami さんが書きました:具体的にどのようにするといいか教えてください。
C++なら引数としてポインタを渡し、その指す先に座標を格納すればいいです。

コード:

void getMousePoint(int* x,int* y) {
    *x=マウスのx座標;
    *y=マウスのy座標;
}
Nekonami さんが書きました:ポインタを使わずに返す方法があれば教えてください。
C++ならポインタの代わりに参照が利用できます。

コード:

void getMousePoint(int& x,int& y) {
    x=マウスのx座標;
    y=マウスのy座標;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#4

投稿記事 by softya(ソフト屋) » 10年前

C言語の文法でも構造体なら戻り値として使えますよ。

コード:

#include<stdio.h>
struct point_t
{
    int x,y;
};

struct point_t getMousePoint(void)
{
    struct point_t ret;
    ret.x=10;//サンプルなので固定値
    ret.y=11;//サンプルなので固定値
    return ret;
}

int main( void )
{
	struct point_t point;
	point = getMousePoint();
	printf( "(%d,%d)", point.x, point.y );
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#5

投稿記事 by ISLe » 10年前

GetMousePoint関数がx座標とy座標をひとつの関数で返しているんですけどね。

こんな関数だったら作る意味がないですね。

コード:

int MyGetMousePoint(int *xPos, int *yPos)
{
    return GetMousePoint(xPos, yPos);
}

アバター
あたっしゅ
記事: 664
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#6

投稿記事 by あたっしゅ » 10年前

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

 上記のリンク先も参考にしてください。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#7

投稿記事 by みけCAT » 10年前

構造体のポインタを渡す、という方法もあります。

コード:

struct point_t {
    int x,y;
};

void getMousePoint(point_t* p) {
    p->x=マウスのx座標;
    p->y=マウスのy座標;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#8

投稿記事 by Nekonami » 10年前

ありがとうございます。構造体を使う方法がわかりやすそうです。

どうにも座標で指定しようとすると、複雑な形のボタンが作れなさそうです。
httpのように、画像をクリックしたら〜というような指定はできないのでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#9

投稿記事 by みけCAT » 10年前

Nekonami さんが書きました:httpのように、画像をクリックしたら〜というような指定はできないのでしょうか?
HTTPに「画像をクリックしたら〜というような指定」をする機能はない気がしますが、何のことでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#10

投稿記事 by みけCAT » 10年前

Nekonami さんが書きました:httpのように、画像をクリックしたら〜というような指定はできないのでしょうか?
いいえ。DXライブラリを使用したプログラムでは、HTTPとは違って、
画像を表示し、その画像を表示している部分のクリック判定を行うクラスを作成するなどの実装をすることにより、
「画像をクリックしたら~というような指定」に近いものができると思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#11

投稿記事 by Nekonami » 10年前

みけCAT さんが書きました: いいえ。DXライブラリを使用したプログラムでは、HTTPとは違って、
画像を表示し、その画像を表示している部分のクリック判定を行うクラスを作成するなどの実装をすることにより、
「画像をクリックしたら~というような指定」に近いものができると思います。
ありがとうございます。
表示している部分のクリック判定はどのように行えばいいでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#12

投稿記事 by みけCAT » 10年前

Nekonami さんが書きました:表示している部分のクリック判定はどのように行えばいいでしょうか?
「どのように行えばいいでしょうか?」→「適切な計算式による計算で行えばいいです。」

具体的に、どのような形のボタンを作りたいですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#13

投稿記事 by Nekonami » 10年前

みけCAT さんが書きました: 具体的に、どのような形のボタンを作りたいですか?
円、六角形などです。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#14

投稿記事 by みけCAT » 10年前

円は、円の中心とマウスの座標の位置の距離(ユークリッド距離)が円の半径以下なら円の中にマウスの座標があります。
六角形(または任意の多角形)は三角形に分割し、
それぞれの三角形について、図のような方法で判定を行えばいいと思います。
p,qは連立方程式を解けば求まります。
in_triangle_judge.png
点が三角形の中に入っているかの判定法
in_triangle_judge.png (17.96 KiB) 閲覧数: 12350 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#15

投稿記事 by Nekonami » 10年前

みけCAT さんが書きました:円は、円の中心とマウスの座標の位置の距離(ユークリッド距離)が円の半径以下なら円の中にマウスの座標があります。
六角形(または任意の多角形)は三角形に分割し、
それぞれの三角形について、図のような方法で判定を行えばいいと思います。
p,qは連立方程式を解けば求まります。
ありがとうございました!挑戦してみたいと思います。
最後に編集したユーザー Nekonami on 2014年3月31日(月) 22:09 [ 編集 1 回目 ]

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#16

投稿記事 by Nekonami » 10年前

すみません、だいぶ日が空いてしまいました。
みけ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;
// まだここまでです
}
【追記】一旦解決済みは消させていただきます。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#17

投稿記事 by みけCAT » 10年前

Nekonami さんが書きました:ベクトルとは、座標のことを指しているのでしょうか?
違います。ベクトルは「向きと長さを持った量」です。
ここでは、線分を「始点」と「始点から終点に移動するときの移動量」で表しています。
この「始点から終点に移動するときの移動量」がベクトルになります。
Nekonami さんが書きました:説明不足ですみません。まだベクトルの概念も理解していないのでこのような質問をさせていただきました。
補足になるかわかりませんが、自分なりに考えたソースコードを貼っておきます。
三角形は二等辺三角形になるようにしています。
赤ベクトルが底辺で…という感じです。
よろしくお願いします。
・ベクトルの算出は(冗長ですが)正しいと思います。
・「頂点のY座標は底辺の中点のY座標と同じ」というコメントは間違っていると思います。
・三角形にマウスカーソルがあるか判定するには、三角形の情報の他にマウスカーソルの情報も必要です。
・そもそも戻り値がvoidですが、どのように判定結果を返すのでしょうか?

【追記】コードを解釈した図を貼っておきます。
Nekonami_vector.png
No: 16のコードの解釈
Nekonami_vector.png (1.67 KiB) 閲覧数: 12197 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#18

投稿記事 by Nekonami » 10年前

みけCAT さんが書きました:
Nekonami さんが書きました:ベクトルとは、座標のことを指しているのでしょうか?
・「頂点のY座標は底辺の中点のY座標と同じ」というコメントは間違っていると思います。
・三角形にマウスカーソルがあるか判定するには、三角形の情報の他にマウスカーソルの情報も必要です。
・そもそも戻り値がvoidですが、どのように判定結果を返すのでしょうか?
Y座標ではなくX座標でした。頂点から垂線を引いたときに底辺の中点と交わる、という風に言いたかったんです。
それとvoidはまだ返り値を返す段階ではなかったのでとりあえず書きました。悪い癖ですね。気をつけます。

ベクトルの値の求め方はとりあえずあっているようでしたので、そこから判定につなげる為にもう一つ。
連立方程式を解くということですが、2つの式は具体的にどのようになりますか?(数学の問題になりますかね…汗)

【追記】コード解釈の画像はその通りです。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#19

投稿記事 by みけCAT » 10年前

緑ベクトルを(GreenVektor_X, GreenVektor_Y)と仮定します。

連立方程式はNo: 14の画像の下に書いてあるように、

コード:

RedVektor_X*p + BlueVektor_X*q = GreenVektor_X
RedVektor_Y*p + BlueVektor_Y*q = GreenVektor_Y
です。
未知変数はp,q、他は定数(既知)です。
オフトピック
ベクトルはvektorではなくvectorと書くのが正式ですが…
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#20

投稿記事 by Nekonami » 10年前

みけCAT さんが書きました:緑ベクトルを(GreenVektor_X, GreenVektor_Y)と仮定します。

連立方程式はNo: 14の画像の下に書いてあるように、

コード:

RedVektor_X*p + BlueVektor_X*q = GreenVektor_X
RedVektor_Y*p + BlueVektor_Y*q = GreenVektor_Y
です。
未知変数はp,q、他は定数(既知)です。
XとYでそれぞれ式を立てればよかったのですね。ありがとうございます。
また何か質問する機会があればよろしくお願いします。
みけCAT さんが書きました:
オフトピック
ベクトルはvektorではなくvectorと書くのが正式ですが…
オフトピック
vektorはドイツ語らしいです。ひょえー。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#21

投稿記事 by みけCAT » 10年前

Nekonami さんが書きました:
みけCAT さんが書きました:
オフトピック
ベクトルはvektorではなくvectorと書くのが正式ですが…
オフトピック
vektorはドイツ語らしいです。ひょえー。
なるほど、そうでしたか。
ドイツ語-英語 翻訳:: Vektor :: 辞書
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#22

投稿記事 by Nekonami » 10年前

とりあえず三角形、円の2つとも完成しました。
(ベクトルを求める式、よく見たら無駄だらけでした…)

これで大丈夫ですかね?

コード:

// 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;
	}
}

【追記】円のdouble型は関数 hypot を hypotf にしてfloat型にしてもいいと思いますか?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#23

投稿記事 by みけCAT » 10年前

円の当たり判定は大丈夫だと思いますが、三角形はどう考えてもダメです。
・p,qが初期化されていないように見える
・マウスカーソルの情報が使用されていない
・PointVector_X、PointVector_Yが使用されていない
・そもそも0と1の間の数を扱うのに、p,qはint型ではダメ
逆になぜこれで完成したと思ったのですか?自分でテストしたのですか?
Nekonami さんが書きました:【追記】円のdouble型は関数 hypot を hypotf にしてfloat型にしてもいいと思いますか?
はい。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
usao
記事: 1887
登録日時: 11年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#24

投稿記事 by usao » 10年前

> RedVektor_X*p + BlueVektor_X*q = GreenVektor_X
> RedVektor_Y*p + BlueVektor_Y*q = GreenVektor_Y

この連立方程式を p,q について解かなければならないのであって,
この式をそのままコーディングすれば良いというわけではないと思いますよ.

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#25

投稿記事 by Nekonami » 10年前

みけCAT さんが書きました:円の当たり判定は大丈夫だと思いますが、三角形はどう考えてもダメです。
・p,qが初期化されていないように見える
・マウスカーソルの情報が使用されていない
・PointVector_X、PointVector_Yが使用されていない
・そもそも0と1の間の数を扱うのに、p,qはint型ではダメ
逆になぜこれで完成したと思ったのですか?自分でテストしたのですか?
先ほど修正してテストしてみましたが、関数がマウスカーソルの位置に関係なく1を返しています。
コードを貼っておきます。

コード:

#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 について解かなければならないのであって,
この式をそのままコーディングすれば良いというわけではないと思いますよ.
コードを見返してみても連立方程式の部分に問題があるのでは、と思いました。
それぞれについて解けばいいのですね。やってみます。

また夜に結果を報告したいと思います。

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#26

投稿記事 by Nekonami » 10年前

もしよろしければ、なぜこの式を使うことで判定できるか詳しく解説して頂けませんか?
理解を深めて応用を利かせられるようにしたいです。

アバター
usao
記事: 1887
登録日時: 11年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#27

投稿記事 by usao » 10年前

ベクトルの話ができないと非常に説明し難い気がしますが,
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に関する条件に一致しますね.)

アバター
usao
記事: 1887
登録日時: 11年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#28

投稿記事 by usao » 10年前

>緑の矢印を,赤の矢印(をp倍に伸縮したもの)と青の矢印(をq倍〃)の和で表す,ということを考えたら
>pとqはそれぞれどんな値になるか? という話です.

これをもっと簡単に言うと,
矢印の根元の場所から,緑矢印の先端の場所 まで行きたいです.
しかし,直接移動可能な方向は,赤矢印(に平行な)方向と,青矢印(〃)方向 に限定されています.
では,
赤方向にどれだけ(赤矢印のp倍)進んで,その後青方向にどれだけ(青矢印のq倍)進めば 目的の位置に行けるでしょうか?
みたいなことですね.

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#29

投稿記事 by Nekonami » 10年前

usaoさん、ご返信ありがとうございます。
ベクトルについてまだ学習してないので理解できたかわかりませんが、力の分解のようなことでしょうか?
自分なりの解釈をまとめた画像を貼っておきます。
添付ファイル
Vector.png
Vector.png (10.87 KiB) 閲覧数: 11947 回

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#30

投稿記事 by Nekonami » 10年前

一応三角形内にあるか判定できるようになりました。
(連立方程式は知人に手伝ってもらいながら解きました。)

ただ、予定している黄色い三角形の範囲より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;
}  

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#31

投稿記事 by みけCAT » 10年前

割り算を整数で行っているのが問題ですね。
割られる値/割る値をfloatにキャストしてから割り算をしてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#32

投稿記事 by Nekonami » 10年前

みけCAT さんが書きました:割り算を整数で行っているのが問題ですね。
割られる値/割る値をfloatにキャストしてから割り算をしてください。
というと、RedVector_XやBlueVector_Yなどをすべてfloatにキャストしてしまえばいいのですか?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#33

投稿記事 by みけCAT » 10年前

Nekonami さんが書きました:
みけCAT さんが書きました:割り算を整数で行っているのが問題ですね。
割られる値/割る値をfloatにキャストしてから割り算をしてください。
というと、RedVector_XやBlueVector_Yなどをすべてfloatにキャストしてしまえばいいのですか?
キャストというより、それらの変数の型を最初からfloatにすればいいと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Nekonami
記事: 21
登録日時: 10年前

Re: マウスのx座標とy座標の2つを返り値とした関数を作りたい

#34

投稿記事 by Nekonami » 10年前

アドバイスを基に修正してみたらうまくいきました。
みけ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;
}  

閉鎖

“C言語何でも質問掲示板” へ戻る