forked from: forked from: forked from: Trajectory Path formula
Click on stage and use arrow keys to shift start point. Takes into account both directions coming from under plane floor and above it. (yo >= 0 ? 1: -1 ) check (ie. double-sided plane)
/**
* Copyright Glidias ( http://wonderfl.net/user/Glidias )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/wk4j
*/
// forked from Glidias's forked from: forked from: Trajectory Path formula
// forked from Glidias's forked from: Trajectory Path formula
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Vector3D;
import flash.ui.Keyboard;
/**
* @author Glenn Ko
*/
[SWF(frameRate="60", backgroundColor="#FFFFFF")]
public class LobTrajectory extends Sprite
{
private var SPEED:Number = 244;
private var DRAW_SEGMENTS:int = 16;
private var startPosition:Point = new Point();
private var GRAVITY:Number = 266;
private var velocity:Point = new Point();
private var _displace:Point = new Point();
private var curPosition:Point = new Point();
private var curSprite:Sprite = new Sprite();
private var totalFlightTime:Number;
private var _tRise:Number;
private var _h:Number;
public function LobTrajectory()
{
y= -130;
startPosition.x = 150;
startPosition.y = stage.stageHeight -100;
curPosition = startPosition.clone();
drawPath();
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
curSprite.graphics.beginFill(0xFF0000);
curSprite.graphics.drawCircle(0, 0, 4);
addChild(curSprite);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDOwn);
}
private function onKeyDOwn(e:KeyboardEvent):void
{
var keyCode:uint = e.keyCode;
if (keyCode === Keyboard.NUMPAD_DIVIDE) {
onMouseMove(null);
}
else if (keyCode === Keyboard.NUMPAD_ADD) {
onMouseMove(null);
}
else if (keyCode === Keyboard.LEFT) {
startPosition.x--;
onMouseMove(null);
}
else if (keyCode === Keyboard.RIGHT) {
startPosition.x++;
onMouseMove(null);
}
else if (keyCode === Keyboard.UP) {
startPosition.y--;
onMouseMove(null);
}
else if (keyCode === Keyboard.DOWN) {
startPosition.y++;
onMouseMove(null);
}
}
private function onEnterFrame(e:Event):void
{
var timeElapsed:Number = (1 / 60);
velocity.y += GRAVITY * timeElapsed;
curPosition.x += velocity.x * timeElapsed;
curPosition.y += velocity.y * timeElapsed;
curSprite.x = curPosition.x;
curSprite.y = curPosition.y;
}
/**
* Basic dragless trajectory time of impact 1-liner calculation across flat ground.
* Simply calculates time of rise to apex added with time of fall to ground level.
* @param yo Start y position
* @param vyo Start velocity y
* @param g Constant gravity
* @return Time of impact/flight till object hits the ground
*/
//inline
private function getTrajectoryTimeOfFlight(yo:Number, vyo:Number, g:Number ):Number {
var tRise:Number = -vyo / g;
_tRise = tRise;
// 0 = yo + .5 * g * t * t + vyo * t
var h:Number = yo + vyo*vyo/(2*g);
_h = h;
var tSink:Number = Math.sqrt(2*h/g) * (yo >= 0 ? 1 : -1); //+- quadratic
return tRise + tSink;
//return vyo/g + Math.sqrt((2*yo + vyo*2*t - 1*g*t*t)/g);
//return vyo/g + Math.sqrt((2*yo + vyo*2*t - 1*g*t*t)/g);
}
private function onMouseMove(e:MouseEvent):void
{
// startPosition.x = mouseX;
// startPosition.y = mouseY;
_displace.x = mouseX - startPosition.x;
_displace.y = mouseY - startPosition.y;
_displace.normalize(SPEED);
velocity.x = _displace.x;
velocity.y = _displace.y;
curPosition.x = startPosition.x;
curPosition.y = startPosition.y;
totalFlightTime = getTrajectoryTimeOfFlight(stage.stageHeight - startPosition.y, velocity.y, GRAVITY);
drawPath();
}
private function drawPath():void
{
graphics.clear();
graphics.beginFill(0x000000, 1);
graphics.lineStyle(0, 0, 1);
var totalTimeToUse:Number = totalFlightTime;// (totalTime > MAX_TIME) ? totalTime : totalTime / MAX_TIME * MAX_TIME;
for (var i:int = 0; i <= DRAW_SEGMENTS; i++) { // draw in between segments
var t:Number = (i / DRAW_SEGMENTS) * totalTimeToUse;
var px:Number;
var py:Number;
graphics.drawCircle(
px= startPosition.x + velocity.x * t,
py = startPosition.y + .5 * GRAVITY * t * t + velocity.y * t
,4);
// get forward vector
var vx:Number = velocity.x;
var vy:Number = velocity.y + GRAVITY*t;
var d:Number = 1 / Math.sqrt(vx * vx + vy * vy); // normalize
vx *= d;
vy *= d;
graphics.moveTo(px, py);
graphics.lineTo(px + vx * 11, py + vy * 11);
}
// if (_tRise <0) _tRise = 0;
graphics.moveTo(startPosition.x + _tRise*velocity.x, startPosition.y);
graphics.lineTo(startPosition.x + _tRise*velocity.x, startPosition.y - 320)
graphics.moveTo(startPosition.x + totalFlightTime*velocity.x, startPosition.y);
graphics.lineTo(startPosition.x + totalFlightTime*velocity.x, startPosition.y - 320);
graphics.beginFill(0xFFFF00,1);
graphics.drawCircle(
px= startPosition.x + _tRise*velocity.x,
py = startPosition.y+ .5 * GRAVITY * _tRise * _tRise + velocity.y * _tRise
,4);
graphics.moveTo(0,stage.stageHeight);
graphics.lineTo(stage.stageWidth, stage.stageHeight-1);
}
}
}