等速系の命中計算(衝突半径を考慮する)
最速発射問題
tステップ後に発射した場合の(再接近距離)^2-(衝突半径)^2をグラフ化。
値が負の部分が衝突状態。衝突状態になる最小のtを求めればよい。
/**
* Copyright uwi ( http://wonderfl.net/user/uwi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/eOA3
*/
// forked from uwi's 等速系の命中計算(衝突半径を考慮しない)
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.getTimer;
import flash.display.Graphics;
// 最速発射問題
// tステップ後に発射した場合の(再接近距離)^2-(衝突半径)^2をグラフ化。
// 値が負の部分が衝突状態。衝突状態になる最小のtを求めればよい。
public class Test extends Sprite {
private var _tf : TextField;
// 自機の情報
private var _x0x : Number = 0;
private var _x0y : Number = 0;
private var _th0 : Number = 0;
// 弾速
private var _bv : Number = 7;
// 変位
private const PHI : Number = 0.1; // 1ステップでまわる角度
private const STEP : Number = 6.0; // 1ステップで進む距離
private const R : Number = STEP / (2 * Math.sin(PHI)); // いわゆる回転半径
private var _qx : Number; // 回転中心の位置
private var _qy : Number;
// 敵弾の情報
private var _exx : Number = 100;
private var _exy : Number = 100;
private var _evx : Number = -2;
private var _evy : Number = -3;
// 衝突判定距離
private var _cr : Number = 10;
public function Test() {
_tf = new TextField();
_tf.width = 465;
_tf.height = 465;
addChild(_tf);
var s : int = getTimer();
_qx = _x0x + R * Math.cos(_th0 + Math.PI / 2);
_qy = _x0y + R * Math.sin(_th0 + Math.PI / 2);
drawGraph(graphics, gmin, 0, 100, 1, 50, 450, 4, 0.01);
var g : int = getTimer();
tr((g - s) + " ms");
}
private function drawGraph(g : Graphics, f : Function, min : Number, max : Number, step : Number, ox : Number, oy : Number, scaleX : Number, scaleY : Number) : void
{
g.lineStyle(1, 0x000000);
g.moveTo(ox, oy); g.lineTo(max * scaleX + ox, oy);
g.lineStyle(2, 0x990000);
var y : Number = f(min);
var maxy : Number = y;
g.moveTo(min * scaleX + ox, -y * scaleY + oy);
for(var x : Number = min + step;x <= max;x += step){
y = f(x);
tr(x, y);
if(maxy < y)maxy = y;
g.lineTo(x * scaleX + ox, -y * scaleY + oy);
}
g.lineStyle(1, 0x000000);
g.moveTo(ox, oy); g.lineTo(ox, -maxy * scaleY + oy);
}
private function makeG(t : Number, u : Number) : Array
{
var vx : Array = xx(t);
var vw : Array = w(t);
return [
vx[0] + vw[0] * _bv * u - _exx - _evx * (t + u),
vx[1] + vw[1] * _bv * u - _exy - _evy * (t + u)
];
}
private function makeJ(t : Number, u : Number) : Array
{
var vdx : Array = dx(t);
var vw : Array = w(t);
var vdw : Array = dw(t);
return [
vdx[0] + vdw[0] * _bv * u - _evx,
vw[0] * _bv - _evx,
vdx[1] + vdw[1] * _bv * u - _evy,
vw[1] * _bv - _evx
];
}
private function gmin(t : Number) : Number
{
var vx : Array = xx(t);
var vw : Array = w(t);
var A : Array = [
vx[0] - _exx - _evx * t,
vx[1] - _exy - _evy * t
];
var B : Array = [
vw[0] * _bv - _evx,
vw[1] * _bv - _evy
];
var nB : Number = B[0] * B[0] + B[1] * B[1];
if(nB > 0.01){
var T : Number = -(A[0] * B[0] + A[1] * B[1]) / nB;
if(T >= 0){
A[0] += B[0] * T;
A[1] += B[1] * T;
}
}
return A[0] * A[0] + A[1] * A[1] - _cr * _cr;
}
private function xx(t : Number) : Array
{
return [
_qx + R * Math.cos(_th0 - Math.PI / 2 + t * 2 * PHI),
_qy + R * Math.sin(_th0 - Math.PI / 2 + t * 2 * PHI)
];
}
private function dx(t : Number) : Array
{
return [
2 * PHI * R * Math.cos(_th0 + t * 2 * PHI),
2 * PHI * R * Math.sin(_th0 + t * 2 * PHI),
];
}
private function w(t : Number) : Array
{
return [
Math.cos(_th0 + PHI * t),
Math.sin(_th0 + PHI * t)
];
}
private function dw(t : Number) : Array
{
return [
-PHI * Math.sin(_th0 + PHI * t),
PHI * Math.cos(_th0 + PHI * t)
];
}
private function tr(...o : Array) : void
{
_tf.appendText(o + "\n");
}
}
}