特定の角度を返す関数

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
dic
記事: 656
登録日時: 13年前
住所: 宮崎県
連絡を取る:

特定の角度を返す関数

#1

投稿記事 by dic » 2年前

お世話になっています。dicです。

今回は、ホーミング機能と同じ、タップしたところにプレイヤーが移動するように
タップした位置と、現在の位置の角度をもとめたいのですが、うまくいきません。

どこの計算がマズいでしょうか?
よろしくお願いします。

コード:

#include "DxLib.h"
#include <stdio.h>
#include "common.h"

int		s_iPlayerImage = 0;
int		s_iBackImage = 0;

static double s_iPlayerPosX = 500;
static double s_iPlayerPosY = 500;

void	Player1Input();






void	Player1Draw()
{
	DrawGraph(s_iPlayerPosX, s_iPlayerPosY, s_iPlayerImage, TRUE );
}


double	GetAngle(int x, int y, int x2, int y2)
{
	double angle = 0;

	double a, b, c;
	a = b = c = 0.0;
	
	a = abs(x2 - x);
	b = abs(y2 - y);
	c = sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));

	double si, co;
	si = co = 0.0;
	si = b / c;
	co = a / c;

	angle = 180 / (si * 3.1415);

	DrawLine(x, y, x2, y2, GetColor(255, 255, 255));
	DrawFormatString(100,  20, GetColor(255, 255, 255), "a:%f", a);
	DrawFormatString(100,  40, GetColor(255, 255, 255), "b:%f", b);
	DrawFormatString(100,  60, GetColor(255, 255, 255), "co:%f", c);
	DrawFormatString(100,  80, GetColor(255, 255, 255), "si:%f", si);
	DrawFormatString(100, 100, GetColor(255, 255, 255), "co:%f", co);
	DrawFormatString(100, 120, GetColor(255, 255, 255), "angle:%f", angle);

	return angle;
}

void	Player1Input()
{
	int PosX, PosY;
	PosX = PosY = 0;
	GetTouchInput(0, &PosX, &PosY, NULL, NULL);

	if ((PosX > 0) && (PosY > 0))
	{
		double angle;
		angle = GetAngle(s_iPlayerPosX, s_iPlayerPosY, PosX, PosY);

		double X, Y, speed;
		X = Y = 0;
		speed = 1.0;

		X = speed * cos(angle);
		Y = speed * sin(angle);

		s_iPlayerPosX += X;
		s_iPlayerPosY += Y;

		DrawFormatString(100, 140, GetColor(255, 255, 255), "X:%f", X);
		DrawFormatString(100, 160, GetColor(255, 255, 255), "Y:%f", Y);
	}
}






void	Stage1Init()
{
	s_iPlayerImage = LoadGraph("player.png");
	s_iBackImage = LoadGraph("cosmo.jpg");
}


void	Stage1MainLoop()
{
	DrawGraph(0, 0, s_iBackImage, true);

	Player1Input();
	Player1Draw();
}

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

Re: 特定の角度を返す関数

#2

投稿記事 by usao » 2年前

> a = abs(x2 - x);
> b = abs(y2 - y);

なぜ abs ?

---

> angle = 180 / (si * 3.1415);

これは何を計算している?

---

・角度が欲しいなら atan2 でも使えばいいんじゃないかな.自前で計算する必要ある?
・それ以前に sin と cos の値が必要な場面なのであれば,そもそも「角度」を計算する必要すら無いっていう.

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

Re: 特定の角度を返す関数

#3

投稿記事 by usao » 2年前

あと,

> si = b / c;

みたいなのがノーチェックで書いてあるように見えるけど,
「2点が同一座標である場合にはどうするのか?」っていうのも考えた方が良いのではないかな.

dic
記事: 656
登録日時: 13年前
住所: 宮崎県
連絡を取る:

Re: 特定の角度を返す関数

#4

投稿記事 by dic » 2年前

>> a = abs(x2 - x);
>> b = abs(y2 - y);
>
>なぜ abs ?
x2 > x のときと x > x2 の2通りがあるので



>> angle = 180 / (si * 3.1415);
>
>これは何を計算している?
Θから度数に変換してます。


atan2 は中身がわからないので、使えないのです。

dic
記事: 656
登録日時: 13年前
住所: 宮崎県
連絡を取る:

Re: 特定の角度を返す関数

#5

投稿記事 by dic » 2年前

昔できてたんですけど、ソースコード一式
なくしてしまって、また作るハメになりました

dic
記事: 656
登録日時: 13年前
住所: 宮崎県
連絡を取る:

Re: 特定の角度を返す関数

#6

投稿記事 by dic » 2年前

コードは下のようにできたのですが、x座標がマイナスの値をとらずに困ってます。
どこか間違っているでしょうか?
動かないのでコメントアウトしてます。

コード:


void	Player1Input()
{
	int PosX, PosY;
	PosX = PosY = 0;
	GetTouchInput(0, &PosX, &PosY, NULL, NULL);

	if ((PosX > 0) && (PosY > 0))
	{
		double X, Y, speed;
		X = Y = 0;
		speed = 1.0;

		//	各辺の長さを求める
		double a, b, c;
		a = b = c = 0.0;
		a = (PosX - s_iPlayerPosX);
		b = (PosY - s_iPlayerPosY);
		c = sqrt((s_iPlayerPosX - PosX) * (s_iPlayerPosX - PosX) + (s_iPlayerPosY - PosY) * (s_iPlayerPosY - PosY));

		//	sin, cos のラジアンを求める
		double si, co;
		si = co = 0.0;
		si = b / c;
		co = a / c;

		//	スピードと角度を掛ける
		X = speed * cos(co);
		Y = speed * sin(si);

		//	座標を更新する
//		s_iPlayerPosX += X;
		s_iPlayerPosY += Y;

		DrawFormatString(100, 140, GetColor(255, 255, 255), "X:%f", X);
		DrawFormatString(100, 160, GetColor(255, 255, 255), "Y:%f", Y);
	}
}

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

Re: 特定の角度を返す関数

#7

投稿記事 by usao » 2年前

> si = b / c;
> co = a / c;

えっとー,これが sin と cos の値なんだよね?
それなのに,これを cos(co) だとか sin(si) だとかいう使い方するのはおかしいよね?

dic
記事: 656
登録日時: 13年前
住所: 宮崎県
連絡を取る:

Re: 特定の角度を返す関数

#8

投稿記事 by dic » 2年前

>えっとー,これが sin と cos の値なんだよね?
>それなのに,これを cos(co) だとか sin(si) だとかいう使い方するのはおかしいよね?
わかりません、どうすればいいのでしょうか?

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

Re: 特定の角度を返す関数

#9

投稿記事 by usao » 2年前

どうやらプログラミング以前の話と見えるので,「三角関数」でググるとかした方が早いと思う.
(ここまでの話が理解できない状態では,このような場所でのやりとりは不可能であろう)

コーディングよりも先に,まず数学の復習が必要であろう.

dic
記事: 656
登録日時: 13年前
住所: 宮崎県
連絡を取る:

Re: 特定の角度を返す関数

#10

投稿記事 by dic » 2年前

すいません、別の方
答えていただけないでしょうか?

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

Re: 特定の角度を返す関数

#11

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

「角度」を求めようとせず、正規化した「方向ベクトル」を求め、それを用いて移動するのはどうですか?

コード:

void	Player1Input()
{
	int PosX, PosY;
	PosX = PosY = 0;
	GetTouchInput(0, &PosX, &PosY, NULL, NULL);

	if ((PosX > 0) && (PosY > 0))
	{
		double X, Y, speed;
		X = Y = 0;
		speed = 1.0;

		//	各辺の長さを求める
		double a, b, c;
		a = b = c = 0.0;
		a = (PosX - s_iPlayerPosX);
		b = (PosY - s_iPlayerPosY);
		c = sqrt((s_iPlayerPosX - PosX) * (s_iPlayerPosX - PosX) + (s_iPlayerPosY - PosY) * (s_iPlayerPosY - PosY));

		//	正規化した方向ベクトルを求める
		double nx, ny;
		nx = a / c;
		ny = b / c;

		//	スピードと方向ベクトルを掛ける
		X = speed * nx;
		Y = speed * ny;

		//	座標を更新する
		s_iPlayerPosX += X;
		s_iPlayerPosY += Y;

		DrawFormatString(100, 140, GetColor(255, 255, 255), "X:%f", X);
		DrawFormatString(100, 160, GetColor(255, 255, 255), "Y:%f", Y);
	}
}
※動作未確認です。typoなどあるかもしれません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: 特定の角度を返す関数

#12

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

どうしても「角度」を求めたいのであれば、三角関数が目的の値を返す角度を二分探索する方法もあるかもしれません。
dic さんが書きました:
2年前
atan2 は中身がわからないので、使えないのです。
atanは使えますか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

dic
記事: 656
登録日時: 13年前
住所: 宮崎県
連絡を取る:

Re: 特定の角度を返す関数

#13

投稿記事 by dic » 2年前

みけCATさん

方向ベクトルというのですね、
習った覚えがない・・・
ベクトルは今勉強中です。(すこーしずつ)

無事、思ったようにタップした位置にプレイヤーが移動するようになりました。
解決しました。ありがとうございました。


そうですね、角度は sin[360], cos[360] という配列を用意して、
ソートしながら近い値を返そうかと思います。
二分探索木は、難しそうなので、のちのちの挑戦にとっておきます。

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

Re: 特定の角度を返す関数

#14

投稿記事 by usao » 2年前

> 正規化した「方向ベクトル」を求め

それが sin と cos なわけだがw

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

Re: 特定の角度を返す関数

#15

投稿記事 by usao » 2年前

オフトピック
> えっとー,これが sin と cos の値なんだよね?

の意味が理解できないのに
変数名を nx,ny に変えてやれば「解決」するんかい?

「解決」ってのは「そのままパクれるコードそのものが出てくること」なのかな?
(#まぁ今回の場合だと,そのままパクったら無事に済みそうにはないが)

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

Re: 特定の角度を返す関数

#16

投稿記事 by usao » 2年前

オフトピック
> 三角関数が目的の値を返す角度を二分探索する

解を囲み込むのに工夫が要りそうな…?
(そのへんをやりやすい形の目的関数を立てるのかな?)

返信

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