ライバルカーから見た視点を考える

OA・OB = |OA||OB|cosθ
|OA|=1
|OB|=1のとき
OA・OB = 1*1*cosθ = cosθ

 OA・OB
-------- = cosθ
|OA||OB|

OA={x1, y1}
OB={x2, y2}
OA・OB = x1*x2+y1*y2

	//車の基本方向を表すベクトル
	Vec2 sVec;
	//車の進行方向ベクトル
	Vec2 transVec;
	//車の位置 位置ベクトル Vec2
	Vec2 carPosition;
	//車の向き 回転角度 double
	double carRot;
	//車のスピード pixel/sec
	double speed;
"ライバルカーから見た視野判定"
# include <Siv3D.hpp> // OpenSiv3D v0.6.10
 
const double PI = 3.14159265359;
const double vLength = 60.0;
const Vec2 SCRSIZE{ 800, 600};
const Vec2 CHRSIZE{ 64,64 };
 
 
/// @brief 数学の座標をスクリーン座標に変換する関数
/// @param _point 変換前の数学座標
/// @return 変換されたスクリーン座標
Vec2 ConvertMath2Screen(Vec2 _point)
{
	Vec2 resultPoint;
	Vec2 halfScrSize = { Scene::Width() / 2.0, Scene::Height() / 2.0 };
	resultPoint.x = _point.x + halfScrSize.x;
	resultPoint.y = Scene::Height() - (_point.y + halfScrSize.y);
	return resultPoint;
}
 
/// @param _angle 角度を入力
/// @return  ラジアンに変換された値
double Degree2Radians(double _angle)
{
	return(_angle * (PI / 180.0));
}
 
/// @brief 座標軸を描く関数
void DrawAxis()
{
	Vec2 halfScrSize = { Scene::Width() / 2.0, Scene::Height() / 2.0 };
	Vec2 xAxisStart = { 0, halfScrSize.y };
	Vec2 xAxisEnd = { Scene::Width() , halfScrSize.y };
	Vec2 yAxisStart = { halfScrSize.x, Scene::Height() };
	Vec2 yAxisEnd = { halfScrSize.x, 0 };
	Line{ xAxisStart, xAxisEnd }.drawArrow(2, Vec2{ 5,5 }, Palette::Black);
	Line{ yAxisStart, yAxisEnd }.drawArrow(2, Vec2{ 5,5 }, Palette::Black);
}
 
/// @brief _angle度だけ_vecを原点中心に回転して返す
/// @param _vec 回転されるベクトル
/// @param _angle  回転角度(度)
/// @return  回転後のベクトル
Vec2 RotateVec(Vec2 _vec, double _angle)
{
	double theta = Degree2Radians(_angle); //ラジアン
	Vec2 res;
	res.x = _vec.x * cos(theta) - _vec.y * sin(theta);
	res.y = _vec.x * sin(theta) + _vec.y * cos(theta);
 
	return(res);
}
 
/* -----車のパラメータを表すグローバル変数たち----- */
struct Car {
	//車の基本方向を表すベクトル
	Vec2 sVec;
	//車の進行方向ベクトル
	Vec2 transVec;
	//車の位置 位置ベクトル Vec2
	Vec2 carPosition;
	//車の向き 回転角度 double
	double carRot;
	//車のスピード pixel/sec
	double speed;
};
/* ----------------------------------------------  */
 
//myCarの初期値設定
		 //sVec  transVec carPosition carRot speed
Car myCar{ {0,1}, {0,0},      {0,0},    0,    50.0 };
Car rivalCar{ {0,1}, {0,1.0},      {0,0},    -90,    50.0 };
 
//等速左右往復
void UpdateRivalCar() {
	//基本的に回転はcarRotのパラメータをベースに処理を行う
	//=>transVecは基本向きのベクトルをcarRot度回転させたものになる
	rivalCar.transVec = RotateVec(rivalCar.sVec, rivalCar.carRot);
	//ベクトル = ベクトル + スカラー*ベクトル*フレーム経過時間
	//フレーム経過時間をかけることによって、正確に1sあたりの移動量を計算する
	rivalCar.carPosition = rivalCar.carPosition
		+ rivalCar.speed * rivalCar.transVec * Scene::DeltaTime();
	const Vec2 HSCRSIZE{ SCRSIZE.x / 2, SCRSIZE.y / 2 };
 
	if (rivalCar.carPosition.x  > HSCRSIZE.x - CHRSIZE.x / 2 || rivalCar.carPosition.x  < -HSCRSIZE.x + CHRSIZE.x / 2) {
		if (rivalCar.carPosition.x < 0)
		{
			rivalCar.carPosition.x = -HSCRSIZE.x + CHRSIZE.x/2;
 
		}else
			rivalCar.carPosition.x = HSCRSIZE.x - CHRSIZE.x/2;
 
		rivalCar.carRot += 180;
		if (rivalCar.carRot > 360)
			rivalCar.carRot -= 360;
	}
	else
	{
		rivalCar.carPosition = rivalCar.carPosition
			+ rivalCar.speed * rivalCar.transVec * Scene::DeltaTime();
	}
}
 
void DrawViewRange(Car _car, Color _color)
{
	Vec2 rRange, lRange;
	const double rangeLength = 200.0;
	Vec2 tVec = _car.transVec;
	tVec.normalize();
	rRange = RotateVec(_car.transVec, -30);
	lRange = RotateVec(_car.transVec, 30);
	Triangle{ ConvertMath2Screen(_car.carPosition),
			 ConvertMath2Screen(_car.carPosition + rangeLength * rRange),
			 ConvertMath2Screen(_car.carPosition + rangeLength * lRange) }.draw({ _color,0.4 });
}
double GetDistance(Car _src, Car _target)
{
	double dist = ? ? ? ? ;
	return(dist);
}
bool IsViewTarget(Car _mySrc, Car _target)
{   //自分の進行方向と相手の角度が±30度以内 && 距離がviewDist以内ならtrue
	const double viewDist = 200;
	const double viewRange = 30;//自分の進行方向と±30度
	//ヒント、2台の車の進行方向のベクトルのなす角度が±30度だとcosθは
	//いくつからいくつの範囲になるかな?
}
 
 
void DrawRivalCar() {
	Texture carImg = TextureAsset(U"RIVAL");
	//ラジアンで回すのよ
	carImg.resized(CHRSIZE).rotated(Degree2Radians(-rivalCar.carRot)).drawAt(ConvertMath2Screen(rivalCar.carPosition));
	//車の向きのベクトルをvLengthの長さで描画
	Line{ ConvertMath2Screen(rivalCar.carPosition), ConvertMath2Screen(rivalCar.carPosition + vLength * rivalCar.transVec) }
	.drawArrow(3, { 6,6 }, Palette::Red);
	DrawViewRange(rivalCar, Palette::Aqua);
}
 
 
 
void UpdateMyCar()
{
	if (MouseL.pressed())
	{
		myCar.carRot += Scene::DeltaTime() * 90;
	}
	if (MouseR.pressed())
	{
		myCar.carRot -= Scene::DeltaTime() * 90;
	}
	myCar.transVec = RotateVec(myCar.sVec, myCar.carRot);
	//ベクトル = ベクトル + スカラー*ベクトル*フレーム経過時間
	//フレーム経過時間をかけることによって、正確に1sあたりの移動量を計算する
	myCar.carPosition = myCar.carPosition
		+ myCar.speed * myCar.transVec * Scene::DeltaTime();
}
 
void Update()
{
	UpdateRivalCar();
	UpdateMyCar();
	if (IsViewTarget(rivalCar, myCar))
		Print << U"見えた!";
 
}
 
 
void DrawMyCar()
{
	Texture carImg = TextureAsset(U"CAR");
	//ラジアンで回すのよ
	carImg.resized(CHRSIZE).rotated(Degree2Radians(-myCar.carRot)).drawAt(ConvertMath2Screen(myCar.carPosition));
	//車の向きのベクトルをvLengthの長さで描画
	Line{ ConvertMath2Screen(myCar.carPosition), ConvertMath2Screen(myCar.carPosition + vLength * myCar.transVec) }
	.drawArrow(3, { 6,6 }, Palette::Yellow);
}
 
void Draw()
{
	DrawRivalCar();
	DrawMyCar();
}
void Main()
{
	// 背景の色を設定する | Set the background color
	Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
 
	//// 絵文字からテクスチャを作成する | Create a texture from an emoji
	//const Texture emoji{ U"🦖"_emoji };
	//// 太文字のフォントを作成する | Create a bold font with MSDF method
	//const Font font{ FontMethod::MSDF, 48, Typeface::Bold };
	//// テキストに含まれる絵文字のためのフォントを作成し、font に追加する | Create a font for emojis in text and add it to font as a fallback
	//const Font emojiFont{ 48, Typeface::ColorEmoji };
	//font.addFallback(emojiFont);
 
	TextureAsset::Register(U"CAR", U"car.png");
	TextureAsset::Register(U"RIVAL", U"rival.png");
 
	Vec2 origin{ 0,0 };
	Vec2 sOrigin = ConvertMath2Screen(origin);
	Print << sOrigin;
	//
	//double rotation = 0;
 
	while (System::Update())
	{
		DrawAxis();
 
		Update();
 
		Draw();
	}
}