/**
 * قȂʒuɂ2̓_ABԂ̋擾
 * 
 * @param {Integer} ax _AxW
 * @param {Integer} ay _AyW
 * @param {Integer} bx _BxW
 * @param {Integer} by _ByW
 * @returns {Integer} _ABԂ̋
 */
function GetGapLength(ax,ay,bx,by){
	return ( ( bx - ax ) ^ 2 + ( by - ay ) ^ 2 ) ^ 0.5;
}

/**
 * _AقȂʒuɂ_Bւ̐Ίpx擾
 * 
 * @param {Integer} ax _AxW
 * @param {Integer} ay _AyW
 * @param {Integer} bx _BxW
 * @param {Integer} by _ByW
 * @returns {Integer} _A_Bւ̐Ίpx
 */
function GetGapAngle(ax,ay,bx,by){
	return atan2( by - ay, bx - ax );
}

/**
 * _A炠鋗AΊpxɂ_BxW擾
 * 
 * @param {Integer} ax        _AxW
 * @param {Integer} gaplength _B܂ł̋
 * @param {Integer} gapangle  _Bւ̐Ίpx
 * @returns {Integer} _BxW
 */
function GetGapX(ax,gaplength,gapangle){
	return ax + gaplength * cos(gapangle);
}

/**
 * _A炠鋗AΊpxɂ_ByW擾
 * 
 * @param {Integer} ay        _AyW
 * @param {Integer} gaplength _B܂ł̋
 * @param {Integer} gapangle  _Bւ̐Ίpx
 * @returns {Integer} _ByW
 */
function GetGapY(ay,gaplength,gapangle){
	return ay + gaplength * sin(gapangle);
}

/**
 * ^ꂽpx0ȏ360ɂĕԂ
 * 
 * @param {Integer} angle px
 * @returns {Integer} ꂽpx
 */
function RollAngle(angle){
	return ( ( angle % 360 ) + 360) % 360;
}

/**
 * px␳z[~O֐
 * 
 * @param {Integer} x      ݈ʒuxW
 * @param {Integer} y      ݈ʒuyW
 * @param {Integer} tox    ǔڕWxW
 * @param {Integer} toy    ǔڕWyW
 * @param {Integer} nangle ݂̊px
 * @param {Integer} dangle px␳ʍől
 * @returns {Integer} z[~O␳̊px
 */
function AngleSearch(x,y,tox,toy,nangle,dangle){
	let TargetAngle = atan2(toy - y,tox - x);
	let ICross = cos(nangle - TargetAngle);
	let CCross = cos(dangle);
	
	if(ICross < CCross){
		let LCross = cos(nangle - dangle - TargetAngle);
		let RCross = cos(nangle + dangle - TargetAngle);
		if(LCross > RCross){
			nangle -= dangle;
		}else{
			nangle += dangle;
		}
	}else{
		nangle = TargetAngle;
	}
	
	return nangle;
}

/**
 * 3DW2DWɕϊ
 * 
 * @param {Integer} x xW
 * @param {Integer} y yW
 * @param {Integer} z zW
 * @param {Integer} a x̉]px
 * @param {Integer} b ỷ]px
 * @param {Integer} c z̉]px
 * @returns {Array} xW,yW,zW̔z[x,y,z]
 */
function Conv3Dto2D(x,y,z,a,b,c){
	let xyz = [x,y,z];
	
	xyz = RollZ(xyz[0],xyz[1],xyz[2],c);
	xyz = RollX(xyz[0],xyz[1],xyz[2],a);
	xyz = RollY(xyz[0],xyz[1],xyz[2],b);
	
	return xyz;
}

function RollX(x,y,z,a){
	let xx = x;
	let yy = y * cos(a) - z * sin(a);
	let zz = y * sin(a) + z * cos(a);
	
	return [xx,yy,zz];
}

function RollY(x,y,z,a){
	let xx = z * sin(a) + x * cos(a);
	let yy = y;
	let zz = z * cos(a) - x * sin(a);
	
	return [xx,yy,zz];
}

function RollZ(x,y,z,a){
	let xx = x * cos(a) - y * sin(a);
	let yy = x * sin(a) + y * cos(a);
	let zz = z;
	
	return [xx,yy,zz];
}

/**
 * _(x,y)pxangleňƕǂƂ̌_AˊpԂ
 * 
 * @param {Integer} x     w_xW
 * @param {Integer} y     w_yW
 * @param {Integer} angle px
 * @returns {Array} ǂƂ̌_Aˊp[rx,ry,rangle]
 */
function GetReflectData(x,y,angle){
	let rx = 0;
	let ry = 0;
	let rangle = 0;
	
	// ɂ邽߂̏I_ݒ
	let tox = x + cos(angle) * 800;	// Kɑ傫lŏI_쐬
	let toy = y + sin(angle) * 800;	// Kɑ傫lŏI_쐬
	
	// ȗ̂߁Bl̕ϐ錾Ăꍇɂ͏ĂOK
	let MinX = GetClipMinX();
	let MaxX = GetClipMaxX();
	let MinY = GetClipMinY();
	let MaxY = GetClipMaxY();
	
	// ㉺Eɑ΂Ĕs
	let PosU = Collision_Line_Line(x,y,tox,toy,MinX,MinY,MaxX,MinY);
	let PosL = Collision_Line_Line(x,y,tox,toy,MinX,MinY,MinX,MaxY);
	let PosR = Collision_Line_Line(x,y,tox,toy,MaxX,MinY,MaxX,MaxY);
	let PosB = Collision_Line_Line(x,y,tox,toy,MinX,MaxY,MaxX,MaxY);
	
	// ʂɂĂǂ̕ǂŔ˂邩I ㉺ȄŔ肳܂
	if( PosU[0] != NULL ){
		// ゾ
		rx = PosU[0];
		ry = PosU[1];
		rangle = -angle;
	}else if( PosB[0] != NULL ){
		// 
		rx = PosB[0];
		ry = PosB[1];
		rangle = -angle;
	}else if( PosL[0] != NULL ){
		// 
		rx = PosL[0];
		ry = PosL[1];
		rangle = 180 - angle;
	}else if( PosR[0] != NULL ){
		// E
		rx = PosR[0];
		ry = PosR[1];
		rangle = 180 - angle;
	}else{
		// ǂɂ˂ĂȂꍇA_~[ƂČ̒lZbg
		rx = x;
		ry = y;
		rangle = angle;
	}
	
	return [rx,ry,rangle];
}

/**
 * (x1,y1)-(x2,y2)Ɛ(x3,y3)-(x4,y4)̌_Ԃ
 * 
 * @param {Integer} x1 1̎n_xW
 * @param {Integer} y1 1̎n_yW
 * @param {Integer} x2 1̏I_xW
 * @param {Integer} y2 1̏I_yW
 * @param {Integer} x3 2̎n_xW
 * @param {Integer} y3 2̎n_yW
 * @param {Integer} x4 2̏I_xW
 * @param {Integer} y4 2̏I_yW
 * @returns {Array} 2̌_[x,y] Ȃꍇɂ[NULL,NULL]Ԃ
 */
function Collision_Line_Line(x1,y1,x2,y2,x3,y3,x4,y4){
	let f1 = x2 - x1;
	let g1 = y2 - y1;
	let f2 = x4 - x3;
	let g2 = y4 - y3;
	
	let det = (f2 * g1) - (f1 * g2);
	
	// det̒l0(2)̏ꍇ_݂Ȃ̂Ŗ߂
	if(det == 0){
		return [NULL,NULL];
	}else{
		// ȊȌꍇA_vZ
		let dx = x3 - x1;
		let dy = y3 - y1;
		let t1 = (f2 * dy - g2 * dx) / det;
		let t2 = (f1 * dy - g1 * dx) / det;
		
		// _̒ɑ݂Ȃ琔lvZ
		if( (0 <= t1 && t1 <= 1) && (0 <= t2 && t2 <= 1) ){
			let rx = x1 + t1 * f1;
			let ry = y1 + t1 * g1;
			
			return [rx,ry];
		}else{
			// _̉ɂꍇA_ȂƂ
			return [NULL,NULL];
		}
	}
}